Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/1.8.0-uniapp
Conflicts: sql/optional/mall/mall.sqlplp
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.framework.captcha.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ClassUtil;
|
||||||
|
import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
|
||||||
|
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
|
||||||
|
import com.anji.captcha.service.CaptchaCacheService;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class YudaoCaptchaConfiguration {
|
||||||
|
|
||||||
|
static {
|
||||||
|
// 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
|
||||||
|
// 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
|
||||||
|
ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CaptchaCacheService captchaCacheService(StringRedisTemplate stringRedisTemplate) {
|
||||||
|
return new RedisCaptchaServiceImpl(stringRedisTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package cn.iocoder.yudao.framework.captcha.core.service;
|
||||||
|
|
||||||
|
import com.anji.captcha.service.CaptchaCacheService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 Redis 实现验证码的存储
|
||||||
|
*
|
||||||
|
* @author 星语
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor // 保证 aj-captcha 的 SPI 创建
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RedisCaptchaServiceImpl implements CaptchaCacheService {
|
||||||
|
|
||||||
|
@Resource // 保证 aj-captcha 的 SPI 创建时的注入
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return "redis";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(String key, String value, long expiresInSeconds) {
|
||||||
|
stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists(String key) {
|
||||||
|
return Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String key) {
|
||||||
|
stringRedisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(String key) {
|
||||||
|
return stringRedisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long increment(String key, long val) {
|
||||||
|
return stringRedisTemplate.opsForValue().increment(key,val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
|
cn.iocoder.yudao.framework.captcha.config.YudaoCaptchaConfiguration
|
||||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 29 KiB |
@ -1,3 +0,0 @@
|
|||||||
### 请求 /captcha/get-image 接口 => 成功
|
|
||||||
GET {{baseUrl}}/system/captcha/get-image
|
|
||||||
tenant-id: {{adminTenentId}}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.controller.admin.common;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.common.vo.CaptchaImageRespVO;
|
|
||||||
import cn.iocoder.yudao.module.system.service.common.CaptchaService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.annotation.security.PermitAll;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
|
|
||||||
@Api(tags = "管理后台 - 验证码")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/system/captcha")
|
|
||||||
public class CaptchaController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CaptchaService captchaService;
|
|
||||||
|
|
||||||
@GetMapping("/get-image")
|
|
||||||
@PermitAll
|
|
||||||
@ApiOperation("生成图片验证码")
|
|
||||||
public CommonResult<CaptchaImageRespVO> getCaptchaImage() {
|
|
||||||
return success(captchaService.getCaptchaImage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.convert.common;
|
|
||||||
|
|
||||||
import cn.hutool.captcha.AbstractCaptcha;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.common.vo.CaptchaImageRespVO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
@Mapper
|
|
||||||
public interface CaptchaConvert {
|
|
||||||
|
|
||||||
CaptchaConvert INSTANCE = Mappers.getMapper(CaptchaConvert.class);
|
|
||||||
|
|
||||||
default CaptchaImageRespVO convert(String uuid, AbstractCaptcha captcha) {
|
|
||||||
return CaptchaImageRespVO.builder().uuid(uuid).img(captcha.getImageBase64()).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.framework.captcha.config;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableConfigurationProperties(CaptchaProperties.class)
|
|
||||||
public class CaptchaConfig {
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.common;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.common.vo.CaptchaImageRespVO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证码 Service 接口
|
|
||||||
*/
|
|
||||||
public interface CaptchaService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得验证码图片
|
|
||||||
*
|
|
||||||
* @return 验证码图片
|
|
||||||
*/
|
|
||||||
CaptchaImageRespVO getCaptchaImage();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否开启图片验证码
|
|
||||||
*
|
|
||||||
* @return 是否
|
|
||||||
*/
|
|
||||||
Boolean isCaptchaEnable();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得 uuid 对应的验证码
|
|
||||||
*
|
|
||||||
* @param uuid 验证码编号
|
|
||||||
* @return 验证码
|
|
||||||
*/
|
|
||||||
String getCaptchaCode(String uuid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除 uuid 对应的验证码
|
|
||||||
*
|
|
||||||
* @param uuid 验证码编号
|
|
||||||
*/
|
|
||||||
void deleteCaptchaCode(String uuid);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.system.service.common;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.common.vo.CaptchaImageRespVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.redis.common.CaptchaRedisDAO;
|
|
||||||
import cn.iocoder.yudao.module.system.framework.captcha.config.CaptchaProperties;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseRedisUnitTest;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
@Import({CaptchaServiceImpl.class, CaptchaProperties.class, CaptchaRedisDAO.class})
|
|
||||||
public class CaptchaServiceTest extends BaseRedisUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CaptchaServiceImpl captchaService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private CaptchaRedisDAO captchaRedisDAO;
|
|
||||||
@Resource
|
|
||||||
private CaptchaProperties captchaProperties;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetCaptchaImage() {
|
|
||||||
// 调用
|
|
||||||
CaptchaImageRespVO respVO = captchaService.getCaptchaImage();
|
|
||||||
// 断言
|
|
||||||
assertNotNull(respVO.getUuid());
|
|
||||||
assertNotNull(respVO.getImg());
|
|
||||||
String captchaCode = captchaRedisDAO.get(respVO.getUuid());
|
|
||||||
assertNotNull(captchaCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetCaptchaCode() {
|
|
||||||
// 准备参数
|
|
||||||
String uuid = randomString();
|
|
||||||
String code = randomString();
|
|
||||||
// mock 数据
|
|
||||||
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
String resultCode = captchaService.getCaptchaCode(uuid);
|
|
||||||
// 断言
|
|
||||||
assertEquals(code, resultCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteCaptchaCode() {
|
|
||||||
// 准备参数
|
|
||||||
String uuid = randomString();
|
|
||||||
String code = randomString();
|
|
||||||
// mock 数据
|
|
||||||
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
captchaService.deleteCaptchaCode(uuid);
|
|
||||||
// 断言
|
|
||||||
assertNull(captchaRedisDAO.get(uuid));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
######################################################################
|
||||||
|
# Build Tools
|
||||||
|
|
||||||
|
/unpackage/*
|
||||||
|
/node_modules/*
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Development Tools
|
||||||
|
|
||||||
|
/.idea/*
|
||||||
|
/.vscode/*
|
||||||
|
/.hbuilderx/*
|
||||||
|
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<script>
|
||||||
|
import config from './config'
|
||||||
|
import store from '@/store'
|
||||||
|
import { getAccessToken } from '@/utils/auth'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onLaunch: function() {
|
||||||
|
this.initApp()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化应用
|
||||||
|
initApp() {
|
||||||
|
// 初始化应用配置
|
||||||
|
this.initConfig()
|
||||||
|
// 检查用户登录状态
|
||||||
|
//#ifdef H5
|
||||||
|
this.checkLogin()
|
||||||
|
//#endif
|
||||||
|
},
|
||||||
|
initConfig() {
|
||||||
|
this.globalData.config = config
|
||||||
|
},
|
||||||
|
checkLogin() {
|
||||||
|
if (!getAccessToken()) {
|
||||||
|
this.$tab.reLaunch('/pages/login')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/static/scss/index.scss'
|
||||||
|
</style>
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 芋道
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 登录方法
|
||||||
|
export function login(username, password, captchaVerification) {
|
||||||
|
const data = {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
captchaVerification
|
||||||
|
}
|
||||||
|
return request({
|
||||||
|
url: '/system/auth/login',
|
||||||
|
headers: {
|
||||||
|
isToken: false
|
||||||
|
},
|
||||||
|
'method': 'POST',
|
||||||
|
'data': data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户详细信息
|
||||||
|
export function getInfo() {
|
||||||
|
return request({
|
||||||
|
url: '/system/auth/get-permission-info',
|
||||||
|
'method': 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退出方法
|
||||||
|
export function logout() {
|
||||||
|
return request({
|
||||||
|
url: '/system/auth/logout',
|
||||||
|
'method': 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取验证码
|
||||||
|
export function getCaptcha(data) {
|
||||||
|
return request({
|
||||||
|
url: '/captcha/get',
|
||||||
|
headers: {
|
||||||
|
isToken: false,
|
||||||
|
isTenant: false
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
'data': data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证验证码
|
||||||
|
export function checkCaptcha(data) {
|
||||||
|
return request({
|
||||||
|
url: '/captcha/check',
|
||||||
|
headers: {
|
||||||
|
isToken: false,
|
||||||
|
isTenant: false
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
'data': data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
import upload from '@/utils/upload'
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 用户密码重置
|
||||||
|
export function updateUserPwd(oldPassword, newPassword) {
|
||||||
|
const data = {
|
||||||
|
oldPassword,
|
||||||
|
newPassword
|
||||||
|
}
|
||||||
|
return request({
|
||||||
|
url: '/system/user/profile/update-password',
|
||||||
|
method: 'PUT',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户个人信息
|
||||||
|
export function getUserProfile() {
|
||||||
|
return request({
|
||||||
|
url: '/system/user/profile/get',
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改用户个人信息
|
||||||
|
export function updateUserProfile(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/user/profile/update',
|
||||||
|
method: 'PUT',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户头像上传
|
||||||
|
export function uploadAvatar(data) {
|
||||||
|
return upload({
|
||||||
|
url: '/system/user/profile/update-avatar',
|
||||||
|
method: 'PUT',
|
||||||
|
name: data.name,
|
||||||
|
filePath: data.filePath
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-section">
|
||||||
|
<view class="uni-section-header" @click="onClick">
|
||||||
|
<view class="uni-section-header__decoration" v-if="type" :class="type" />
|
||||||
|
<slot v-else name="decoration"></slot>
|
||||||
|
|
||||||
|
<view class="uni-section-header__content">
|
||||||
|
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
|
||||||
|
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="uni-section-header__slot-right">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="uni-section-content" :style="{padding: _padding}">
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Section 标题栏
|
||||||
|
* @description 标题栏
|
||||||
|
* @property {String} type = [line|circle|square] 标题装饰类型
|
||||||
|
* @value line 竖线
|
||||||
|
* @value circle 圆形
|
||||||
|
* @value square 正方形
|
||||||
|
* @property {String} title 主标题
|
||||||
|
* @property {String} titleFontSize 主标题字体大小
|
||||||
|
* @property {String} titleColor 主标题字体颜色
|
||||||
|
* @property {String} subTitle 副标题
|
||||||
|
* @property {String} subTitleFontSize 副标题字体大小
|
||||||
|
* @property {String} subTitleColor 副标题字体颜色
|
||||||
|
* @property {String} padding 默认插槽 padding
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UniSection',
|
||||||
|
emits:['click'],
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
titleFontSize: {
|
||||||
|
type: String,
|
||||||
|
default: '14px'
|
||||||
|
},
|
||||||
|
titleColor:{
|
||||||
|
type: String,
|
||||||
|
default: '#333'
|
||||||
|
},
|
||||||
|
subTitle: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
subTitleFontSize: {
|
||||||
|
type: String,
|
||||||
|
default: '12px'
|
||||||
|
},
|
||||||
|
subTitleColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#999'
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
_padding(){
|
||||||
|
if(typeof this.padding === 'string'){
|
||||||
|
return this.padding
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.padding?'10px':''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
title(newVal) {
|
||||||
|
if (uni.report && newVal !== '') {
|
||||||
|
uni.report('title', newVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick() {
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" >
|
||||||
|
$uni-primary: #2979ff !default;
|
||||||
|
|
||||||
|
.uni-section {
|
||||||
|
background-color: #fff;
|
||||||
|
.uni-section-header {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 10px;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
&__decoration{
|
||||||
|
margin-right: 6px;
|
||||||
|
background-color: $uni-primary;
|
||||||
|
&.line {
|
||||||
|
width: 4px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.circle {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-top-right-radius: 50px;
|
||||||
|
border-top-left-radius: 50px;
|
||||||
|
border-bottom-left-radius: 50px;
|
||||||
|
border-bottom-right-radius: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.square {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
.distraction {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&-sub {
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__slot-right{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-section-content{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
/**
|
||||||
|
* @word 要加密的内容
|
||||||
|
* @keyWord String 服务器随机返回的关键字
|
||||||
|
* */
|
||||||
|
export function aesEncrypt(word, keyWord = "XwKsGlMcdPMEhR1B") {
|
||||||
|
var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
|
var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||||
|
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.Pkcs7
|
||||||
|
});
|
||||||
|
return encrypted.toString();
|
||||||
|
}
|
||||||