抽奖活动前端应用

This commit is contained in:
wanghuayue 2021-04-12 10:06:59 +08:00
parent a309927ac0
commit d6188b90d8
111 changed files with 5262 additions and 1 deletions

129
sino-act-web/pom.xml Normal file
View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>sino-act-web</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- SpringBoot Web容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot 拦截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--防止进入swagger页面报类型转换错误排除2.9.2中的引用手动增加1.5.21版本-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<!-- swagger2-UI-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>sino-activity</artifactId>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.1.RELEASE</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -0,0 +1,22 @@
package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* 启动程序
*
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages = "com")
public class ActWebApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(ActWebApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 活动前端服务启动成功 ლ(´ڡ`ლ)゙ \n" +
" ''-' `'-' `-..-' ");
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author ruoyi
*/
public class ActWebServletInitializer extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(ActWebApplication.class);
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.cache;
import java.util.Date;
import java.util.Hashtable;
public class Cache {
private static Hashtable<String, Object> __cacheList = new Hashtable<String, Object>();
public Cache() {
super();
}
// 添加cache,不过期
public synchronized static void add(String key, Object value) {
Cache.add(key, value, -1);
}
// 添加cache有过期时间
public synchronized static void add(String key, Object value, long timeOut) {
if (timeOut > 0) {
timeOut += System.currentTimeMillis();
}
CacheItem item = new CacheItem(key, value, timeOut);
Cache.__cacheList.put(key, item);
}
// 获取cache
public synchronized static Object get(String key) {
Object obj = Cache.__cacheList.get(key);
if (obj == null) {
return null;
}
CacheItem item = (CacheItem) obj;
boolean expired = Cache.cacheExpired(key);
if (expired == true) // 已过期
{
Cache.remove(key);
return null;
}
return item.getValue();
}
// 移除cache
public synchronized static void remove(String key) {
Object obj = Cache.__cacheList.get(key);
if (obj != null) {
obj = null;
}
Cache.__cacheList.remove(key);
}
// 判断是否过期
private static boolean cacheExpired(String key) {
CacheItem item = (CacheItem) Cache.__cacheList.get(key);
if (item == null) {
return false;
}
long milisNow = System.currentTimeMillis();
long milisExpire = item.getTimeOut();
if (milisExpire <= 0) { // 不过期
return false;
} else if (milisNow >= milisExpire) {
return true;
} else {
return false;
}
}
}

View File

@ -0,0 +1,48 @@
package com.ruoyi.cache;
public class CacheItem {
private String key;
private Object value;
private long timeOut;
public CacheItem() {
}
public CacheItem(String key, Object value) {
this.key = key;
this.value = value;
this.timeOut = 0;
}
public CacheItem(String key, Object value, long timeOut) {
this.key = key;
this.value = value;
this.timeOut = timeOut;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public long getTimeOut() {
return timeOut;
}
public void setTimeOut(long timeOut) {
this.timeOut = timeOut;
}
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* 程序注解配置
*
* @author ruoyi
*/
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.**.mapper")
public class ApplicationConfig
{
}

View File

@ -0,0 +1,125 @@
package com.ruoyi.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.config.properties.DruidProperties;
import com.ruoyi.datasource.DynamicDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.servlet.*;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* druid 配置多数据源
*
* @author ruoyi
*/
@Configuration
public class DruidConfig
{
@Bean
@ConfigurationProperties("spring.datasource.druid.master")
public DataSource masterDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}
@Bean
@ConfigurationProperties("spring.datasource.druid.slave")
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public DataSource slaveDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}
@Bean(name = "dynamicDataSource")
@Primary
public DynamicDataSource dataSource(DataSource masterDataSource)
{
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
return new DynamicDataSource(masterDataSource, targetDataSources);
}
/**
* 设置数据源
*
* @param targetDataSources 备选数据源集合
* @param sourceName 数据源名称
* @param beanName bean名称
*/
public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
{
try
{
DataSource dataSource = SpringUtils.getBean(beanName);
targetDataSources.put(sourceName, dataSource);
}
catch (Exception e)
{
}
}
/**
* 去除监控页面底部的广告
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
{
// 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
final String filePath = "support/http/resources/js/common.js";
// 创建filter进行过滤
Filter filter = new Filter()
{
@Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
chain.doFilter(request, response);
// 重置缓冲区响应头不会被重置
response.resetBuffer();
// 获取common.js
String text = Utils.readFromResource(filePath);
// 正则替换banner, 除去底部的广告信息
text = text.replaceAll("<a.*?banner\"></a><br/>", "");
text = text.replaceAll("powered.*?shrek.wang</a>", "");
response.getWriter().write(text);
}
@Override
public void destroy()
{
}
};
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(commonJsPattern);
return registrationBean;
}
}

View File

@ -0,0 +1,47 @@
package com.ruoyi.config;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.xss.XssFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.DispatcherType;
import java.util.HashMap;
import java.util.Map;
/**
* Filter配置
*
* @author ruoyi
*/
@Configuration
public class FilterConfig
{
@Value("${xss.enabled}")
private String enabled;
@Value("${xss.excludes}")
private String excludes;
@Value("${xss.urlPatterns}")
private String urlPatterns;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean xssFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new XssFilter());
registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
registration.setName("xssFilter");
registration.setOrder(Integer.MAX_VALUE);
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("excludes", excludes);
initParameters.put("enabled", enabled);
registration.setInitParameters(initParameters);
return registration;
}
}

View File

@ -0,0 +1,44 @@
package com.ruoyi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
/**
* 资源文件配置加载
*
* @author ruoyi
*/
@Configuration
public class I18nConfig implements WebMvcConfigurer
{
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor()
{
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(localeChangeInterceptor());
}
}

View File

@ -0,0 +1,133 @@
package com.ruoyi.config;
import com.ruoyi.common.utils.StringUtils;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* Mybatis支持*匹配扫描包
*
* @author ruoyi
*/
@Configuration
public class MyBatisConfig
{
@Autowired
private Environment env;
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
public static String setTypeAliasesPackage(String typeAliasesPackage)
{
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
List<String> allResult = new ArrayList<String>();
try
{
for (String aliasesPackage : typeAliasesPackage.split(","))
{
List<String> result = new ArrayList<String>();
aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = resolver.getResources(aliasesPackage);
if (resources != null && resources.length > 0)
{
MetadataReader metadataReader = null;
for (Resource resource : resources)
{
if (resource.isReadable())
{
metadataReader = metadataReaderFactory.getMetadataReader(resource);
try
{
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
}
if (result.size() > 0)
{
HashSet<String> hashResult = new HashSet<String>(result);
allResult.addAll(hashResult);
}
}
if (allResult.size() > 0)
{
typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
}
else
{
throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
}
}
catch (IOException e)
{
e.printStackTrace();
}
return typeAliasesPackage;
}
public Resource[] resolveMapperLocations(String[] mapperLocations)
{
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<Resource> resources = new ArrayList<Resource>();
if (mapperLocations != null)
{
for (String mapperLocation : mapperLocations)
{
try
{
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
}
catch (IOException e)
{
// ignore
}
}
}
return resources.toArray(new Resource[resources.size()]);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class);
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
}
}

View File

@ -0,0 +1,55 @@
package com.ruoyi.config;
import com.ruoyi.config.properties.WxMpProperties;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.stream.Collectors;
/**
* wechat mp configuration
*
* @author Binary Wang(https://github.com/binarywang)
*/
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
private final WxMpProperties properties;
@Bean
public WxMpService wxMpService() {
// 代码里 getConfigs()处报错的同学请注意仔细阅读项目说明你的IDE需要引入lombok插件
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("大哥拜托先看下项目首页的说明readme文件添加下相关配置注意别配错了");
}
WxMpService service = new WxMpServiceImpl();
service.setMultiConfigStorages(configs
.stream().map(a -> {
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();;
/*if (this.properties.isUseRedis()) {
final WxMpProperties.RedisConfig redisConfig = this.properties.getRedisConfig();
JedisPool jedisPool = new JedisPool(redisConfig.getHost(), redisConfig.getPort());
configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), a.getAppId());
} else {
configStorage = new WxMpDefaultConfigImpl();
}*/
configStorage.setAppId(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
return configStorage;
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
return service;
}
}

View File

@ -0,0 +1,77 @@
package com.ruoyi.config.properties;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* druid 配置属性
*
* @author ruoyi
*/
@Configuration
public class DruidProperties
{
@Value("${spring.datasource.druid.initialSize}")
private int initialSize;
@Value("${spring.datasource.druid.minIdle}")
private int minIdle;
@Value("${spring.datasource.druid.maxActive}")
private int maxActive;
@Value("${spring.datasource.druid.maxWait}")
private int maxWait;
@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
private int maxEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.druid.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.druid.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.druid.testOnReturn}")
private boolean testOnReturn;
public DruidDataSource dataSource(DruidDataSource datasource)
{
/** 配置初始化大小、最小、最大 */
datasource.setInitialSize(initialSize);
datasource.setMaxActive(maxActive);
datasource.setMinIdle(minIdle);
/** 配置获取连接等待超时的时间 */
datasource.setMaxWait(maxWait);
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
/** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
/**
* 用来检测连接是否有效的sql要求是一个查询语句常用select 'x'如果validationQuery为nulltestOnBorrowtestOnReturntestWhileIdle都不会起作用
*/
datasource.setValidationQuery(validationQuery);
/** 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。 */
datasource.setTestWhileIdle(testWhileIdle);
/** 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */
datasource.setTestOnBorrow(testOnBorrow);
/** 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */
datasource.setTestOnReturn(testOnReturn);
return datasource;
}
}

View File

@ -0,0 +1,73 @@
package com.ruoyi.config.properties;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.json.JSON;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* wechat mp properties
*
* @author Binary Wang(https://github.com/binarywang)
*/
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
/**
* 是否使用redis存储access token
*/
private boolean useRedis;
/**
* redis 配置
*/
private RedisConfig redisConfig;
@Data
public static class RedisConfig {
/**
* redis服务器 主机地址
*/
private String host;
/**
* redis服务器 端口号
*/
private Integer port;
}
/**
* 多个公众号配置信息
*/
private List<MpConfig> configs;
@Data
public static class MpConfig {
/**
* 设置微信公众号的appid
*/
private String appId;
/**
* 设置微信公众号的app secret
*/
private String secret;
/**
* 设置微信公众号的token
*/
private String token;
/**
* 设置微信公众号的EncodingAESKey
*/
private String aesKey;
}
@Override
public String toString() {
return JSONObject.toJSON(this).toString();
}
}

View File

@ -0,0 +1,28 @@
package com.ruoyi.datasource;
import com.ruoyi.common.config.datasource.DynamicDataSourceContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
/**
* 动态数据源
*
* @author ruoyi
*/
public class DynamicDataSource extends AbstractRoutingDataSource
{
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
{
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey()
{
return DynamicDataSourceContextHolder.getDataSourceType();
}
}

View File

@ -0,0 +1,165 @@
package com.ruoyi.service;
import com.ruoyi.cache.Cache;
import com.ruoyi.common.utils.DateUtils;
import com.sinosoft.activity.domain.DrawRule;
import com.sinosoft.activity.service.IDrawRuleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
public class DrawService {
private static final Logger logger = LoggerFactory.getLogger(DrawService.class);
@Autowired
private IDrawRuleService drawRuleService;
/**
* 刷新抽奖需要的缓存信息
*
* @param drawCode
* @throws Exception
*/
private void loadDrawRule(String drawCode) throws Exception {
logger.info("加载缓存:" + drawCode);
String yesterdayDateStr = DateUtils.parseDateToStr("yyyyMMdd", DateUtils.addDays(DateUtils.getNowDate(), -1));
// String yesterdayTimeStr = yesterdayDateStr + "0000000";
// Date tomorrowTime = DateUtil.toFormatDate(yesterdayTimeStr,
// "yyyyMMddHHmmss");
String currentDateStr = DateUtils.dateTime();
// long l1 = tomorrowTime.getTime();
// long l2 = new Date().getTime();
// long timeOut = l1 - l2;
long timeOut = 1000 * 60 * 60;
// 抽奖缓存日期加入缓存
Cache.remove("_" + drawCode + "_currentDateStr_");
Cache.add("_" + drawCode + "_currentDateStr_", currentDateStr);
// 抽奖规则加入缓存
DrawRule drawRuleParams = new DrawRule();
drawRuleParams.setDRAWCODE(drawCode);
DrawRule drawRule = drawRuleService.selectDrawRuleList(drawRuleParams).get(0);
cacheAdd("_" + drawCode + "_" + currentDateStr + "_rule_", drawRule, "_" + drawCode + "_" + yesterdayDateStr + "_rule_", timeOut);
// 奖项配置加入缓存
QueryRule gtDrawConfigQueryRule = QueryRule.getInstance();
gtDrawConfigQueryRule.addEqual("drawCode", drawCode);
gtDrawConfigQueryRule.addEqual("state", Constant.DRAW_CONFIG_STATUS_EFFECTIVE);
gtDrawConfigQueryRule.addAscOrder("prizeLevel");
List<GtDrawConfig> gtDrawConfigs = gtDrawConfigService.queryByQueryRule(gtDrawConfigQueryRule);
cacheAdd("_" + drawCode + "_" + currentDateStr + "_config_", gtDrawConfigs, "_" + drawCode + "_" + yesterdayDateStr + "_config_", timeOut);
// 空奖品加入缓存
QueryRule gtDrawConfigBlankCondition = QueryRule.getInstance();
gtDrawConfigBlankCondition.addEqual("drawCode", drawCode);
gtDrawConfigBlankCondition.addEqual("state", Constant.DRAW_CONFIG_STATUS_EFFECTIVE);
gtDrawConfigBlankCondition.addEqual("prizeLevel", "blank");
List<GtDrawConfig> gtDrawConfigBlankList = gtDrawConfigService.queryByQueryRule(gtDrawConfigBlankCondition);
if (gtDrawConfigBlankList == null) {
throw new Exception("空奖品配置错误");
}
QueryRule blankQueryRule = QueryRule.getInstance();
blankQueryRule.addEqual("prizeCode", gtDrawConfigBlankList.get(0).getPrizeCode());
blankQueryRule.addEqual("status", "1");
GtPrizeInfo blankPrize = gtPrizeInfoService.queryUniqueGtPrizeInfo(blankQueryRule);
Cache.remove("_" + drawCode + "_blank_");
Cache.add("_" + drawCode + "_blank_", blankPrize);
// 空奖奖项配置加入缓存
QueryRule gtBlankDrawConfigCondition = QueryRule.getInstance();
gtBlankDrawConfigCondition.addEqual("drawCode", drawCode);
gtBlankDrawConfigCondition.addEqual("prizeLevel", "blank");
List<GtDrawConfig> gtBlankDrawConfigList = gtDrawConfigService.queryByQueryRule(gtBlankDrawConfigCondition);
if (gtBlankDrawConfigList != null && gtBlankDrawConfigList.size() > 0) {
GtDrawConfig gtDrawConfig = gtBlankDrawConfigList.get(0);
Cache.remove("_" + drawCode + "_blankConfig_");
Cache.add("_" + drawCode + "_blankConfig_", gtDrawConfig);
}
// 非空奖奖项配置加入缓存
QueryRule gtDrawConfigCondition = QueryRule.getInstance();
gtDrawConfigCondition.addEqual("drawCode", drawCode);
gtDrawConfigCondition.addEqual("state", Constant.DRAW_CONFIG_STATUS_EFFECTIVE);
gtDrawConfigCondition.addNotEqual("prizeLevel", "blank");
gtDrawConfigCondition.addAscOrder("prizeLevel");
List<GtDrawConfig> gtDrawConfigList = gtDrawConfigService.queryByQueryRule(gtDrawConfigCondition);
cacheAdd("_" + drawCode + "_" + currentDateStr + "_gtDrawConfigList_", gtDrawConfigList, "_" + drawCode + "_" + yesterdayDateStr + "_gtDrawConfigList_", timeOut);
// 计算总权重
BigDecimal totalProbability = BigDecimal.ZERO;
// 最小概率
BigDecimal minProbability = BigDecimal.ZERO;
if (gtDrawConfigList != null && gtDrawConfigList.size() > 0) {
for (int i = 0; i < gtDrawConfigList.size(); i++) {
GtDrawConfig gtDrawConfig = gtDrawConfigList.get(i);
String prizeWigth = new BigDecimal(gtDrawConfig.getProbability()).divide(new BigDecimal(100)).toString();
totalProbability = totalProbability.add(new BigDecimal(prizeWigth));
String n = prizeWigth;
if (i == 0) {
minProbability = new BigDecimal(n);
} else {
if (new BigDecimal(n).compareTo(minProbability) == -1) {
minProbability = new BigDecimal(n);
}
logger.info("最小权重:" + n + "最小概率" + minProbability);
}
}
}
// 计算基数
BigDecimal bd = new BigDecimal(String.valueOf(minProbability));
logger.info("权重长度 = " + bd.scale());
BigDecimal baseNumer = new BigDecimal(Math.pow(10, bd.scale())).add(new BigDecimal(gtDrawConfigList.size()));
cacheAdd("_" + drawCode + "_" + currentDateStr + "_baseNumber_", baseNumer, "_" + drawCode + "_" + yesterdayDateStr + "_baseNumber_", timeOut);
// 计算起始区间
long tmp = 0;
if (gtDrawConfigList != null && gtDrawConfigList.size() > 0) {
for (int i = 0; i < gtDrawConfigList.size(); i++) {
GtDrawConfig gtDrawConfig = gtDrawConfigList.get(i);
String probability = gtDrawConfig.getProbability();
GtPrizeConfigTemp gtPrizeConfigTemp = new GtPrizeConfigTemp();
gtPrizeConfigTemp.setBaseNumer(baseNumer.longValue());
gtPrizeConfigTemp.setConfig(gtDrawConfig);
QueryRule prizeQueryRule = QueryRule.getInstance();
prizeQueryRule.addEqual("prizeCode", gtDrawConfig.getPrizeCode());
List<GtPrizeInfo> prizeInfo = gtPrizeInfoService.queryByQueryRule(prizeQueryRule);
gtPrizeConfigTemp.setPrizeInfo(prizeInfo.get(0));
// 区间1从0开始
if (i == 0) {
// 区间数从1开始
long start = new BigDecimal(1).longValue();
long end = new BigDecimal(Math.floor(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).doubleValue())).longValue();
gtPrizeConfigTemp.setStartNumer(start);
gtPrizeConfigTemp.setEndNumber(end);
gtPrizeConfigTemp.setWeightLength(end);
tmp = end;
} else {
long start = new BigDecimal(tmp).add(new BigDecimal(1)).longValue();
long end = new BigDecimal(start).add(new BigDecimal(new BigDecimal(Math.floor(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).doubleValue())).longValue())).longValue();
gtPrizeConfigTemp.setStartNumer(start);
gtPrizeConfigTemp.setEndNumber(end);
gtPrizeConfigTemp.setWeightLength(baseNumer.multiply(new BigDecimal(probability).divide(new BigDecimal(100))).longValue());
tmp = end;
}
// 奖项开始结束区间加入缓存
cacheAdd("_cache_" + drawCode + "_" + currentDateStr + "_" + gtDrawConfig.getPrizeLevel() + "_", gtPrizeConfigTemp, "_cache_" + drawCode + "_" + yesterdayDateStr + "_" + gtDrawConfig.getPrizeLevel() + "_", timeOut);
}
}
}
/**
* HashTable缓存元素
*
* @param name
* @param value
* @param yesterdayName
* @param timeOut
*/
private void cacheAdd(String name, Object value, String yesterdayName, long timeOut) {
logger.info("缓存加入键:" + name);
if (Cache.get(name) == null) {
Cache.add(name, value, timeOut);
} else {
Cache.remove(name);
Cache.add(name, value, timeOut);
if (Cache.get(yesterdayName) != null) {
Cache.remove(yesterdayName);
}
}
}
}

View File

@ -0,0 +1,120 @@
package com.ruoyi.web.controller.common;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
/**
* 通用请求处理
*
* @author ruoyi
*/
@Controller
public class CommonController
{
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
@Autowired
private ServerConfig serverConfig;
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@GetMapping("common/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{
try
{
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
FileUtils.deleteFile(filePath);
}
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
* 通用上传请求
*/
@PostMapping("/common/upload")
@ResponseBody
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("fileName", fileName);
ajax.put("url", url);
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
* 本地资源通用下载
*/
@GetMapping("/common/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
}

View File

@ -0,0 +1,344 @@
package com.ruoyi.web.controller.draw;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.web.vo.Const;
import com.ruoyi.web.vo.Result;
import com.ruoyi.web.vo.draw.*;
import com.sinosoft.activity.domain.DrawConfig;
import com.sinosoft.activity.domain.DrawInfo;
import com.sinosoft.activity.service.IDrawConfigService;
import com.sinosoft.activity.service.IDrawInfoService;
import com.sinosoft.activity.service.IDrawTaskNotifyService;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 抽奖Controller
* @author huayue
* @since 2020-08-13
*/
@Controller
@RequestMapping("/draw")
public class DrawController {
private static final Logger logger = LoggerFactory.getLogger(DrawController.class);
@Autowired
private IDrawConfigService drawConfigService;
@Autowired
private IDrawTaskNotifyService drawTaskNotifyService;
@Autowired
private IDrawInfoService drawInfoService;
@Autowired
private WxMpService wxService;
private WxOAuth2UserInfo getUserInfo(HttpServletRequest request, String code) throws Exception {
// if (!this.wxService.switchover(appid)) {
//
// }
HttpSession session = request.getSession();
WxOAuth2UserInfo wxOAuth2UserInfo = (WxOAuth2UserInfo) session.getAttribute("WxOAuth2UserInfo");
if (wxOAuth2UserInfo != null) {
return wxOAuth2UserInfo;
}
if (StringUtils.isBlank(code)) {
return null;
}
WxOAuth2AccessToken accessToken = wxService.getOAuth2Service().getAccessToken(code);
wxOAuth2UserInfo = wxService.getOAuth2Service().getUserInfo(accessToken, null);
session.setAttribute("WxOAuth2UserInfo", wxOAuth2UserInfo);
return wxOAuth2UserInfo;
}
@RequestMapping(value="/init.action", method = RequestMethod.POST)
@ResponseBody
public DrawInitResult init(HttpServletRequest request, String drawCode, String code) {
DrawInitResult result = new DrawInitResult();
try {
getUserInfo(request, code);
DrawConfig drawConfig = new DrawConfig();
drawConfig.setDRAWCODE(drawCode);
List<DrawConfig> drawConfigs = drawConfigService.selectDrawConfigList(drawConfig);
List<Prize> prizes = result.getPrizes();
for (DrawConfig config : drawConfigs) {
Prize prize = new Prize();
String prizeCode = config.getPRIZECODE();
String prizeName = config.getPRIZENAME();
String prizeImg = null;
prize.setPrizeCode(prizeCode);
prize.setPrizeName(prizeName);
prize.setPrizeImg(prizeImg);
prizes.add(prize);
}
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.init ex: ", e);
}
return result;
}
@RequestMapping(value="/num.action", method = RequestMethod.POST)
@ResponseBody
public DrawNumResult num(HttpServletRequest request, String drawCode) {
DrawNumResult result = new DrawNumResult();
try {
WxOAuth2UserInfo userInfo = this.getUserInfo(request, null);
if (userInfo == null) {
result.setRespCode("-2");
result.setRespMsg("会话已失效,请重新登录");
logger.info("DrawController.init userId is null");
return result;
}
String userId = userInfo.getOpenid();
int num = drawTaskNotifyService.selectDrawNumByUserId(userId, drawCode);
//查询抽奖次数
result.setTotal(null);
result.setNum(num+"");
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.num ex: ", e);
}
return result;
}
@RequestMapping(value="/start.action", method = RequestMethod.POST)
@ResponseBody
public DrawResult start(HttpServletRequest request, String drawCode) {
DrawResult result = new DrawResult();
try {
HttpSession session = request.getSession();
WxOAuth2UserInfo userInfo = this.getUserInfo(request, null);
if (userInfo == null) {
result.setRespCode("-2");
result.setRespMsg("会话已失效,请重新登录");
logger.info("DrawController.start openid is null");
return result;
}
String openid = userInfo.getOpenid();
String userName = userInfo.getNickname();
DrawInfo queryInfo = new DrawInfo();
queryInfo.setDRAWCODE(drawCode);
queryInfo.setSTATUS(Const.STATUS_VALID);
List<DrawInfo> drawInfos = drawInfoService.selectDrawInfoList(queryInfo);
if (drawInfos == null || drawInfos.size() == 0) {
result.setRespCode("-3");
result.setRespMsg("活动未开启");
return result;
}
DrawInfo drawInfo = drawInfos.get(0);
Date starttime = drawInfo.getSTARTTIME();
Date endtime = drawInfo.getENDTIME();
Date currDate = new Date();
if (currDate.before(starttime) || currDate.after(endtime)) {
result.setRespCode("-3");
result.setRespMsg("活动未开始");
return result;
}
// String userAccount = geUserPersonal.getUserAccount();
// String mobile = geUserPersonal.getMobliePhone();
// DrawActivityRequestBody body = new DrawActivityRequestBody();
// body.setDrawCode(drawCode);
// body.setUserId(openid);
// body.setUserType("01");
// body.setUserName(StringUtils.isBlank(userName)?userAccount:userName);
// body.setDrawTime(DateUtil.convertDate(new Date(), DateUtil.YYYYMMDDHHMMSSS));
// body.setMerchantCode("MerchantCode");
// body.setMerchantSysCode("MerchantSysCode");
// body.setBusinessArea("6");
// body.setChannel("WEIXIN");
// body.setSource("24");
// body.setPhone(mobile);
// DrawActivityResponse drawActivityResponse = activityService.drawActivityService(body).get_return();
// DrawActivityResponseHeader header = drawActivityResponse.getHeader();
// String resultCode = header.getResultCode();
// if (!WSResult.SUCCESS.equals(resultCode)) {
// result.setRespCode(resultCode);
// result.setRespMsg(WSResult.getMsg(resultCode));
// return result;
// }
// DrawActivityResponseBody responseBody = drawActivityResponse.getBody();
// String prizeCode = responseBody.getPrizeCode();
// result.setPrizeCode(prizeCode);
// String prizeName = responseBody.getPrizeName();
// result.setPrizeName(prizeName);
// String prizeType = responseBody.getPrizeType();
// result.setPrizeType(prizeType);
// result.setPrizeLevel(responseBody.getPrizeLevel());
// result.setDisplayOrder(responseBody.getDisplayOrder());
// result.setCue(responseBody.getCue());
// result.setAvailable(responseBody.getAvailable());
// String extId = responseBody.getExtId();
// result.setExtId(extId);
// result.setGatewayFlow(responseBody.getGatewayFolw());
// result.setResult(responseBody.getResult());
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.start ex: ", e);
}
return result;
}
@RequestMapping(value="/prizes.action", method = RequestMethod.POST)
@ResponseBody
public PrizeResult prizes(HttpServletRequest request, String drawCode, String isAll) {
PrizeResult result = new PrizeResult();
List<Prize> prizes = new ArrayList<Prize>();
try {
HttpSession session = request.getSession();
WxOAuth2UserInfo userInfo = getUserInfo(request, null);
if (userInfo == null && !"1".equals(isAll)) {
result.setPrizes(prizes);
return result;
}
String userId = null;
if (!"1".equals(isAll)) {
userId = userInfo.getOpenid();
}
// AwardPrizeListResponse awardPrizeListResponse = activityService.awardPrizeList(drawCode, userId).get_return();
// AwardPrizeListResponseHeader header = awardPrizeListResponse.getHeader();
// result.setRespCode(header.getResultCode());
// result.setRespMsg(header.getResultInfo());
// AwardPrizeListResponseBody responseBody = awardPrizeListResponse.getResponseBody();
// AwardPrizeList[] awardPrizes = responseBody.getAwardPrizeLists();
// if (awardPrizes != null) {
// for (int i = 0; i < awardPrizes.length; i++) {
// AwardPrizeList awardPrize = awardPrizes[i];
// Prize prize = new Prize();
// prize.setPrizeCode(awardPrize.getPrizeCode());
// prize.setPrizeName(awardPrize.getPrizeName());
// prize.setPrizeType(awardPrize.getPrizeType());
// prize.setDrawTime(DateUtil.convertDate(DateUtil.convertStringToDate(awardPrize.getDrawTime(), DateUtil.YYYYMMDDHHMMSSS), "yyyy/MM/dd HH:mm"));
// prize.setStatus(awardPrize.getStatus());
// prize.setExtId(awardPrize.getExtId());
// prize.setGatewayFlow(awardPrize.getGatewayFolw());
// String userName = awardPrize.getUserName();
// if (StringUtils.isNotBlank(userName)) {
// int end = 1;
// if (userName.length()==2) {
// end = 0;
// }
// prize.setUserName(StringUtil.getStarString2(userName, 1, end));
// }
// String mobile = awardPrize.getMobile();
// if (StringUtils.isNotBlank(mobile)) {
// prize.setMobile(StringUtil.getStarString2(mobile, 3, 4));
// }
// prizes.add(prize);
// }
// }
result.setPrizes(prizes);
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.prizes ex: ", e);
}
return result;
}
@RequestMapping(value="/addDrawNum", method = RequestMethod.POST)
@ResponseBody
public Result addDrawNum(HttpServletRequest request, String drawCode, String taskType) {
Result result = new Result();
try {
HttpSession session = request.getSession();
WxOAuth2UserInfo userInfo = getUserInfo(request, null);
if (userInfo == null) {
result.setRespCode("-2");
result.setRespMsg("未授权登录");
logger.error("DrawController.addDrawNum openId is null");
return result;
}
String openId = userInfo.getOpenid();
//赠送抽奖机会
// TaskNotifyRequestBody requestBody = new TaskNotifyRequestBody();
// requestBody.setTaskId("");
// requestBody.setIsLimited("0");
// requestBody.setUserId(openId);
// requestBody.setTaskType(taskType);
// requestBody.setGetNumber("1");
// requestBody.setDrawCode(drawCode);
// TaskNotifyResponse taskNotifyResponse = null;//activityService.taskNotify(requestBody).get_return();
// TaskNotifyResponseHeader header = taskNotifyResponse.getHeader();
// String resultCode = header.getResultCode();
// if ("GT0000602".equals(resultCode)) {
// result.setRespCode("04");
// result.setRespMsg("积分不足哦");
// return result;
// }
// String number = taskNotifyResponse.getResponseBody().getGetNumber();
// Integer num = Integer.valueOf(number);
// if (num == null || num < 1) {
// result.setRespCode("03");
// result.setRespMsg("已经赠送过抽奖机会");
// }
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.addDrawNum ex: ", e);
}
return result;
}
@RequestMapping(value="/saveAddress.action", method = RequestMethod.POST)
@ResponseBody
public Result saveAddress(HttpServletRequest request, String drawCode, String uname, String phone, String addr, String flow) {
Result result = new Result();
try {
HttpSession session = request.getSession();
WxOAuth2UserInfo userInfo = getUserInfo(request, null);
if (userInfo == null) {
result.setRespCode("-2");
result.setRespMsg("会话已失效,请重新登录");
logger.info("DrawController.saveAddress userId is null");
return result;
}
if (StringUtils.isBlank(uname)) {
result.setRespCode("-4");
result.setRespMsg("请输入姓名");
return result;
}
// String validateMobile = CommonValidate.validateMobile(phone, "1");
// if (StringUtils.isNotBlank(validateMobile)) {
// result.setRespCode("-4");
// result.setRespMsg(validateMobile);
// return result;
// }
String userId = userInfo.getOpenid();
// SaveUserAddressRequestBody requestBody = new SaveUserAddressRequestBody();
// requestBody.setDrawCode(drawCode);
// requestBody.setGatewayFlow(flow);
// requestBody.setUserId(userId);
// requestBody.setUserName(uname);
// requestBody.setPhone(phone);
// requestBody.setAddress(addr);
// //实物留资
// requestBody.setNotifyType("007");
// requestBody.setCity("");
// activityService.saveUserAddress(requestBody);
} catch (Exception e) {
result.setRespCode("-1");
result.setRespMsg("系统异常,请稍后再试");
logger.error("DrawController.saveAddress ex: ", e);
}
return result;
}
}

View File

@ -0,0 +1,26 @@
package com.ruoyi.web.controller.tool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* build 表单构建
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/build")
public class BuildController extends BaseController
{
private String prefix = "tool/build";
@RequiresPermissions("tool:build:view")
@GetMapping()
public String build()
{
return prefix + "/build";
}
}

View File

@ -0,0 +1,175 @@
package com.ruoyi.web.controller.tool;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
/**
* swagger 用户测试方法
*
* @author ruoyi
*/
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
}
@ApiOperation("获取用户列表")
@GetMapping("/list")
public AjaxResult userList()
{
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
return AjaxResult.success(userList);
}
@ApiOperation("获取用户详细")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path")
@GetMapping("/{userId}")
public AjaxResult getUser(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
return AjaxResult.success(users.get(userId));
}
else
{
return error("用户不存在");
}
}
@ApiOperation("新增用户")
@ApiImplicitParam(name = "userEntity", value = "新增用户信息", dataType = "UserEntity")
@PostMapping("/save")
public AjaxResult save(UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return error("用户ID不能为空");
}
return AjaxResult.success(users.put(user.getUserId(), user));
}
@ApiOperation("更新用户")
@ApiImplicitParam(name = "userEntity", value = "新增用户信息", dataType = "UserEntity")
@PutMapping("/update")
public AjaxResult update(UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return error("用户ID不能为空");
}
if (users.isEmpty() || !users.containsKey(user.getUserId()))
{
return error("用户不存在");
}
users.remove(user.getUserId());
return AjaxResult.success(users.put(user.getUserId(), user));
}
@ApiOperation("删除用户信息")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path")
@DeleteMapping("/{userId}")
public AjaxResult delete(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
users.remove(userId);
return success();
}
else
{
return error("用户不存在");
}
}
}
@ApiModel("用户实体")
class UserEntity
{
@ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("用户名称")
private String username;
@ApiModelProperty("用户密码")
private String password;
@ApiModelProperty("用户手机")
private String mobile;
public UserEntity()
{
}
public UserEntity(Integer userId, String username, String password, String mobile)
{
this.userId = userId;
this.username = username;
this.password = password;
this.mobile = mobile;
}
public Integer getUserId()
{
return userId;
}
public void setUserId(Integer userId)
{
this.userId = userId;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getMobile()
{
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.web.core.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2的接口配置
*
* @author ruoyi
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig
{
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/**
* 创建API
*/
@Bean
public Docket createRestApi()
{
return new Docket(DocumentationType.SWAGGER_2)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题若依管理系统_接口文档")
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(RuoYiConfig.getName(), null, null))
// 版本
.version("版本号:" + RuoYiConfig.getVersion())
.build();
}
}

View File

@ -0,0 +1,32 @@
package com.ruoyi.web.vo;
/**
*
* @author Huayue
* @version 1658
*/
public interface Const {
String CHANNEL_APP = "App";
String CHANNEL_WECHAT = "WX";
String RES_SUCC = "1";
String RES_MSG_SUCC = "操作成功";
String RES_ERR = "-1";
String RES_MSG_ERR = "系统异常,请稍后再试";
String RES_SESSION_TIMEOUT = "-2";
String RES_MSG_SESSION_TIMEOUT = "会话失效,请重新登录";
String RES_MOBILE_NULL = "-3";
String RES_MSG_MOBILE_NULL = "请先完善手机号";
String RES_NOT_AUTH = "-4";
String RES_MSG_NOT_AUTH = "请勾选协议";
String RES_ACCOUNT_EXCEPT = "-5";
String RES_MSG_ACCOUNT_EXCEPT = "账户异常,请联系在线客服";
String RES_PARAM_ERR = "-7";
String RES_MSG_PARAM_ERR = "参数错误";
String RES_ERR_SHARE = "-8";
String RES_ERR_LIMIT = "-9";
String STATUS_VALID = "1";
String STATUS_INVALID = "0";
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.web.vo;
public class Result {
private String respCode = Const.RES_SUCC;
private String respMsg = Const.RES_MSG_SUCC;
public String getRespCode() {
return respCode;
}
public void setRespCode(String respCode) {
this.respCode = respCode;
}
public String getRespMsg() {
return respMsg;
}
public void setRespMsg(String respMsg) {
this.respMsg = respMsg;
}
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.web.vo;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
public class UserInfo extends WxOAuth2UserInfo {
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}

View File

@ -0,0 +1,72 @@
package com.ruoyi.web.vo.draw;
import com.ruoyi.web.vo.Result;
import java.util.ArrayList;
import java.util.List;
/**
* 抽奖页面初始化vo
* @author Huayue
* @version 1664
*/
public class DrawInitResult extends Result {
private List<Prize> prizes = new ArrayList<Prize>();
/**
* 剩余抽奖次数
*/
private String num;
/**
* 消耗积分
*/
private String integral;
/**
* integral
*/
private String drawType;
/**
* 活动规则内容
*/
private String drawRule;
public String getIntegral() {
return integral;
}
public void setIntegral(String integral) {
this.integral = integral;
}
public String getDrawType() {
return drawType;
}
public void setDrawType(String drawType) {
this.drawType = drawType;
}
public String getDrawRule() {
return drawRule;
}
public void setDrawRule(String drawRule) {
this.drawRule = drawRule;
}
public List<Prize> getPrizes() {
return prizes;
}
public void setPrizes(List<Prize> prizes) {
this.prizes = prizes;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}

View File

@ -0,0 +1,34 @@
package com.ruoyi.web.vo.draw;
import com.ruoyi.web.vo.Result;
import java.util.ArrayList;
import java.util.List;
public class DrawNumResult extends Result {
/**
* 总抽奖次数
*/
private String total;
/**
* 剩余抽奖次数
*/
private String num;
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}

View File

@ -0,0 +1,96 @@
package com.ruoyi.web.vo.draw;
import com.ruoyi.web.vo.Result;
public class DrawResult extends Result {
private String prizeCode;
private String prizeName;
private String prizeLevel;
private String prizeType;
private String displayOrder;
private String cue;
private String available;
private String extId;
private String gatewayFlow;
private String result;
public String getPrizeCode() {
return prizeCode;
}
public void setPrizeCode(String prizeCode) {
this.prizeCode = prizeCode;
}
public String getPrizeName() {
return prizeName;
}
public void setPrizeName(String prizeName) {
this.prizeName = prizeName;
}
public String getPrizeLevel() {
return prizeLevel;
}
public void setPrizeLevel(String prizeLevel) {
this.prizeLevel = prizeLevel;
}
public String getPrizeType() {
return prizeType;
}
public void setPrizeType(String prizeType) {
this.prizeType = prizeType;
}
public String getDisplayOrder() {
return displayOrder;
}
public void setDisplayOrder(String displayOrder) {
this.displayOrder = displayOrder;
}
public String getCue() {
return cue;
}
public void setCue(String cue) {
this.cue = cue;
}
public String getAvailable() {
return available;
}
public void setAvailable(String available) {
this.available = available;
}
public String getExtId() {
return extId;
}
public void setExtId(String extId) {
this.extId = extId;
}
public String getGatewayFlow() {
return gatewayFlow;
}
public void setGatewayFlow(String gatewayFlow) {
this.gatewayFlow = gatewayFlow;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}

View File

@ -0,0 +1,100 @@
package com.ruoyi.web.vo.draw;
public class Prize {
private String prizeCode;
private String prizeType;
private String prizeName;
private String status;
private String drawTime;
private String userName;
private String mobile;
/**
* 外部奖品标识
*/
private String extId;
/**
* 抽奖记录流水标识
*/
private String gatewayFlow;
private String prizeImg;
public String getPrizeCode() {
return prizeCode;
}
public void setPrizeCode(String prizeCode) {
this.prizeCode = prizeCode;
}
public String getPrizeType() {
return prizeType;
}
public void setPrizeType(String prizeType) {
this.prizeType = prizeType;
}
public String getPrizeName() {
return prizeName;
}
public void setPrizeName(String prizeName) {
this.prizeName = prizeName;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDrawTime() {
return drawTime;
}
public void setDrawTime(String drawTime) {
this.drawTime = drawTime;
}
public String getExtId() {
return extId;
}
public void setExtId(String extId) {
this.extId = extId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGatewayFlow() {
return gatewayFlow;
}
public void setGatewayFlow(String gatewayFlow) {
this.gatewayFlow = gatewayFlow;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getPrizeImg() {
return prizeImg;
}
public void setPrizeImg(String prizeImg) {
this.prizeImg = prizeImg;
}
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.web.vo.draw;
import com.ruoyi.web.vo.Result;
import java.util.List;
public class PrizeResult extends Result {
private List<Prize> prizes;
public List<Prize> getPrizes() {
return prizes;
}
public void setPrizes(List<Prize> prizes) {
this.prizes = prizes;
}
}

View File

@ -0,0 +1,73 @@
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
# url: jdbc:mysql://47.105.105.125:3306/intermarketing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: intermarketing
# password: ?intermarketing123?
url: jdbc:mysql://localhost:3306/intermarketing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: admin
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# redis配置
redis:
database: 5
host: db.sinosoftec.com
port: 6379
password: sinosoft@ec~123
timeout: 6000ms # 连接超时时长(毫秒)
lettuce:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接

View File

@ -0,0 +1,156 @@
# 项目相关配置
ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.6.0
# 版权年份
copyrightYear: 2021
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 开发环境配置
server:
# 服务器的HTTP端口默认为80
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# tomcat最大线程数默认为200
max-threads: 800
# Tomcat启动初始化的线程数默认值25
min-spare-threads: 30
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
org.springframework.web: INFO
com.github.binarywang.demo.wx.mp: DEBUG
me.chanjar.weixin: DEBUG
# 用户配置
user:
password:
# 密码错误{maxRetryCount}次锁定10分钟
maxRetryCount: 5
# Spring配置
spring:
# 模板引擎
thymeleaf:
mode: HTML
encoding: utf-8
# 禁用缓存
cache: false
# 资源信息
messages:
# 国际化资源文件路径
basename: static/i18n/messages
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# MyBatis
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
# Shiro
#shiro:
# user:
# # 登录地址
# loginUrl: /login
# # 权限认证失败地址
# unauthorizedUrl: /unauth
# # 首页地址
# indexUrl: /index
# # 验证码开关
# captchaEnabled: true
# # 验证码类型 math 数组计算 char 字符
# captchaType: math
# cookie:
# # 设置Cookie的域名 默认空,即当前访问的域名
# domain:
# # 设置cookie的有效访问路径
# path: /
# # 设置HttpOnly属性
# httpOnly: true
# # 设置Cookie的过期时间天为单位
# maxAge: 30
# # 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可KeyGenerator keygen = KeyGenerator.getInstance("AES"); SecretKey deskey = keygen.generateKey(); System.out.println(Base64.encodeToString(deskey.getEncoded()));
# cipherKey: zSyK5Kp6PZAAjlT+eeNMlg==
# session:
# # Session超时时间-1代表永不过期默认30分钟
# expireTime: 30
# # 同步session到数据库的周期默认1分钟
# dbSyncPeriod: 1
# # 相隔多久检查一次session的有效性默认就是10分钟
# validationInterval: 10
# # 同一个用户最大会话数比如2的意思是同一个账号允许最多同时两个人登录默认-1不限制
# maxSession: -1
# # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
# kickoutAfter: false
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice/*
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# Swagger配置
swagger:
# 是否开启swagger
enabled: true
wx:
mp:
useRedis: false
redisConfig:
host: 127.0.0.1
port: 6379
configs:
- appId: wx0afa27c03093f9e6 # 第一个公众号的appid
secret: d4624c36b6795d1d99dcf0547af5443d # 公众号的appsecret
token: qpComing # 接口配置里的Token值
aesKey: 111 # 接口配置里的EncodingAESKey值
- appId: 2222 # 第二个公众号的appid以下同上
secret: 1111
token: 111
aesKey: 111

View File

@ -0,0 +1,24 @@
Application Version: ${ruoyi.version}
Spring Boot Version: ${spring-boot.version}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ruoyi" updateCheck="false">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir"/>
<!-- maxEntriesLocalHeap:堆内存中最大缓存对象数0没有限制 -->
<!-- maxElementsInMemory 在内存中缓存的element的最大数目。-->
<!-- eternal:elements是否永久有效如果为truetimeouts将被忽略element将永不过期 -->
<!-- timeToIdleSeconds:失效前的空闲秒数当eternal为false时这个属性才有效0为不限制 -->
<!-- timeToLiveSeconds:失效前的存活秒数创建时间到失效时间的间隔为存活时间当eternal为false时这个属性才有效0为不限制 -->
<!-- overflowToDisk 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
<!-- statistics是否收集统计信息。如果需要监控缓存使用情况应该打开这个选项。默认为关闭统计会影响性能。设置statistics="true"开启统计 -->
<!-- 默认缓存 -->
<defaultCache
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false">
</defaultCache>
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="loginRecordCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false">
</cache>
<!-- 系统活跃用户缓存 -->
<cache name="sys-userCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="false">
</cache>
<!-- 系统用户授权缓存 没必要过期 -->
<cache name="sys-authCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
memoryStoreEvictionPolicy="LRU"
statistics="false"/>
<!-- 系统缓存 -->
<cache name="sys-cache"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统参数缓存 -->
<cache name="sys-config"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统字典缓存 -->
<cache name="sys-dict"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统会话缓存 -->
<cache name="shiro-activeSessionCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="false"/>
</ehcache>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="/home/ruoyi/logs/act" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
<setting name="useGeneratedKeys" value="true" /> <!-- 允许 JDBC 支持自动生成主键 -->
<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->
<setting name="logImpl" value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 驼峰式命名 -->
</settings>
</configuration>

View File

@ -0,0 +1,74 @@
.goods{
/* opacity:0;
height:0; */
}
.goods .cont{
min-height:400px;
}
.goods .popCont{
z-index: 1000;
}
.goods .cont{
/* background: url(../images/back01.png)no-repeat; */
background-size: 100% auto;
display:flex;
flex-direction: column;
align-items: center;
}
.goods .cont>img:first-child{
width:65px;
height:auto;
object-fit:contain;
margin-top:20px;
}
.goods .cont>div:nth-child(2){
font-size:17px;
color:#ffe2ab;
text-align:center;
margin-top:12px;
}
.goods .cont>div:nth-child(3){
font-size:23px;
color:#ffe2ab;
text-align:center;
margin-top:4px;
font-weight:bold;
}
.goods .cont>div:nth-child(4){
width:83%;
font-size:12px;
color:#ffcece;
margin-top:20px;
}
.goods .cont>img:last-child{
width:83%;
height:auto;
object-fit:contain;
margin-top:20px;
margin-bottom:15px;
}
.goods .cont>input{
width:90%;
height:30px;
box-sizing: border-box;
margin:0;
padding:0 15px;
border:1px solid #f2ca77;
border-radius:15px;
background: #fff;
margin-top:10px;
}
.goods .cont>textarea{
width:90% !important;
max-width:90% !important;
min-height:60px;
box-sizing: border-box;
margin:0;
padding:8px 15px;
border:1px solid #f2ca77;
border-radius:15px;
background: #fff;
margin-top:10px;
outline: none;
line-height:20px;
}

View File

@ -0,0 +1,43 @@
@charset "gbk";
.tip_copy {
position: fixed;
z-index: 1200;
width: 9rem;
/*height: 2rem;*/
background: rgba(0,0,0,0.5);
color: #fff;
line-height: 2rem;
top: 50%;
left: 50%;
margin-top: -2rem;
margin-left: -4.9rem;
text-align: center;
border-radius: 0.5rem;
font-size: 0.6rem;
word-wrap: break-word;
word-break: normal;
padding: 0 0.4rem;
}
.promotion_goBack{
height: 44px;
background-color: #fff;
color:#f43c24;
text-align: center;
line-height: 44px;
font-size: 0.8rem;
font-weight: bold;
position: relative;
}
.btn_back{
position: absolute;
width:1rem ;
height: 1rem;
left: 0.18rem;
top:0.4rem;
line-height: 1rem;
}
.btn_back img{
widows: 100%;
}

View File

@ -0,0 +1,75 @@
.myPrize{
/* opacity:0;
height:0; */
}
.myPrize .cont{
height:280px;
}
.myPrize .cont>div{
width:100%;
height:auto;
box-sizing: border-box;
}
.myPrize .cont>div:first-child{
height:30px;
display:flex;
justify-content: center;
align-items: center;
margin-top:-3px;
}
.myPrize .cont>div:first-child>img{
width:35px;
height:auto;
object-fit: contain;
display:inline-block;
}
.myPrize .cont>div:first-child>div{
margin:0 10px;
font-size:24px;
color:#ffe2ab;
letter-spacing: 1px;
/* font-weight:bold; */
}
.myPrize .popList,.postListTop{
width:100%;
height:auto;
display:flex;
flex-direction: column;
padding:0 7px;
font-size:12px;
background: #f43c24;
}
.myPrize .popList{
flex-basis:100%;
overflow-y: scroll;
}
.postListTop{
z-index: 800;
}
.popList{
z-index: 700;
}
.myPrize .popList>div,.myPrize .postListTop>div{
width:100%;
height:38px;
min-height:38px;
display:flex;
align-items: center;
justify-content: space-between;
padding:10px 12px 0px;
box-sizing: border-box;
border-bottom:1px dashed #f2afa7;
color:#ffe2ab;
background: #f43c24;
}
.myPrize .postListTop>div>div:last-child,.popList>div>div:last-child{
min-width:95px;
text-align: right;
}
.myPrize .postListTop>div:first-child{
border-bottom:1px solid #fff;
color:#fff;
}
.myPrize .postListTop>div:first-child>div:last-child{
text-align: center;
}

View File

@ -0,0 +1,93 @@
*{
margin:0;
padding:0
}
.popup,.popup div{
box-sizing: border-box;
}
.popup{
width:100%;
height:100%;
background: rgba(0,0,0,.7);
position:fixed;
top:0;
left:0;
z-index:1000;
display:flex;
flex-direction: column;
justify-content: center;
animation:3s;
overflow-x:hidden;
overflow-y: scroll;
padding:20px 0;
}
.popupMin{
width:70%;
margin-left:15%;
height:auto !important;
box-sizing: border-box;
position:relative;
display:flex;
flex-direction: column;
/* max-height:1200px; */
margin-bottom:56px;
}
.popCont{
width:100%;
height:auto;
box-sizing: border-box;
position:relative;
display:flex;
z-index:1000;
background: #f43c24;
/* background:url(../images/back.png)repeat;
background-size:100% auto; */
}
.top{
width:100%;
height:auto;
object-fit: contain;
z-index: 999;
}
.bottom{
width:100%;
height:auto;
object-fit: contain;
z-index: 999;
}
.cont{
width:100%;
min-height:300px;
display:flex;
flex-direction: column;
align-items: center;
margin-top:-200px;
}
.left{
width:7.9%;
/* min-width:24px; */
position:relative;
top:0;
left:0px;
z-index: 1000;
background:url(../images/popupList02.png)repeat;
background-size:100% auto;
z-index: 999;
}
.right{
width:7.5%;
position:relative;
top:0;
z-index: 1000;
background:url(../images/popupList03.png)repeat;
background-size:100% auto;
z-index: 999;
}
.popDelect{
width:36px;
height:auto;
object-fit: contain;
margin-top:-36px;
margin-left:calc(50% - 13px);
/* margin-bottom:20px; */
}

View File

@ -0,0 +1,40 @@
.register{
/* opacity:0;
height:0; */
}
.register .cont{
min-height:260px;
}
.register .cont{
/* background: url(../images/back01.png)no-repeat; */
background-size: 100% auto;
display:flex;
flex-direction: column;
align-items: center;
}
.register .cont>img:first-child{
width:75%;
height:auto;
object-fit:contain;
}
.register .cont>div:nth-child(2){
font-size:23px;
color:#ffe2ab;
text-align:center;
margin-top:12px;
font-weight:bold;
}
.register .cont>div:nth-child(3){
text-align:center;
font-size:12px;
color:#ffcece;
margin-top:8px;
}
.register .cont>img:last-child{
width:82%;
height:auto;
object-fit:contain;
margin-top:20px;
margin-bottom:15px;
}

View File

@ -0,0 +1,184 @@
@charset "utf-8";
/* CSS Document */
/*
** HTML5移动重置样式表
*/
/* ============================ 重置css样式 ============================ */
/* 清除内外边距 */
body,
html,
header,
footer,
section,
span,
p,
h1,
h2,
h3,
h4,
ul,
ol,
li,
select,
input,
button,
textarea,
aside,
article,
dd,
dl,
dt {
margin: 0;
padding: 0;
}
/* 设置默认字体 */
body,
button,
input,
select,
textarea {
font: 0.48rem "NotoSansHans-Regular", Helvetica, Arial, sans-serif;
color: #666;
}
/* 重置列表元素 */
ul,
ol {
list-style: none;
}
/* 重置文本格式元素 */
a {
text-decoration: none;
}
a:focus {
outline: none;
}
img {
width: 100%;
border: none;
vertical-align: middle;
}
/* 重置表格元素 */
table {
border-collapse: collapse;
border-spacing: 0;
}
/* ========================= 页面常用样式 CSS样式 =========================== */
/*html,body{
width:100%;
overflow-x:hidden;
}*/
body {
-text-size-adjust: none;
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
/*清除浮动*/
.clearfix:after {
display: block;
clear: both;
height: 0;
visibility: hidden;
content: " ";
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
}
.fl {
float: left;
}
.fr {
float: right;
}
input {
border: none;
border-radius: 0px;
background: none;
outline: none;
}
input[type="button"],
input[type="submit"],
input[type="reset"] {
-webkit-appearance: none;
appearance: none;
}
input[type=text] {
-webkit-appearance: none;
}
select,
button {
-webkit-appearance: none;
appearance: none;
border: none;
background: transparent;
outline: none;
}
i,
em {
font-style: normal;
}
/*placeholder文字默认颜色-webkit-input-placeholder*/
:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #999;
}
::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #999;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
color: #999;
}
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
color: #999;
}
/*时间插件*/
.dwbw.dwb-c {
border-right: 1px solid #398fff;
}
.mbsc-mobiscroll .dwbw {
width: 49.8% !important;
}
.mbsc-mobiscroll .dwb {
padding: 0;
text-align: center;
}
/* 后面新增 */
textarea {
box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
-webkit-appearance: none;
}

View File

@ -0,0 +1,56 @@
.rule{
/* opacity:0 !important;
height:0 !important; */
}
.rule .cont{
height:422px;
}
.rule .cont>div{
width:100%;
height:auto;
box-sizing: border-box;
}
.rule .cont>div:first-child{
height:30px;
min-height:30px;
display:flex;
justify-content: center;
align-items: center;
margin-top:-3px;
background: #f43c24;
overflow: hidden;
}
.rule .cont>div:first-child>img{
width:35px;
height:auto;
object-fit: contain;
display:inline-block;
}
.rule .cont>div:first-child>div{
margin:0 10px;
font-size:24px;
color:#ffe2ab;
letter-spacing: 1px;
/* font-weight:bold; */
}
.rule .contBox{
width:100%;
height:auto;
overflow-x: hidden;
overflow-y: scroll;
}
.rule .content{
width:100%;
height:auto;
line-height:16px;
padding:0 15px;
color:#fff;
margin-top:16px;
font-size:12px;
font-weight:400;
letter-spacing: 1px;
box-sizing: border-box;
}
.rule .content:last-child{
margin-bottom:25px;
}

View File

@ -0,0 +1,419 @@
@charset "GBK";
.template_bg {
/*background: url(../images/bg_body.jpg) repeat center top;*/
background-size: 100% 0.96rem;
}
.promotion_container {
padding-bottom: 0.4rem;
background: url(../images/bg_promotion.jpg) no-repeat center top;
background-size: 100% 26.68rem;
}
.template_header {
padding-top: 0.48rem;
font-size: 0;
color: #774504;
}
.template_header p {
display: inline-block;
vertical-align: top;
width: 50%;
}
.template_header span {
padding-top: 0.28rem;
padding-bottom: 0.32rem;
display: inline-block;
vertical-align: top;
font-size: 0.48rem;
font-weight: bold;
}
.header_left span {
padding-left: 0.18rem;
padding-right: 0.46rem;
background: url(../images/bg_left_btn.png) no-repeat left center;
background-size: 100%;
}
.header_right {
text-align: right;
}
.header_right span {
padding-right: 0.18rem;
padding-left: 0.46rem;
background: url(../images/bg_right_btn.png) no-repeat left center;
background-size: 100%;
}
.promotion_main {
padding: 11.4rem 0.64rem 0.46rem;
padding-top: 11.4rem;
padding-bottom: 0.46rem;
}
.template_main {
position: relative;
background-color: #fff;
border: 0.12rem solid #ffb45c;
-webkit-border-radius: 0.8rem;
border-radius: 0.8rem;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.pay_draw,
.red_package {
width: 6.6rem;
padding-bottom: 0.14rem;
}
.img_header {
position: absolute;
left: 50%;
top: -1.16rem;
transform: translateX(-50%);
width: 3.04rem;
height: 1.84rem;
background: url(../images/bg_title.png) no-repeat center center;
background-size: 100% 100%;
line-height: 1.84rem;
text-align: center;
}
.icon_phone {
width: 1.24rem;
height: 1.3rem;
}
.icon_hongbao {
width: 1.26rem;
height: 1.3rem;
}
.icon_title {
display: block;
margin: 0.88rem auto 0;
width: 5.96rem;
height: 0.66rem;
}
.promotion_content {
padding: 0.2rem 0.48rem;
font-size: 0.48rem;
line-height: 0.72rem;
color: #554002;
text-align: justify;
padding-top: 0.5rem;
}
.template_btn {
display: block;
margin: 0 auto;
width: 4.62rem;
height: 1.4rem;
position: relative;
z-index: 2;
}
.draw_btn {
background: url(../images/img_draw_btn.png) no-repeat center center;
background-size: 100% 100%;
}
.hb_btn {
background: url(../images/img_hongbao_btn.png) no-repeat center center;
background-size: 100% 100%;
}
.activity_rules {
padding-bottom: 0.2rem;
margin: 0 0.64rem;
background-color: #fb6442;
}
.rules_title {
padding: 0.48rem 0;
background: url(../images/icon_title.png) no-repeat center center;
background-size: 5rem 0.46rem;
font-size: 0.6rem;
color: #fff150;
font-weight: bold;
text-align: center;
}
.rules_content {
padding: 0 1.04rem 0 0.52rem;
font-size: 0.48rem;
color: #fff;
line-height: 0.8rem;
text-align: justify;
}
.pay_draw_1 {
padding-bottom: 0.64rem;
}
.pay_draw_1 .promotion_content {
padding: 0.6rem 0.74rem 0.48rem 1.2rem;
line-height: 0.96rem;
}
.icon_hb {
position: absolute;
bottom: -0.16rem;
left: 0;
}
.promotion_main_2 {
position: relative;
padding-bottom: 0.92rem;
padding-top: 11.92rem;
}
.draw_container {
background: url(../images/bg_draw.jpg) no-repeat center top;
background-size: 100% 26.68rem;
}
/* 大转盘样式 */
.banner {
display: block;
position: relative;
}
.banner .turnplate {
display: block;
width: 12.16rem;
margin: 0 auto;
position: relative;
z-index: 10;
background-position: center center;
overflow: hidden;
}
.banner .turnplate canvas.item {
width: 100%;
}
.banner .turnplate img.pointer {
position: absolute;
width: 4.92rem;
height: 5.5rem;
left: 30%;
top: 24.7%;
}
.lucy_wheel {
padding-top: 11.4rem;
}
.draw_title {
position: absolute;
top: -1.8rem;
left: 50%;
transform: translateX(-50%);
background: url(../images/icon_draw_title.png) no-repeat center top;
background-size: 100% 100%;
min-width: 9.0rem;
height: 4.08rem;
padding-top: 0.36rem;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: center;
font-size: 0.56rem;
color: #fff;
}
.draw_footer {
position: absolute;
bottom: -0.4rem;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 2.12rem;
z-index: 1;
}
.lucy_info {
position: relative;
background: url("../images/bg_lucy_bottom.jpg") no-repeat center bottom;
background-size: 100% 100%;
height: 1.52rem;
margin-top: 0.16rem;
box-sizing: border-box;
text-align: left;
}
.lucy_info img {
position: absolute;
bottom: 0;
left: 0;
width: 3.28rem;
height: 3.12rem;
z-index: 11;
}
.myscroll {
margin: 0.56rem 0 0.36rem;
padding: 0 0.4rem 0 3.36rem;
width: 100%;
height: 1.04rem;
display: inline-block;
overflow: hidden;
vertical-align: top;
box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.myscroll li {
height: 0.48rem;
font-size: 0.48rem;
color: #fef6e1;
line-height: 0.72rem;
line-height: 0.48rem;
}
/* zk----领红包页面样式 */
.promotion_main.nowPage{
padding: 11.4rem 0;
padding-bottom: 0;
box-sizing: border-box;
position: relative;
}
.zk_red_box{
width: 100%;
overflow: hidden;
}
.zk_red_box .zk_red_box_header{
width: 100%;
height: 5.4rem;
background: url(../images/img_red_packet_header.png) no-repeat center 1px;
background-size:100%;
overflow: hidden;
position: relative;
text-align: center;
}
.zk_red_box .zk_red_box_footer{
margin-top: -1px;
width: 100%;
height: 7.96rem;
background: url(../images/img_red_packet_footer.png) no-repeat center 1px;
background-size:100%;
overflow: hidden;
}
.zk_red_box .zk_red_box_header h2.title{
font-size: 0.52rem;
color: #fdf8bd;
margin-top: 0.34rem;
height: 0.52rem;
text-align: center;
}
.zk_red_box .zk_red_box_footer>p{
margin-top: 1.76rem;
font-size: 0.6rem;
line-height: 0.6rem;
height: 0.6rem;
color: #ffffff;
margin-left: 0.14rem;
text-align: center;
}
/* 刮奖弹层 */
.zk_red_box .zk_red_box_header canvas{
position: absolute;
width: 9.08rem;
height: 3.72rem;
left: 50%;
top: 1.6rem;
transform: translateX(-50%);
z-index: 99;
/* background-image: url(../images/img_scratch_popup.png);
background-color: #fff;
background-repeat: no-repeat;
background-position-x: center;
background-position-y: center;
background-size: 100%;*/
/* z-index: 99; */
}
/* 刮奖状态---成功 */
.zk_red_box .zk_red_box_header .scratch_off_box{
position: absolute;
width: 9.08rem;
height: 3.72rem;
left: 50%;
top: 1.6rem;
transform: translateX(-50%);
z-index: 1;
}
.zk_red_box .zk_red_box_header .scratch_off_box.success p:first-child{
margin-top: 0.68rem;
color: #989797;
font-size: 0.6rem;
line-height: 0.6rem;
height: 0.6rem;
}
.zk_red_box .zk_red_box_header .scratch_off_box.success p:nth-child(2){
margin-top: 0.28rem;
font-size: 0.8rem;
color: #db2310;
line-height: 0.8rem;
height: 0.8rem;
}
.zk_red_box .zk_red_box_header .scratch_off_box p.again_btn{
width: 4.62rem;
height: 1.36rem;
background: url(../images/icon_again_bg.png) no-repeat center center;
background-size: 100%;
margin: 0 auto;
line-height: 1.6rem;
font-size: 0.6rem;
color: #f9edc7;
}
/* 刮奖状态---失败 */
.zk_red_box .zk_red_box_header .scratch_off_box.fail p:first-child{
margin-top: 1.26rem;
color: #989797;
font-size: 0.6rem;
line-height: 0.6rem;
height: 0.6rem;
margin-bottom: 0.46rem;
}
/* 刮奖状态---没有抽奖机会 */
.zk_red_box .zk_red_box_header .scratch_off_box.no_chance p:first-child{
margin-top: 1.26rem;
color: #989797;
font-size: 0.6rem;
line-height: 0.6rem;
height: 0.6rem;
margin-bottom: 0.5rem;
}
.zk_red_box .zk_red_box_header .scratch_off_box.no_chance p:last-child{
color: #989797;
font-size: 0.48rem;
line-height: 0.48rem;
height: 0.48rem;
}
.myscroll.zk_carry_box{
margin: 0;
padding: 0;
position: absolute;
bottom: 0.1rem;
left: 50%;
transform: translateX(-50%);
width: 13rem;
height: 1.04rem;
line-height: 1.04rem;
color: #ffffff;
font-size: 0.48rem;
text-align: center;
background: rgba(209, 163, 112, .9);
border-radius: 0.24rem;
overflow: hidden;
}

View File

@ -0,0 +1,46 @@
.winPrize{
/* opacity:0;
height:0; */
}
.winPrize .cont{
min-height:260px;
}
.winPrize .cont{
/* background: url(../images/back01.png)no-repeat; */
background-size: 100% auto;
display:flex;
flex-direction: column;
align-items: center;
}
.winPrize .cont>img:first-child{
width:65px;
height:auto;
object-fit:contain;
margin-top:20px;
}
.winPrize .cont>div:nth-child(2){
font-size:17px;
color:#ffe2ab;
text-align:center;
margin-top:12px;
}
.winPrize .cont>div:nth-child(3){
font-size:23px;
color:#ffe2ab;
text-align:center;
margin-top:4px;
font-weight:bold;
}
.winPrize .cont>div:nth-child(4){
font-size:12px;
color:#ffcece;
margin-top:25px;
width:82%;
}
.winPrize .cont>img:last-child{
width:82%;
height:auto;
object-fit:contain;
margin-top:20px;
margin-bottom:15px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,302 @@
(function($) {
var supportedCSS,styles=document.getElementsByTagName("head")[0].style,toCheck="transformProperty WebkitTransform OTransform msTransform MozTransform".split(" ");
for (var a=0;a<toCheck.length;a++) if (styles[toCheck[a]] !== undefined) supportedCSS = toCheck[a];
// Bad eval to preven google closure to remove it from code o_O
// After compresion replace it back to var IE = 'v' == '\v'
var IE = eval('"v"=="\v"');
jQuery.fn.extend({
rotate:function(parameters)
{
if (this.length===0||typeof parameters=="undefined") return;
if (typeof parameters=="number") parameters={angle:parameters};
var returned=[];
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (!element.Wilq32 || !element.Wilq32.PhotoEffect) {
var paramClone = $.extend(true, {}, parameters);
var newRotObject = new Wilq32.PhotoEffect(element,paramClone)._rootObj;
returned.push($(newRotObject));
}
else {
element.Wilq32.PhotoEffect._handleRotation(parameters);
}
}
return returned;
},
getRotateAngle: function(){
var ret = [];
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (element.Wilq32 && element.Wilq32.PhotoEffect) {
ret[i] = element.Wilq32.PhotoEffect._angle;
}
}
return ret;
},
stopRotate: function(){
for (var i=0,i0=this.length;i<i0;i++)
{
var element=this.get(i);
if (element.Wilq32 && element.Wilq32.PhotoEffect) {
clearTimeout(element.Wilq32.PhotoEffect._timer);
}
}
}
});
// Library agnostic interface
Wilq32=window.Wilq32||{};
Wilq32.PhotoEffect=(function(){
if (supportedCSS) {
return function(img,parameters){
img.Wilq32 = {
PhotoEffect: this
};
this._img = this._rootObj = this._eventObj = img;
this._handleRotation(parameters);
}
} else {
return function(img,parameters) {
// Make sure that class and id are also copied - just in case you would like to refeer to an newly created object
this._img = img;
this._rootObj=document.createElement('span');
this._rootObj.style.display="inline-block";
this._rootObj.Wilq32 =
{
PhotoEffect: this
};
img.parentNode.insertBefore(this._rootObj,img);
if (img.complete) {
this._Loader(parameters);
} else {
var self=this;
// TODO: Remove jQuery dependency
jQuery(this._img).bind("load", function()
{
self._Loader(parameters);
});
}
}
}
})();
Wilq32.PhotoEffect.prototype={
_setupParameters : function (parameters){
this._parameters = this._parameters || {};
if (typeof this._angle !== "number") this._angle = 0 ;
if (typeof parameters.angle==="number") this._angle = parameters.angle;
this._parameters.animateTo = (typeof parameters.animateTo==="number") ? (parameters.animateTo) : (this._angle);
this._parameters.step = parameters.step || this._parameters.step || null;
this._parameters.easing = parameters.easing || this._parameters.easing || function (x, t, b, c, d) { return -c * ((t=t/d-1)*t*t*t - 1) + b; }
this._parameters.duration = parameters.duration || this._parameters.duration || 1000;
this._parameters.callback = parameters.callback || this._parameters.callback || function(){};
if (parameters.bind && parameters.bind != this._parameters.bind) this._BindEvents(parameters.bind);
},
_handleRotation : function(parameters){
this._setupParameters(parameters);
if (this._angle==this._parameters.animateTo) {
this._rotate(this._angle);
}
else {
this._animateStart();
}
},
_BindEvents:function(events){
if (events && this._eventObj)
{
// Unbinding previous Events
if (this._parameters.bind){
var oldEvents = this._parameters.bind;
for (var a in oldEvents) if (oldEvents.hasOwnProperty(a))
// TODO: Remove jQuery dependency
jQuery(this._eventObj).unbind(a,oldEvents[a]);
}
this._parameters.bind = events;
for (var a in events) if (events.hasOwnProperty(a))
// TODO: Remove jQuery dependency
jQuery(this._eventObj).bind(a,events[a]);
}
},
_Loader:(function()
{
if (IE)
return function(parameters)
{
var width=this._img.width;
var height=this._img.height;
this._img.parentNode.removeChild(this._img);
this._vimage = this.createVMLNode('image');
this._vimage.src=this._img.src;
this._vimage.style.height=height+"px";
this._vimage.style.width=width+"px";
this._vimage.style.position="absolute"; // FIXES IE PROBLEM - its only rendered if its on absolute position!
this._vimage.style.top = "0px";
this._vimage.style.left = "0px";
/* Group minifying a small 1px precision problem when rotating object */
this._container = this.createVMLNode('group');
this._container.style.width=width;
this._container.style.height=height;
this._container.style.position="absolute";
this._container.setAttribute('coordsize',width-1+','+(height-1)); // This -1, -1 trying to fix ugly problem with small displacement on IE
this._container.appendChild(this._vimage);
this._rootObj.appendChild(this._container);
this._rootObj.style.position="relative"; // FIXES IE PROBLEM
this._rootObj.style.width=width+"px";
this._rootObj.style.height=height+"px";
this._rootObj.setAttribute('id',this._img.getAttribute('id'));
this._rootObj.className=this._img.className;
this._eventObj = this._rootObj;
this._handleRotation(parameters);
}
else
return function (parameters)
{
this._rootObj.setAttribute('id',this._img.getAttribute('id'));
this._rootObj.className=this._img.className;
this._width=this._img.width;
this._height=this._img.height;
this._widthHalf=this._width/2; // used for optimisation
this._heightHalf=this._height/2;// used for optimisation
var _widthMax=Math.sqrt((this._height)*(this._height) + (this._width) * (this._width));
this._widthAdd = _widthMax - this._width;
this._heightAdd = _widthMax - this._height; // widthMax because maxWidth=maxHeight
this._widthAddHalf=this._widthAdd/2; // used for optimisation
this._heightAddHalf=this._heightAdd/2;// used for optimisation
this._img.parentNode.removeChild(this._img);
this._aspectW = ((parseInt(this._img.style.width,10)) || this._width)/this._img.width;
this._aspectH = ((parseInt(this._img.style.height,10)) || this._height)/this._img.height;
this._canvas=document.createElement('canvas');
this._canvas.setAttribute('width',this._width);
this._canvas.style.position="relative";
this._canvas.style.left = -this._widthAddHalf + "px";
this._canvas.style.top = -this._heightAddHalf + "px";
this._canvas.Wilq32 = this._rootObj.Wilq32;
this._rootObj.appendChild(this._canvas);
this._rootObj.style.width=this._width+"px";
this._rootObj.style.height=this._height+"px";
this._eventObj = this._canvas;
this._cnv=this._canvas.getContext('2d');
this._handleRotation(parameters);
}
})(),
_animateStart:function()
{
if (this._timer) {
clearTimeout(this._timer);
}
this._animateStartTime = +new Date;
this._animateStartAngle = this._angle;
this._animate();
},
_animate:function()
{
var actualTime = +new Date;
var checkEnd = actualTime - this._animateStartTime > this._parameters.duration;
// TODO: Bug for animatedGif for static rotation ? (to test)
if (checkEnd && !this._parameters.animatedGif)
{
clearTimeout(this._timer);
}
else
{
if (this._canvas||this._vimage||this._img) {
var angle = this._parameters.easing(0, actualTime - this._animateStartTime, this._animateStartAngle, this._parameters.animateTo - this._animateStartAngle, this._parameters.duration);
this._rotate((~~(angle*10))/10);
}
if (this._parameters.step) {
this._parameters.step(this._angle);
}
var self = this;
this._timer = setTimeout(function()
{
self._animate.call(self);
}, 10);
}
// To fix Bug that prevents using recursive function in callback I moved this function to back
if (this._parameters.callback && checkEnd){
this._angle = this._parameters.animateTo;
this._rotate(this._angle);
this._parameters.callback.call(this._rootObj);
}
},
_rotate : (function()
{
var rad = Math.PI/180;
if (IE)
return function(angle)
{
this._angle = angle;
this._container.style.rotation=(angle%360)+"deg";
}
else if (supportedCSS)
return function(angle){
this._angle = angle;
this._img.style[supportedCSS]="rotate("+(angle%360)+"deg)";
}
else
return function(angle)
{
this._angle = angle;
angle=(angle%360)* rad;
// clear canvas
this._canvas.width = this._width+this._widthAdd;
this._canvas.height = this._height+this._heightAdd;
// REMEMBER: all drawings are read from backwards.. so first function is translate, then rotate, then translate, translate..
this._cnv.translate(this._widthAddHalf,this._heightAddHalf); // at least center image on screen
this._cnv.translate(this._widthHalf,this._heightHalf); // we move image back to its orginal
this._cnv.rotate(angle); // rotate image
this._cnv.translate(-this._widthHalf,-this._heightHalf); // move image to its center, so we can rotate around its center
this._cnv.scale(this._aspectW,this._aspectH); // SCALE - if needed ;)
this._cnv.drawImage(this._img, 0, 0); // First - we draw image
}
})()
}
if (IE)
{
Wilq32.PhotoEffect.prototype.createVMLNode=(function(){
document.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
try {
!document.namespaces.rvml && document.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
return function (tagName) {
return document.createElement('<rvml:' + tagName + ' class="rvml">');
};
} catch (e) {
return function (tagName) {
return document.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
};
}
})();
}
})(jQuery);

View File

@ -0,0 +1,75 @@
// 我的奖品点击关闭事件
$(".prizeDelect").click(function(){
$('.myPrize').hide();
// $(".myPrize").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".myPrize").css({ "opacity":1,"height":'100%' });
// },3000)
});
// 登记点击关闭事件
$(".regDelect").click(function(){
$('.register').hide();
// $(".register").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".register").css({ "opacity":1,"height":'100%' });
// },3000)
});
//继续抽奖
$(".popBtn1").click(function(){
console.log('继续抽奖');
$('.register').hide();
// $(".register").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".register").css({ "opacity":1,"height":'100%' });
// },3000)
});
$(".popBtn2").click(function(){
console.log('继续抽奖');
$('.winPrize').hide();
// $(".winPrize").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".winPrize").css({ "opacity":1,"height":'100%' });
// },3000)
});
$(".popBtn3").click(function(){
// console.log('提交信息');
// $('.goods').hide();
// $(".goods").css({ "opacity":0,"height":'0px' });
// $(".register").css({ "opacity":1,"height":'100%' });
// setTimeout(function(){
// $(".goods").css({ "opacity":1,"height":'100%' });
// },3000)
});
// 中奖
$(".winDelect").click(function(){
$('.winPrize').hide();
// $(".winPrize").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".winPrize").css({ "opacity":1,"height":'100%' });
// },3000)
});
//
$(".goodsDelect").click(function(){
$('.goods').hide();
// $(".goods").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".goods").css({ "opacity":1,"height":'100%' });
// },3000)
});
//活动规则
$(".ruleDelect").click(function(){
$('.rule').hide();
// $(".rule").css({ "opacity":0,"height":'0px' });
// $("body").removeClass("popupBox");
// setTimeout(function(){
// $(".rule").css({ "opacity":1,"height":'100%' });
// },3000)
});

View File

@ -0,0 +1,170 @@
var drawCode = getParameter('drawCode');
var prizeType = null;
var prizeCode = null;
function rtn() {
let rtnBtn = getParameter('rtn');
if (rtnBtn) {
location.href = decodeURIComponent(rtnBtn);
} else {
history.back();
}
}
function drawrule() {
console.log('rule');
$('.rule').show();
}
function tip(msg) {
$('.tip_copy>p').text(msg);
$('.tip_copy').show();
setTimeout(function(){
$('.tip_copy').hide();
},1500);
}
function myprizes() {
$('.popList').html('');
$('.myPrize').show();
$.ajax({
type: "POST",
url: contextRootPath+"/draw/prizes.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
if (!data.prizes) {
return;
}
console.log(data.prizes);
$.each(data.prizes, function (i, n) {
var ptype = n.prizeType;
var status = n.status;
var iscenter = 0;
var prize = $('.prize_li').clone();
$(prize).css('display', 'inherit');
prize.removeClass('prize_li');
prize.find('.pname').html(n.prizeName);
prize.find('.time').html(n.drawTime);
$(prize).attr('val', n.prizeCode);
$(prize).attr('flow', n.gatewayFlow);
$(prize).attr('ptype', ptype);
$('.popList').append(prize);
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
}
$('.pop_height').css({
'max-height': $(window).height() * 0.45 + 'px'
});
$(window).resize(function () {
$('.pop_height').css({
'max-height': $(window).height() * 0.45 + 'px'
})
});
function readtext(obj) {
var pcode = $(obj).parent().parent('li').attr('val');
var text = prizeTexts.get(pcode);
$(obj).parent().next('.read_text').html(text);
$(obj).parent().next('i').toggle();
}
function readinfo(obj) {
var ptype = $(obj).parent().parent('li').attr('ptype');
var pcode = $(obj).parent().parent('li').attr('val');
var flow = $(obj).parent().parent('li').attr('flow');
var pname = $(obj).parent().parent('li').find('.pname').text();
setPrizeInfo(ptype, pcode, pname, flow);
$('.smak_prize').hide();
$('.material').show();
}
function setPrizeInfo(ptype, pcode, cue, flow) {
prizeCode = pcode;
prizeType = ptype;
$('.flow').val(flow);
let src = $('img[pcode="'+pcode+'"]').attr('src');
if (ptype == 'materialObject') {
$('.goods').find('.cue').text(cue);
$('.goods').find('.pimg').attr('src', src);
} else if (ptype == 'pcoupon') {
$('.winPrize').find('.cue').text(cue);
$('.winPrize').find('.remark').text('电子码将以短信的形式发送到您的手机号上,请注意查收');
$('.winPrize').find('.pimg').attr('src', src);
} else {
$('.winPrize').find('.cue').text(cue);
$('.winPrize').find('.remark').text('将在2小时内发放至您的一账通绑定银行卡中请注意查收');
$('.winPrize').find('.pimg').attr('src', src);
}
}
function prizes() {
$.ajax({
type: "POST",
url: contextRootPath+"/draw/prizes.action",
data: {drawCode: drawCode, isAll: 1},
dataType: "json",
success: function(data){
var content = '';
if (data.prizes) {
$.each(data.prizes, function (i, n) {
if (n.mobile) {
content = content + ('<li>恭喜 '+n.mobile+' 获得'+n.prizeName+'</li>');
}
});
}
$(".myscroll ul").html(content);
$('.myscroll').myScroll({
speed: 100, //数值越大,速度越慢
rowHeight: 24//li的高度
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
}
function saveAddr() {
var uname = $('.uname').val();
var phone = $('.phone').val();
var addr = $('.addr').val();
if ('integral' == prizeType) {
} else if ('materialObject' == prizeType) {
if (!uname) {
tip('请输入收货人姓名');
return;
}
if (!phone) {
tip('请输入收货人手机号码');
return;
}
if (!addr) {
tip('请输入收货人地址');
return;
}
} else {
}
var flow = $('.flow').val();
uname = getEntryptPwd(uname);
phone = getEntryptPwd(phone);
$.ajax({
type: "POST",
url: contextRootPath+"/draw/saveAddress.action",
data: {drawCode: drawCode, flow:flow, uname: uname, phone: phone, addr: addr},
dataType: "json",
success: function(data){
if (data.respCode == '1') {
if ('integral' == prizeType) {
} else if ('materialObject' == prizeType) {
} else {
}
$('.goods').hide();
$('.register').show();
} else {
tip(data.respMsg);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,25 @@
document.getElementsByTagName("html")[0].style.fontSize = document.documentElement.clientWidth / 15 + "px"; //改变窗口的时候重新计算大小
window.onresize = function () {
document.getElementsByTagName("html")[0].style.fontSize = document.documentElement.clientWidth / 15 + "px"
}
;(function() {
if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
handleFontSize();
} else {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", handleFontSize);
document.attachEvent("onWeixinJSBridgeReady", handleFontSize); }
}
function handleFontSize() {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function() {
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
});
}
})();

View File

@ -0,0 +1,51 @@
// JavaScript Document
(function($){
$.fn.myScroll = function(options){
//默认配置
var defaults = {
speed:80, //滚动速度,值越大速度越慢
rowHeight:18 //每行的高度
};
var opts = $.extend({}, defaults, options),intId = [];
function marquee(obj, step){
obj.find("ul").animate({
marginTop: '-=1'
},0,function(){
var s = Math.abs(parseInt($(this).css("margin-top")));
if(s >= step){
$(this).find("li").slice(0, 1).appendTo($(this));
$(this).css("margin-top", 0);
}
});
}
this.each(function(i){
var sh = opts["rowHeight"],speed = opts["speed"],_this = $(this);
intId[i] = setInterval(function(){
if(_this.find("ul").height()<=_this.height()){
clearInterval(intId[i]);
}else{
marquee(_this, sh);
}
}, speed);
_this.hover(function(){
clearInterval(intId[i]);
},function(){
intId[i] = setInterval(function(){
if(_this.find("ul").height()<=_this.height()){
clearInterval(intId[i]);
}else{
marquee(_this, sh);
}
}, speed);
});
});
}
})(jQuery);

View File

@ -0,0 +1,33 @@
function getParameter(param) {
var query = window.location.search;
var iLen = param.length;
var iStart = query.indexOf(param);
if (iStart == -1)
return "";
iStart += iLen + 1;
var iEnd = query.indexOf("&", iStart);
if (iEnd == -1)
return query.substring(iStart);
return query.substring(iStart, iEnd);
}
function filterCodeState(search) {
var arr = search.slice(1).split('&');
var result = '?';
for (var i in arr) {
var param_arr = arr[i].split('=');
var key = param_arr[0];
if (key=='code'||key=='state') {
continue;
}
result = result + (key+'='+param_arr[1]) + '&';
}
return result.slice(0,-1);
}
function getEntryptPwd(pwd){
var pubKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCy7kkPxA6rFFJD9oUQIr+unqPSW5zAnCrAVsrIz7iUOR/v7fVpxY+7hRGarmWW+Ipj+EfDdPJEvVab8KbCpNn4QR54IuXxkKhoAoaBCzpk4ml3VX7K62v7PwvyhpNk3oZRfnHDaVU4vpYkBnQt59ZCc/PqgU833/ZJRXuUxlaE2QIDAQAB';
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(pwd);
}

View File

@ -0,0 +1,375 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta charset="GBK">
<meta name="format-detection" content="telephone=no" />
<title>支付抽好礼,好运伴随你</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" type="text/css" href="css/popup.css"/>
<link rel="stylesheet" type="text/css" href="css/myPrize.css"/>
<link rel="stylesheet" type="text/css" href="css/rule.css"/>
<style type="text/css">
.popupBox{
width:100%;
height:100%;
/*overflow: hidden;*/
}
</style>
</head>
<body class="template_bg popupBox" style="background-color: #f9eec8;">
<div class="promotion_goBack rtn_btn" onclick="rtn()">
<span class="btn_back"><img src="images/btn_back.png" alt=""></span>
<span>返回</span>
</div>
<div class="promotion_container">
<header class="template_header">
<p class="header_left"><span onclick="drawrule()">活动规则</span></p>
<p class="header_right"><span onclick="myprizes()">我的奖品</span></p>
<!-- <p class="header_right" style="position: absolute;top: 2rem;right: 0;z-index: 10;"><span onclick="rtn()">&nbsp;返&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;回&nbsp;</span></p>-->
</header>
<!-- 推广图1 -->
<div class="promotion_main clearfix promotion_main_1 nowPage">
<!-- 红包 -->
<div class="zk_red_box">
<div class="zk_red_box_header">
<h2 class="title">剩余抽奖次数:<span class="num">0</span></h2>
<!-- 刮奖区 -->
<!-- <div class="scratch_off_popup"> -->
<canvas id="canvas" style="height: 4rem;"></canvas>
<!-- </div> -->
<!-- 三种状态 -->
<div style="display: none;" class="scratch_off_box success">
<p class="cue" style="display: none;">恭喜你获得现金红包</p>
<p class="amount" style="margin-top: 0.18rem;">0.08元</p>
<p class="remark" style="padding-top: 0.3rem;color: #bbadad;">红包将在2小时内发放至您的一账通绑定银行卡中请注意查收</p>
<p class="again_btn">再来一次</p>
</div>
<div style="display: none;" class="scratch_off_box fail">
<p>大奖离你还差一点儿,加油</p>
<p class="again_btn">再抽一次</p>
</div>
<div style="display: none;" class="scratch_off_box no_chance">
<p><img src="images/16.gif" style="width: 25px;vertical-align: middle;" alt="">您的抽奖机会已用完</p>
<p>推荐客户获取更多抽奖机会吧~</p>
</div>
</div>
<div class="zk_red_box_footer">
<p>今日有机会刮出</p>
</div>
</div>
<!-- 获奖人 -->
<div class="myscroll zk_carry_box">
<ul class="">
<!-- zk_carry_box -->
<li>恭喜 187****1234 获得现金红包</li>
</ul>
</div>
</div>
</div>
<div class="tip_copy" style="display: none;">
<p></p>
</div>
<!--我的奖品 弹窗-->
<div class='popup myPrize' style="display: none;">
<div class='popupMin'>
<img src="images/top02.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<div>
<img src="images/left.png">
<div>我的奖品</div>
<img src="images/right.png">
</div>
<div class='postListTop'>
<div>
<div>抽中奖品</div>
<div>获奖时间</div>
</div>
</div>
<div class='popList'>
</div>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect prizeDelect'>
</div>
<div class="prize_li" style="display: none;">
<div class="pname">奖品名称</div>
<div class="time">2020/08/05 09:00</div>
</div>
<!--活动规则-->
<div class='popup rule' style="display: none;">
<div class='popupMin'>
<img src="images/top02.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<div>
<img src="images/left.png">
<div>活动规则</div>
<img src="images/right.png">
</div>
<ul class='contBox' style="list-style: inside">
<li class='content'>活动时间2020年10月29日-12月31日。</li>
<li class='content'>活动期间客户推荐客户使用一账通完成支付不包含理财产品购买、手机充值、生活缴费即可获得一次红包抽奖机会中奖概率100%。抽奖机会有效期截止至2021年1月15日。</li>
<li class='content'>奖品现金红包29400个中奖概率100%,中奖后,系统将自动发放到您的手机或银行卡中,请及时查收。</li>
<li class='content'>最终奖品情况以活动实际情况为准,中国人寿保留调整相关奖品情况的权利,如奖品发生变更,将通过抽奖活动页面进行公示。</li>
<li class='content'>中奖后,用户需及时领取奖励,并提交所需领取信息,若因领奖信息有误、不完整而导致奖品未能及时获得、无法正常发放,或活动结束用户仍未领取奖品,则视为用户放弃该奖品。</li>
<li class='content'>用户参加活动即视为理解并同意本活动规则。</li>
<li class='content'>对活动有任何疑问请点击活动首页左侧的客服图标进行咨询也可联系中国人寿在线客服关注“中国人寿保险”微信公众号在对话框输入“0”再输入“2”即可</li>
<li class='content'>理财产品包括养老保障、现金宝、鑫享宝及其他基金产品。</li>
<li class='content'>在参与活动的过程中,如出现违规操作行为或违反活动规则进行恶意套利的用户,中国人寿有权追回奖励、取消其参与本次活动的资格并追究其法律责任。</li>
<li class='content'>本活动最终解释权归中国人寿电子商务有限公司所有,中国人寿电子商务有限公司保留修改上述条款和条件的权利,所有条款和条件将在法律允许的最大程度内使用。</li>
<li class='content'>本活动与苹果公司无关。</li>
<li class='content'>奖品数量有限,先到先得。</li>
</ul>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect ruleDelect'>
<span style='clear: both;'></span>
</div>
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/main.js"></script>
<script src="js/scroll.js"></script>
<script src="../../common/taglibs.js"></script>
<script src="js/util.js"></script>
<script src="js/draw.js"></script>
<script src="js/common.js"></script>
<script src="../../js/mobile/login_register/login.js"></script>
<script>
(function () {
var num = 0;
$.ajax({
type: "POST",
url: contextRootPath+"/draw/num.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
num = data.num||0;
$('.num').text(num);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
// 设置推广内容高度
function innerHeight() {
if(!$('.promotion_main_1').is(':hidden')) {
var arr = [];
$('.promotion_main_1 .promotion_content').each(function () {
var height = $(this).outerHeight();
arr.push(height);
})
var minHeight = Math.max.apply(null, arr);
$('.promotion_main_1 .promotion_content').css('minHeight', minHeight);
}
}
innerHeight();
$(window).resize(function () {
$('.promotion_main_1 .promotion_content').css('minHeight', '');
innerHeight();
})
$('.myscroll').myScroll({
speed: 80, //数值越大,速度越慢
rowHeight: 24//li的高度
});
// 设置初始的中奖状态 success-中奖 fail-未中奖 no_chance-没有抽奖机会
var status = '';
// 刮奖效果 -zk
window.onload = function(){
// let list = $('.scratch_off_box');
// setTimeout(()=>{
// for(var n=0;n<list.length;n++){
// if(list.eq(n).hasClass(`${status}`)){
// list.eq(n).siblings('.scratch_off_box').hide();
// return;
// }
// }
// })
var canvas = document.getElementById('canvas');
var cx = canvas.offsetWidth;
var cy = canvas.offsetHeight;
var style = window.getComputedStyle(canvas, null);
var cssWidth = parseFloat(style["width"]);
var cssHeight = parseFloat(style["height"]);
var scaleX = canvas.width / cssWidth; // 水平方向的缩放因子
var scaleY = canvas.height / cssHeight; // 垂直方向的缩放因子
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.lineWidth = '1';
function drawimage(){
var img = new Image();
img.src = 'images/img_scratch_popup.png';
img.style.width = '100%';
img.style.height = '100%';
img.onload = function(){
ctx.drawImage(img,0,0,cx*scaleX,cy*scaleY+10)
}
}
drawimage();
// ctx.fillStyle = '#c0c0c0';
var rect = canvas.getBoundingClientRect();
var time = 0;
var running = false;
// 新增-2020-8-20-初始化 中奖状态
canvas.addEventListener('touchstart',function(){
// success-中奖 fail-未中奖 no_chance-没有抽奖机会
if (running) {
console.log('running...');
return;
}
running=!running;
console.log('start');
start();
})
canvas.addEventListener('touchmove', function(e) {
e.preventDefault();
var touch = e.touches[0];
var x = touch.pageX;
var y = touch.pageY;
x -= rect.left;
y -= rect.top;
x *= scaleX; // 修正水平方向的坐标
y *= scaleY; // 修正垂直方向的坐标
// ctx.clearRect(x,y,15,15)
clearArcFun(x,y,15,ctx);
isArea();
})
function isArea(){
//判断刮开面积是否到达百分之六十
console.log('执行isArea效果')
var data = ctx.getImageData(0,0,canvas.width,canvas.height).data;//获取画布的信息
var n = 0 ;
for (var i = 0; i < data.length; i++) {
if (data[i] == 0) {
n++;
};
};
if (n >= data.length * 0.6) {
ctx.globalCompositeOperation = 'destination-over';//重点
// ctx.canvas.style.opacity = 0;
ctx.clearRect(0,0,canvas.width,canvas.height);
$('#canvas').css('pointer-events','none')
}
}
function clearArcFun(x,y,r,cxt){ //(x,y)为要清除的圆的圆心r为半径cxt为context
var stepClear=1;//别忘记这一步
clearArc(x,y,r);
function clearArc(x,y,radius){
var calcWidth=radius-stepClear;
var calcHeight=Math.sqrt(radius*radius-calcWidth*calcWidth);
var posX=x-calcWidth;
var posY=y-calcHeight;
var widthX=2*calcWidth;
var heightY=2*calcHeight;
if(stepClear<=radius){
cxt.clearRect(posX,posY,widthX,heightY);
stepClear+=1;
clearArc(x,y,radius);
}
}
}
// 再抽一次
$('.again_btn').click(function(){
if(num<1) {
$('.no_chance').show().siblings('.scratch_off_box').hide();
console.log('抽奖次数不足')
return;
}
drawimage();
$('#canvas').css('pointer-events','auto');
start();
})
function start() {
$.ajax({
type: "POST",
// async:false,
url: contextRootPath+"/draw/start.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
let respCode = data.respCode;
if (respCode != 1) {
let message = data.respMsg;
console.log(message);
if (respCode == '-2') {
to_login();
return;
}
if(respCode == 'GT00007') {
$('.no_chance').show().siblings('.scratch_off_box').hide();
console.log('抽奖次数不足');
return;
}
running = false;
tip(message);
return;
}
console.log(data.result);
if (data.result == '1') {
// $('.cue').text(data.cue);
$('.amount').text(data.cue);
$('.scratch_off_box').eq(0).show().siblings('.scratch_off_box').hide();
} else {
$('.scratch_off_box').eq(1).show().siblings('.scratch_off_box').hide();
}
prizeType = data.prizeType;
prizeCode = data.prizeCode;
num = data.available || 0;
$('.num').text(num);
setPrizeInfo(prizeType, prizeCode, data.cue, data.gatewayFlow);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
running = false;
}
});
}
}
})();
prizes();
</script>
</body>
</html>

View File

@ -0,0 +1,450 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no" />
<title>幸运大转盘,好运伴随你</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/popup.css"/>
<link rel="stylesheet" type="text/css" href="css/myPrize.css"/>
<link rel="stylesheet" type="text/css" href="css/register.css"/>
<link rel="stylesheet" type="text/css" href="css/winPrize.css"/>
<link rel="stylesheet" type="text/css" href="css/goods.css"/>
<link rel="stylesheet" type="text/css" href="css/rule.css"/>
<script src="/js/config.js"></script>
<style type="text/css">
.popupBox{
width:100%;
height:100%;
/*overflow: hidden;*/
}
</style>
<link rel="stylesheet" href="css/main.css">
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/awardRotate.js"></script>
<script src="js/util.js"></script>
<script src="js/draw.js"></script>
<script>
var turnplate = {
restaraunts: [], //大转盘奖品名称
colors: [], //大转盘奖品区块对应背景颜色
outsideRadius: 118, //大转盘外圆的半径
textRadius: 100, //大转盘奖品位置距离圆心的距离
insideRadius: 49, //大转盘内圆的半径
startAngle: 0, //开始角度
bRotate: false //false:停止;ture:旋转
};
var num = 0;
var prizeImgs = [];
$(document).ready(function () {
//动态添加大转盘的奖品与奖品区域背景颜色
turnplate.restaraunts = ["华为P40", "现金红包", "汽车加油卡", "现金红包", "爱奇艺月卡", "现金红包", "现金红包", "戴森吸尘器"];
turnplate.colors = ["#fffef8", "#ffdcae", "#fffef8", "#ffdcae", "#fffef8", "#ffdcae", "#fffef8", "#ffdcae"];
//
$.ajax({
type: "POST",
async:false,
url: contextRootPath+"/draw/init.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
prizes = data.prizes;
$('.prizeImg').each(function(i, v) {
let prizeImg = prizes[i].prizeImg;
let pcode = prizes[i].prizeCode;
let prizeName = prizes[i].prizeName;
turnplate.restaraunts[i] = prizeName;
$(v).attr('pcode', pcode);
if (prizeImg) {
$(v).attr('src', contextRootPath+ prizeImg);
}
});
// drawRouletteWheel();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
$.ajax({
type: "POST",
url: contextRootPath+"/draw/num.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
num = data.num||0;
$('.num').text(num);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
}
});
var rotateTimeOut = function () {
$('#wheelcanvas').rotate({
angle:0,
animateTo: 2160,
duration: 8000,
callback: function () {
alert('网络超时,请检查您的网络设置!');
}
});
};
//旋转转盘 item:奖品位置; txt提示语;
var rotateFn = function (item, txt) {
var angles = item * (360 / turnplate.restaraunts.length) - (360 / (turnplate.restaraunts.length * 2));
// 商品对应的值
// 1:22.5 飞吻再接再厉
// 2:67.5 i购电子券
// 3:112.5 积分
// 4:157.5几率翻倍
// 5:202.5京东E卡电子券
// 6:247.5西门子洗衣机
// 7:292.5换个姿势再来一次
// 8:337.5一账通电子券
if (angles < 270) {
angles = 270 - angles;
} else {
angles = 360 - angles + 270;
}
$('#wheelcanvas').stopRotate();
$('#wheelcanvas').rotate({
angle: 0,
animateTo: angles + 1800,
duration: 8000,
callback: function () { //回调
console.log(txt);
if ('materialObject' == prizeType) {
$('.goods').show();
} else {
$('.winPrize').show();
}
turnplate.bRotate = false;
}
});
};
$('.pointer').click(function () {
if (turnplate.bRotate) {
console.log('return');
return;
}
turnplate.bRotate = !turnplate.bRotate;
//获取随机数(奖品个数范围内)
//奖品数量等于10,指针落在对应奖品区域的中心角度[252, 216, 180, 144, 108, 72, 36, 360, 324, 288]
$.ajax({
type: "POST",
// async:false,
url: contextRootPath+"/draw/start.action",
data: {drawCode: drawCode},
dataType: "json",
success: function(data){
let respCode = data.respCode;
if (respCode != 1) {
let message = data.respMsg;
console.log(message);
turnplate.bRotate = false;
if (respCode == '-2') {
to_login();
return;
}
tip(message);
return;
}
console.log(data.displayOrder);
var item = parseInt(data.displayOrder);
rotateFn(item, turnplate.restaraunts[item-1]);
prizeType = data.prizeType;
prizeCode = data.prizeCode;
num = data.available || 0;
$('.num').text(num);
setPrizeInfo(prizeType, prizeCode, data.cue, data.gatewayFlow);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('网络异常', textStatus, errorThrown);
turnplate.bRotate = false;
}
});
});
});
function rnd(n, m) {
var random = Math.floor(Math.random() * (m - n + 1) + n);
return random;
}
//页面所有元素加载完毕后执行drawRouletteWheel()方法对转盘进行渲染
window.onload = function () {
drawRouletteWheel();
};
function drawRouletteWheel() {
var canvas = document.getElementById("wheelcanvas");
if (canvas.getContext) {
//根据奖品个数计算圆周角度
var arc = Math.PI / (turnplate.restaraunts.length / 2);
var ctx = canvas.getContext("2d");
//在给定矩形内清空一个矩形
ctx.clearRect(0, 0, 304, 304);
//strokeStyle 属性设置或返回用于笔触的颜色、渐变或模式
ctx.strokeStyle = "#fff";
//font 属性设置或返回画布上文本内容的当前字体属性
ctx.font = 'normal 12px Microsoft YaHei';
for (var i = 0; i < turnplate.restaraunts.length; i++) {
var angle = turnplate.startAngle + i * arc;
ctx.fillStyle = turnplate.colors[i];
ctx.beginPath();
//arc(x,y,r,起始角,结束角,绘制方向) 方法创建弧/曲线(用于创建圆或部分圆)
ctx.arc(152, 152, turnplate.outsideRadius, angle, angle + arc, false);
ctx.arc(152, 152, turnplate.insideRadius, angle + arc, angle, true);
ctx.stroke();
ctx.fill();
//锁画布(为了保存之前的画布状态)
ctx.save();
//改变画布文字颜色
var b = i + 2;
if (b % 2) {
ctx.fillStyle = "#cd2b2b";
} else {
ctx.fillStyle = "#cd2b2b";
};
//----绘制奖品开始----
var text = turnplate.restaraunts[i];
var line_height = 17;
//translate方法重新映射画布上的 (0,0) 位置
ctx.translate(152 + Math.cos(angle + arc / 2) * turnplate.textRadius, 152 + Math.sin(angle + arc / 2) * turnplate.textRadius);
//rotate方法旋转当前的绘图
ctx.rotate(angle + arc / 2 + Math.PI / 2);
/** 下面代码根据奖品类型、奖品名称长度渲染不同效果,如字体、颜色、图片效果。(具体根据实际情况改变) **/
if (text.indexOf("盘") > 0) {//判断字符进行换行
var texts = text.split("盘");
for (var j = 0; j < texts.length; j++) {
ctx.font = j == 0 ? 'bold 20px Microsoft YaHei' : '14px Microsoft YaHei';
if (j == 0) {
ctx.fillText(texts[j] + "盘", -ctx.measureText(texts[j] + "盘").width / 2, j * line_height);
} else {
ctx.fillText(texts[j], -ctx.measureText(texts[j]).width / 2, j * line_height * 1.2); //调整行间距
}
}
} else if (text.length > 8) {//奖品名称长度超过一定范围
text = text.substring(0, 8) + "||" + text.substring(8);
var texts = text.split("||");
for (var j = 0; j < texts.length; j++) {
ctx.fillText(texts[j], -ctx.measureText(texts[j]).width / 2, j * line_height);
}
} else {
//在画布上绘制填色的文本。文本的默认颜色是黑色
//measureText()方法返回包含一个对象,该对象包含以像素计的指定字体宽度
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
}
//添加对应图标
// alert(text.indexOf(turnplate.restaraunts[1]))
var imgId = 'diy'+(i+1)+'-img';
var img = document.getElementById(imgId);
try {
img.onload = function () {
ctx.drawImage(img, -15, 5, 35, 35);
};
ctx.drawImage(img, -15, 5, 35, 35);
} catch (e) {
console.log(e);
}
//把当前画布返回调整到上一个save()状态之前
ctx.restore();
//----绘制奖品结束----
}
}
};
</script>
</head>
<body class="template_bg popupBox" style="background-color: #fbdaaf;">
<div class="draw_container">
<header class="template_header">
<p class="header_left"><span onclick="drawrule()">活动规则</span></p>
<p class="header_right"><span onclick="myprizes()">我的奖品</span></p>
<!-- <p class="header_right" style="position: absolute;top: 2rem;right: 0;"><span onclick="rtn()">&nbsp;返&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;回&nbsp;</span></p>-->
</header>
<div class="lucy_wheel">
<img class="prizeImg" src="images/icon_a.png" id="diy1-img" style="display:none;" />
<img class="prizeImg" src="images/icon_b.png" id="diy2-img" style="display:none;" />
<img class="prizeImg" src="images/icon_c.png" id="diy3-img" style="display:none;" />
<img class="prizeImg" src="images/icon_b.png" id="diy4-img" style="display:none;" />
<img class="prizeImg" src="images/icon_e.png" id="diy5-img" style="display:none;" />
<img class="prizeImg" src="images/icon_b.png" id="diy6-img" style="display:none;" />
<img class="prizeImg" src="images/icon_b.png" id="diy7-img" style="display:none;" />
<img class="prizeImg" src="images/icon_h.png" id="diy8-img" style="display:none;" />
<div class="banner">
<p class="draw_title">您有<span class="num">0</span>次抽奖机会,祝您好运!</p>
<div class="turnplate"
style="background-image:url(images/cj_bg2.png);background-size:100% 100%;">
<canvas class="item" id="wheelcanvas" width="304px" height="304px"></canvas>
<img class="pointer" src="images/btn_start.png"/>
</div>
<img src="images/icon_footer.png" alt="" class="draw_footer">
</div>
<div class="lucy_info">
<img src="images/icon_hb1.png" />
<div class="myscroll">
<ul>
<li>恭喜 187****1234 获得爱奇艺月卡</li>
</ul>
</div>
</div>
</div>
</div>
<div class="tip_copy" style="display: none;">
<p></p>
</div>
<!--我的奖品 弹窗-->
<div class='popup myPrize' style="display: none;">
<div class='popupMin'>
<img src="images/top02.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<div>
<img src="images/left.png">
<div>我的奖品</div>
<img src="images/right.png">
</div>
<div class='postListTop'>
<div>
<div>抽中奖品</div>
<div>获奖时间</div>
</div>
</div>
<div class='popList'>
</div>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect prizeDelect'>
</div>
<div class="prize_li" style="display: none;">
<div class="pname">奖品名称</div>
<div class="time">2020/08/05 09:00</div>
</div>
<!--登记 弹窗-->
<div class='popup register' style="display: none;">
<div class='popupMin'>
<img src="images/top01.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<img src="images/success.png" >
<div>信息登记成功</div>
<div>奖品将在活动结束后四十个工作日寄送</div>
<img src="images/btn.png" class='popBtn popBtn1'>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect regDelect'>
</div>
<!--中奖 弹窗-->
<div class='popup winPrize' style="display: none;">
<div class='popupMin'>
<img src="images/top01.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<img class="pimg" src="images/prize.png">
<div>恭喜您获得</div>
<div class="cue">爱奇艺月卡</div>
<div class="remark">电子码将以短信的形式发送到您的手机号上,请注意查收</div>
<img src="images/btn.png" class='popBtn popBtn2'>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect winDelect'>
</div>
<!--中奖 实物奖 弹窗-->
<div class='popup goods' style="display: none;">
<div class='popupMin'>
<img src="images/top01.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<img class="pimg" src="images/prize1.png">
<div>恭喜您获得</div>
<div class="cue">戴森吸尘器</div>
<div>请留下收货信息,我们奖品将在活动结束后四十个工作日寄送</div>
<input class="uname" type="text" value="" placeholder="请输入收货人姓名"/>
<input class="phone" type="text" value="" placeholder="请输入收货人手机号码" maxlength="11"/>
<textarea class="addr" rows="" cols="" placeholder="请输入收货地址"></textarea>
<input class="flow" type="hidden" value="">
<img src="images/btn1.png" class='popBtn popBtn3' onclick="saveAddr()">
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect goodsDelect'>
</div>
<!--活动规则-->
<div class='popup rule' style="display: none;">
<div class='popupMin'>
<img src="images/top02.png" class='top'>
<div class='popCont'>
<div class='left'></div>
<div class='cont'>
<div>
<img src="images/left.png">
<div>活动规则</div>
<img src="images/right.png">
</div>
<ul class='contBox' style="list-style: inside;">
<li class='content'>活动时间2020年10月29日-12月31日。</li>
<li class='content'>活动期间客户使用一账通完成支付不包含理财产品购买、手机充值、生活缴费即可获得一次抽奖机会。奖品包括华为手机、戴森吸尘器、爱奇艺月卡、现金红包、加油卡等。中奖概率100%。抽奖机会有效期截止至2021年1月15日。</li>
<li class='content'>活动期间客户推荐客户使用一账通完成支付不包含理财产品购买、手机充值、生活缴费即可获得一次红包抽奖机会中奖概率100%。抽奖机会有效期截止至2021年1月15日。</li>
<li class='content'>奖品包括华为手机、戴森吸尘器、爱奇艺月卡、现金红包、加油卡等。其中华为手机1台中奖概率为0.0014%戴森吸尘器1台中奖概率为0.0014%爱奇艺视频月卡100张中奖概率0.14%100元加油卡10张中奖概率 0.01%现金红包7000个金额0.08-888元不等中奖概率99.84%。</li>
<li class='content'>关于非实物奖品发放,系统将自动发放到您的手机或银行卡中,请及时查收。</li>
<li class='content'>关于实物奖品发放我司将在活动结束后的40个工作日内审核获奖信息并通过快递寄出。</li>
<li class='content'>最终奖品情况以活动实际情况为准,中国人寿保留调整相关奖品情况的权利,如奖品发生变更,将通过抽奖活动页面进行公示。</li>
<li class='content'>中奖后,用户需及时领取奖励,并提交所需领取信息,若因领奖信息有误、不完整而导致奖品未能及时获得、无法正常发放,或活动结束用户仍未领取奖品,则视为用户放弃该奖品。</li>
<li class='content'>用户参加活动即视为理解并同意本活动规则。</li>
<li class='content'>对活动有任何疑问请点击活动首页左侧的客服图标进行咨询也可联系中国人寿在线客服关注“中国人寿保险”微信公众号在对话框输入“0”再输入“2”即可</li>
<li class='content'>理财产品包括养老保障、现金宝、鑫享宝及其他基金产品。</li>
<li class='content'>在参与活动的过程中,如出现违规操作行为或违反活动规则进行恶意套利的用户,中国人寿有权追回奖励、取消其参与本次活动的资格并追究其法律责任。</li>
<li class='content'>本活动最终解释权归中国人寿电子商务有限公司所有,中国人寿电子商务有限公司保留修改上述条款和条件的权利,所有条款和条件将在法律允许的最大程度内使用。</li>
<li class='content'>本活动与苹果公司无关。</li>
<li class='content'>奖品数量有限,先到先得。</li>
</ul>
</div>
<div class='right'></div>
</div>
<img src="images/popupList04.png" class='bottom'>
</div>
<img src="images/delect.png" class='popDelect ruleDelect'>
<span style='clear: both;'></span>
</div>
<script src="js/main.js"></script>
<script src="js/scroll.js"></script>
<script src="js/common.js"></script>
<script>
prizes();
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More