jdk版本更换为17

This commit is contained in:
wangchen147 2024-12-12 18:32:42 +08:00
parent 7079fbeea4
commit 2a16950fbd
2310 changed files with 14109 additions and 6708 deletions

View File

@ -186,5 +186,8 @@
"generateMin": "输入字符不能小于",
"generateUnit": "位",
"startDate": "开始时间",
"endDate": "结束时间"
"endDate": "结束时间",
"newcomerNumberColor": "数字颜色",
"newcomerNumberBg": "数字背景色",
"newcomerOtherColor": "文字颜色"
}

View File

@ -1,6 +1,6 @@
import type { App } from 'vue'
import type {App} from 'vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { useCssVar, useTitle } from '@vueuse/core'
import {useCssVar, useTitle} from '@vueuse/core'
import colorFunction from 'css-color-function'
import storage from './storage'
@ -16,7 +16,6 @@ export function useElementIcon(app: App): void {
/**
*
* @param color
*/
export function setThemeColor(color: string, mode: string = 'light'): void {
useCssVar('--el-color-primary', null).value = color
@ -41,7 +40,7 @@ export function setThemeColor(color: string, mode: string = 'light'): void {
}
Object.keys(colors[mode]).forEach((key) => {
useCssVar('--el-color-primary' + '-' + key, null).value = colorFunction.convert(`color(${color} ${colors[mode][key]})`)
useCssVar('--el-color-primary' + '-' + key, null).value = colorFunction.convert(`color(${ color } ${ colors[mode][key] })`)
})
}
@ -49,7 +48,9 @@ export function setThemeColor(color: string, mode: string = 'light'): void {
* 访
*/
export function getAppType() {
const path = location.pathname.split('/').filter((val) => { return val })
const path = location.pathname.split('/').filter((val) => {
return val
})
if (!path.length) {
return 'admin'
@ -141,7 +142,7 @@ export function img(path: string): string {
* @param path
* @returns
*/
export function assetImg (path: string) {
export function assetImg(path: string) {
return new URL('@/', import.meta.url) + path
}
@ -167,7 +168,7 @@ export function strByteLength(str: string = ''): number {
* @param url
*/
export function urlToRouteRaw(url: string) {
const query = {}
const query: any = {}
const [path, param] = url.split('?')
param && param.split('&').forEach((str: string) => {
@ -212,7 +213,7 @@ export function deepClone(obj: object) {
* @param {Boolean} firstU
* @param {Number} radix
*/
export function guid(len = 10, firstU = true, radix = null) {
export function guid(len = 10, firstU = true, radix: any = null) {
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
const uuid = []
radix = radix || chars.length
@ -236,80 +237,168 @@ export function guid(len = 10, firstU = true, radix = null) {
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
if (firstU) {
uuid.shift()
return `u${uuid.join('')}`
return `u${ uuid.join('') }`
}
return uuid.join('')
}
/**
*
*/
export function moneyFormat(money : string) : string {
return isNaN(parseFloat(money)) ? money : parseFloat(money).toFixed(2)
*
*/
export function moneyFormat(money: string): string {
return isNaN(parseFloat(money)) ? money : parseFloat(money).toFixed(2)
}
/**
*
* @param {Object} timeStamp
*/
export function timeStampTurnTime(timeStamp, type = "") {
if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) {
var date = new Date();
date.setTime(timeStamp * 1000);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
h = h < 10 ? ('0' + h) : h;
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second;
if (type) {
if (type == 'yearMonthDay') {
return y + '年' + m + '月' + d + '日';
}
return y + '-' + m + '-' + d;
} else {
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
}
export function timeStampTurnTime(timeStamp: any, type = "") {
if (timeStamp != undefined && timeStamp != "" && timeStamp > 0) {
var date = new Date();
date.setTime(timeStamp * 1000);
var y: any = date.getFullYear();
var m: any = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d: any = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h: any = date.getHours();
h = h < 10 ? ('0' + h) : h;
var minute: any = date.getMinutes();
var second: any = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second;
if (type) {
if (type == 'yearMonthDay') {
return y + '年' + m + '月' + d + '日';
}
return y + '-' + m + '-' + d;
} else {
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
}
} else {
return "";
}
} else {
return "";
}
}
/**
* ()
* @param event
*/
export function filterDigit(event:any){
event.target.value = event.target.value.replace(/[^\d\.]/g,'');
event.target.value = event.target.value.replace(/^\./g,'');
event.target.value = event.target.value.replace(/\.{2,}/g,'.');
export function filterDigit(event: any) {
event.target.value = event.target.value.replace(/[^\d\.]/g, '');
event.target.value = event.target.value.replace(/^\./g, '');
event.target.value = event.target.value.replace(/\.{2,}/g, '.');
// 限制最多两位小数
const decimalParts = event.target.value.split('.');
if (decimalParts.length > 1 && decimalParts[1].length > 2) {
// 如果有小数部分且超过两位,则截取前两位
event.target.value = `${decimalParts[0]}.${decimalParts[1].slice(0, 2)}`;
event.target.value = `${ decimalParts[0] }.${ decimalParts[1].slice(0, 2) }`;
}
}
/**
*
* @param event
* @param event
*/
export function filterNumber(event:any){
event.target.value = event.target.value.replace(/[^\d]/g,'');
export function filterNumber(event: any) {
event.target.value = event.target.value.replace(/[^\d]/g, '');
}
/**
*
* @param event
* @param event
*/
export function filterSpecial(event:any){
export function filterSpecial(event: any) {
event.target.value = event.target.value.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '')
event.target.value = event.target.value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g,'')
event.target.value = event.target.value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g, '')
}
export function importIconFontCss() {
// const modulesFiles = {}; // import.meta.glob('@/styles/icon/official-iconfont.css', { eager: true })
// const modulesFiles = import.meta.glob('@/addon/**/assets/icon/*.css', { eager: true })
// // console.log('modulesFiles',modulesFiles)
//
// const modules:any = {}
// for (const [key, value] of Object.entries(modulesFiles)) {
// const moduleName:any = key.split('/').pop()
// const name = moduleName.split('.')[0]
// modules[name] = value.default
// }
//
// // console.log('modules',modules)
//
// for(let key in modules) {
// // console.log('modules[key]',modules[key])
// import(modules[key]).then((module) => {
// // console.log('module', module.default);
// }).catch((e) => {
// // console.log('caca', e)
// });
// }
}
export function getIcon() {
// const modulesFiles = import.meta.glob('@/styles/icon/*.json', { eager: true })
// const addonModulesFiles = import.meta.glob('@/addon/**/assets/icon/*.json', { eager: true })
// addonModulesFiles && Object.assign(modulesFiles, addonModulesFiles)
//
// // const modulesFiles = {}; // import.meta.glob('@/styles/icon/official-iconfont.css', { eager: true })
// // const modulesFiles = import.meta.glob('@/styles/icon/*.json', { eager: true })
// console.log('modulesFiles', modulesFiles)
//
// const modules = {}
// for (const [key, value] of Object.entries(modulesFiles)) {
// const moduleName = key.split('/').pop()
// console.log('moduleName',moduleName)
// const name = moduleName.split('.')[0]
// modules[name] = value.default
// }
// console.log('modules', modules)
// // const addonModulesFiles = import.meta.glob('@/addon/**/assets/icon/*.json', { eager: true })
}
/**
*
* @param page
* @param limit
* @param where
*/
export function setTablePageStorage(page: any = 1, limit: any = 10, where: any = {}) {
var data = storage.get('tablePageStorage');
if (!data) {
data = {};
}
var key = location.pathname + JSON.stringify(where);
data[key] = {
page,
limit
};
var MAX_COUNT = 5; // 最多存储 5 个页面的分页缓存,超出则删除最开始的第一个页面
if (Object.keys(data).length > MAX_COUNT) {
delete data[Object.keys(data)[0]];
}
storage.set({ key: 'tablePageStorage', data });
}
/**
*
* @param where
*/
export function getTablePageStorage(where: any = {}) {
var data = storage.get('tablePageStorage');
var key = location.pathname + JSON.stringify(where);
if (!data || !data[key]) {
data = {
page: 1,
limit: 10
};
} else {
data = data[key];
}
return data;
}

View File

@ -14,6 +14,13 @@
<name>niucloud-addon</name>
<description>niucloud 应用管理模块</description>
<modules>
<module>tour</module>
<module>sms-email</module>
<module>recharge</module>
<module>cms</module>
<module>shop</module>
<module>shop_giftcard</module>
<module>shop_fenxiao</module>
</modules>
<dependencies>
<dependency>

View File

@ -10,9 +10,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
</properties>
<dependencies>

View File

@ -15,7 +15,7 @@ public class Boot {
EnvironmentValidator environmentValidator = EnvironmentValidator.getInstance(bootConfig);
if (environmentValidator.checkEnvironment()) {
if (!environmentValidator.checkJreUsable()) {
System.out.println("当前Java环境是:" + bootConfig.getJavaVersion() + ",请安装Java8的运行环境.");
System.out.println("当前Java环境是:" + bootConfig.getJavaVersion() + ",请安装Java17的运行环境.");
System.exit(0);
}
if (!environmentValidator.readAppEnv()) {

View File

@ -65,7 +65,7 @@ public class EnvironmentValidator {
* @return
*/
public boolean checkJreUsable() {
if (this.bootConfig.getJavaVersion().startsWith("1.8")) {
if (this.bootConfig.getJavaVersion().startsWith("17")) {
System.out.println("当前Java版本: " + bootConfig.getJavaVersion());
return true;
}

View File

@ -18,9 +18,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
</properties>
<dependencies>

View File

@ -220,7 +220,9 @@ public class CoreSpringContextListener implements ApplicationListener<ContextRef
}
coreScheduleService.installAddonSchedule(addon);
coreAddonService.set(JSONUtil.toBean(info, Addon.class));
Addon model = JSONUtil.toBean(info, Addon.class);
model.setIcon("addon/" + model.getKey() + "/icon.png");
coreAddonService.set(model);
AddonInstallJavaTools.addAddonJson(addon);
}

View File

@ -1,32 +0,0 @@
package com.niu.core.common.config.executable.interceptor;
/**
* 后台权限配置
*/
public class AdminAuthConfig {
// 免登录验证
public static String[] notLoginUri = new String[]{
"system:captcha", // 验证码
"system:login", // 登录接口
"index:config" // 配置接口
};
// 免权限验证
public static String[] notAuthUri = new String[]{
"system:logout", // 退出登录
"system:menu:menus", // 系统菜单
"system:menu:route", // 菜单路由
"system:admin:upInfo", // 管理员更新
"system:admin:self", // 管理员信息
"system:role:all", // 所有角色
"system:post:all", // 所有岗位
"system:dept:list", // 所有部门
"system:menu:list", // 菜单列表
"setting:dict:type:all", // 所有字典类型
"setting:dict:data:all", // 所有字典数据
"article:cate:all", // 所有文章分类
"decorate:data:article", // 装修数据文章
};
}

View File

@ -70,7 +70,8 @@ public class PermissionAuthorizer {
init = true;
}
String bestMatchingPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
Authorizer authorizer = authorizerMap.get(bestMatchingPattern);
Authorizer authorizer = authorizerMap.get("["+ request.getMethod() +"]" + bestMatchingPattern);
if (authorizer != null) {
try{
Class controller=Class.forName(authorizer.getHandlerMethod().getBean().toString());
@ -114,7 +115,7 @@ public class PermissionAuthorizer {
authorizer.setSourcePath(supportUrl);
authorizer.setMethod(supportMethods.toString());
authorizer.setHandlerMethod(handlerMethod);
authorizerMap.put(supportUrl, authorizer);
authorizerMap.put(supportMethods.toString() + supportUrl, authorizer);
}
}

View File

@ -62,6 +62,8 @@ public class PageResult<E> {
public PageResult(long page, long limit, long total, List<E> list) {
this.currentPage = page;
this.perPage = limit;
this.total = total;
this.data = list;
}
/**
@ -69,8 +71,8 @@ public class PageResult<E> {
* @param limit
* @return
*/
public static PageResult build(long page, long limit) {
return new PageResult(page, limit);
public static <E> PageResult<E> build(long page, long limit) {
return new PageResult<>(page, limit);
}
/**
@ -163,6 +165,16 @@ public class PageResult<E> {
return pageList;
}
public static <E> PageResult<E> build(IPage<?> page, List<E> data) {
PageResult<E> pageList = null;
if (page != null) {
pageList = PageResult.build(page.getCurrent(), page.getSize());
pageList.setTotal(page.getTotal());
pageList.setData(data);
}
return pageList;
}
/**
* PageHelper分页转换
*

View File

@ -5,10 +5,7 @@ import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* 支付方提供
@ -65,7 +62,6 @@ public abstract class RSACoder {
* 签名验签算法
* @return
* @throws Exception
* @throws SecureUtilException
*/
public static String sign(byte[] rawData, String privateKey, String algorithm) throws Exception {
byte[] keyBytes = decryptBASE64(privateKey);
@ -187,9 +183,8 @@ public abstract class RSACoder {
* @return
*/
public static byte[] decryptBASE64(String src) {
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
try {
return decoder.decodeBuffer(src);
return Base64.getDecoder().decode(src);
} catch (Exception ex) {
return null;
}
@ -201,8 +196,7 @@ public abstract class RSACoder {
* @return
*/
public static String encryptBASE64(byte[] src) {
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
return encoder.encode(src);
return Base64.getEncoder().encodeToString(src);
}
/**

View File

@ -6,12 +6,14 @@ import com.niu.core.common.component.context.listener.AbstractListener;
import com.niu.core.enums.member.AccountTypeEnum;
import com.niu.core.event.member.MemberAccountEvent;
import com.niu.core.service.core.member.ICoreMemberLevelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@EventListen("core")
@Component
@Slf4j
public class MemberAccountListener extends AbstractListener {
public void handleEvent(MemberAccountEvent event) {

View File

@ -64,7 +64,9 @@ public class PosterDrawListener extends AbstractListener {
e.printStackTrace();
}
TextElement text = new TextElement(testStr, fontStyle, poster.getInt("fontSize"), poster.getInt("x"), poster.getInt("y"));
TextElement text = new TextElement(testStr, fontStyle, poster.getInt("fontSize"), poster.getInt("x", 0), poster.getInt("y"));
// 设置居中
if (poster.getStr("x", "").equals("center")) text.setCenter(true);
// 设置字体颜色
text.setColor(Color.decode(poster.getStr("fontColor")));
// 设置换行

View File

@ -5,22 +5,21 @@ import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.exception.CommonException;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.entity.diy.DiyPage;
import com.niu.core.enums.diy.ComponentEnum;
import com.niu.core.enums.diy.LinkEnum;
import com.niu.core.enums.diy.PagesEnum;
import com.niu.core.enums.diy.TemplateEnum;
import com.niu.core.service.admin.diy.IDiyConfigService;
import com.niu.core.mapper.diy.DiyPageMapper;
import com.niu.core.service.admin.diy.IDiyRouteService;
import com.niu.core.service.admin.diy.param.*;
import com.niu.core.service.admin.diy.IDiyService;
import com.niu.core.service.admin.diy.param.*;
import com.niu.core.service.admin.diy.vo.DiyPageInfoVo;
import com.niu.core.service.admin.diy.vo.DiyPageListVo;
import com.niu.core.common.domain.PageParam;
import com.niu.core.entity.diy.DiyPage;
import com.niu.core.mapper.diy.DiyPageMapper;
import com.niu.core.service.admin.diy.vo.DiyRouteListVo;
import com.niu.core.service.core.diy.ICoreDiyConfigService;
import com.niu.core.service.core.diy.param.StartUpPageConfigParam;
@ -42,7 +41,7 @@ import java.util.List;
*/
@Service
public class DiyServiceImpl implements IDiyService {
@Resource
DiyPageMapper diyPageMapper;
@ -58,13 +57,13 @@ public class DiyServiceImpl implements IDiyService {
/**
* 自定义页面分页列表
*
* @param pageParam 分页参数
* @param pageParam 分页参数
* @param searchParam 搜索参数
* @return PageResult<DiyPageListVo>
*/
@Override
public PageResult<DiyPageListVo> list(PageParam pageParam, DiyPageSearchParam searchParam) {
Integer page = pageParam.getPage();
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
QueryWrapper<DiyPage> queryWrapper = new QueryWrapper<>();
@ -77,12 +76,12 @@ public class DiyServiceImpl implements IDiyService {
IPage<DiyPage> iPage = diyPageMapper.selectPage(new Page<DiyPage>(page, limit), queryWrapper);
List<DiyPageListVo> list = new LinkedList<>();
for(DiyPage item : iPage.getRecords()) {
for (DiyPage item : iPage.getRecords()) {
DiyPageListVo vo = new DiyPageListVo();
BeanUtils.copyProperties(item, vo);
list.add(vo);
}
return PageResult.build(page,limit, iPage.getTotal()).setData(list);
return PageResult.build(page, limit, iPage.getTotal()).setData(list);
}
/**
@ -103,7 +102,7 @@ public class DiyServiceImpl implements IDiyService {
List<DiyPage> pages = diyPageMapper.selectList(queryWrapper);
List<DiyPageListVo> list = new LinkedList<>();
for(DiyPage item : pages) {
for (DiyPage item : pages) {
DiyPageListVo vo = new DiyPageListVo();
BeanUtils.copyProperties(item, vo);
list.add(vo);
@ -121,8 +120,8 @@ public class DiyServiceImpl implements IDiyService {
public DiyPageInfoVo info(Integer id) {
DiyPage model = diyPageMapper.selectOne(
new QueryWrapper<DiyPage>()
.eq("id", id)
.eq("site_id", RequestUtils.siteId()));
.eq("id", id)
.eq("site_id", RequestUtils.siteId()));
if (model == null) return null;
@ -171,8 +170,8 @@ public class DiyServiceImpl implements IDiyService {
public void edit(Integer id, DiyPageParam editParam) {
DiyPage model = diyPageMapper.selectOne(
new QueryWrapper<DiyPage>()
.eq("id", id)
.eq("site_id", RequestUtils.siteId()));
.eq("id", id)
.eq("site_id", RequestUtils.siteId()));
Assert.notNull(model, "数据不存在!");
@ -193,10 +192,11 @@ public class DiyServiceImpl implements IDiyService {
/**
* 设为使用
*
* @param id
*/
public void setUse(Integer id) {
DiyPage model = diyPageMapper.selectOne(new QueryWrapper<DiyPage>().eq("id", id).eq("site_id", RequestUtils.siteId()));
DiyPage model = diyPageMapper.selectOne(new QueryWrapper<DiyPage>().eq("id", id).eq("site_id", RequestUtils.siteId()));
Assert.notNull(model, "页面不存在!");
DiyPage update = new DiyPage();
@ -213,7 +213,7 @@ public class DiyServiceImpl implements IDiyService {
public JSONObject getLink() {
JSONObject linkEnum = LinkEnum.getLink();
for (String key: linkEnum.keySet()) {
for (String key : linkEnum.keySet()) {
if (key.equals("DIY_PAGE")) {
List<DiyPage> pageList = this.diyPageMapper.selectList(new QueryWrapper<DiyPage>()
.eq("site_id", RequestUtils.siteId())
@ -266,7 +266,7 @@ public class DiyServiceImpl implements IDiyService {
param.setName(info.getName());
}
} else {
for (String key: template.keySet()) {
for (String key : template.keySet()) {
if (ObjectUtil.defaultIfNull(template.getByPath(key + ".page", String.class), "").equals(startConfig.getPage())) {
info = this.infoByName(key);
if (info != null) {
@ -337,6 +337,7 @@ public class DiyServiceImpl implements IDiyService {
/**
* 获取默认页面数据
*
* @param type
* @param addon
* @return
@ -355,12 +356,13 @@ public class DiyServiceImpl implements IDiyService {
/**
* 获取页面模板
*
* @return
*/
public JSONObject getTemplate(TemplateParam param) {
JSONObject template = TemplateEnum.getTemplate(param);
for (String key: template.keySet()) {
for (String key : template.keySet()) {
JSONObject pages = ObjectUtil.defaultIfNull(PagesEnum.getPages(key, param.getMode()), new JSONObject());
template.putByPath(key + ".template", pages);
}
@ -370,6 +372,7 @@ public class DiyServiceImpl implements IDiyService {
/**
* 设置启动页
*
* @param value
*/
public void changeTemplate(StartUpPageConfigParam value) {
@ -383,7 +386,7 @@ public class DiyServiceImpl implements IDiyService {
*/
public JSONObject getDecoratePage(DiyPageSearchParam searchParam) {
TemplateParam templateParam = new TemplateParam();
String[] key = { searchParam.getType() };
String[] key = {searchParam.getType()};
templateParam.setKey(key);
JSONObject template = this.getTemplate(templateParam).getJSONObject(searchParam.getType());
if (template == null) throw new CommonException("模板不存在");
@ -448,28 +451,28 @@ public class DiyServiceImpl implements IDiyService {
* 获取自定义页面分页列表轮播搜索组件用
*/
public PageResult<DiyPageListVo> getPageByCarouselSearch(PageParam pageParam) {
Integer page = pageParam.getPage();
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
QueryWrapper<DiyPage> queryWrapper = new QueryWrapper<DiyPage>()
.eq("site_id", RequestUtils.siteId())
.eq("type", "DIY_PAGE")
.notIn("value", Arrays.asList("top_fixed", "right_fixed", "bottom_fixed", "left_fixed", "fixed"))
.or()
.eq("site_id", RequestUtils.siteId())
.ne("type", "DIY_PAGE")
.eq("is_default", 0)
.notIn("value", Arrays.asList("top_fixed", "right_fixed", "bottom_fixed", "left_fixed", "fixed"))
.orderByDesc("id");
.eq("site_id", RequestUtils.siteId())
.eq("type", "DIY_PAGE")
.notIn("value", Arrays.asList("top_fixed", "right_fixed", "bottom_fixed", "left_fixed", "fixed"))
.or()
.eq("site_id", RequestUtils.siteId())
.ne("type", "DIY_PAGE")
.eq("is_default", 0)
.notIn("value", Arrays.asList("top_fixed", "right_fixed", "bottom_fixed", "left_fixed", "fixed"))
.orderByDesc("id");
IPage<DiyPage> iPage = diyPageMapper.selectPage(new Page<DiyPage>(page, limit), queryWrapper);
List<DiyPageListVo> list = new LinkedList<>();
for(DiyPage item : iPage.getRecords()) {
for (DiyPage item : iPage.getRecords()) {
DiyPageListVo vo = new DiyPageListVo();
BeanUtils.copyProperties(item, vo);
list.add(vo);
}
return PageResult.build(page,limit, iPage.getTotal()).setData(list);
return PageResult.build(page, limit, iPage.getTotal()).setData(list);
}
/**
@ -481,7 +484,7 @@ public class DiyServiceImpl implements IDiyService {
String addonFlag = param.getKey();
TemplateParam templateParam = new TemplateParam();
String[] key = { param.getKey() };
String[] key = {param.getKey()};
templateParam.setKey(key);
JSONObject template = getTemplate(templateParam).getJSONObject(param.getKey());
if (template == null) return;

View File

@ -35,6 +35,7 @@ public class DiyPageListVo implements Serializable {
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long updateTime; // 更新时间
private String typeName;
private String addonName;
public String getTypeName() {
JSONObject template = TemplateEnum.getTemplate();

View File

@ -5,24 +5,25 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.common.utils.mapper.QueryMapperUtils;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.entity.member.Member;
import com.niu.core.entity.member.MemberAccountLog;
import com.niu.core.enums.member.AccountTypeEnum;
import com.niu.core.mapper.member.MemberAccountLogMapper;
import com.niu.core.mapper.member.MemberMapper;
import com.niu.core.service.admin.member.IMemberAccountService;
import com.niu.core.service.admin.member.param.AdjustAccountParam;
import com.niu.core.service.admin.member.param.MemberAccountLogSearchParam;
import com.niu.core.service.admin.member.IMemberAccountService;
import com.niu.core.service.admin.member.vo.*;
import com.niu.core.service.core.member.ICoreMemberAccountService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.LinkedList;
@ -34,7 +35,7 @@ import java.util.List;
*/
@Service
public class MemberAccountServiceImpl implements IMemberAccountService {
@Resource
MemberAccountLogMapper memberAccountLogMapper;
@ -46,7 +47,8 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 会员账单列表
* @param pageParam 分页参数
*
* @param pageParam 分页参数
* @param searchParam 搜索参数
* @return PageResult<MemberAccountLogListVo>
*/
@ -54,7 +56,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
public PageResult<MemberAccountLogListVo> list(PageParam pageParam, MemberAccountLogSearchParam searchParam) {
Integer siteId = RequestUtils.siteId();
Integer page = pageParam.getPage();
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
MPJQueryWrapper<MemberAccountLog> queryWrapper = new MPJQueryWrapper<>();
@ -64,10 +66,14 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
queryWrapper.eq("mal.account_type", searchParam.getAccountType());
queryWrapper.orderByDesc("mal.id");
if (ObjectUtil.isNotEmpty(searchParam.getKeywords())) queryWrapper.like("m.member_no|m.username|m.nickname|m.mobile", searchParam.getKeywords());
if (ObjectUtil.defaultIfNull(searchParam.getMemberId(), 0) > 0) queryWrapper.eq("mal.member_id", searchParam.getMemberId());
if (ObjectUtil.isNotEmpty(searchParam.getFromType())) queryWrapper.eq("mal.from_type", searchParam.getFromType());
if (ObjectUtil.isNotEmpty(searchParam.getCreateTime())) QueryMapperUtils.buildByTime(queryWrapper, "mal.create_time", searchParam.getCreateTime());
if (ObjectUtil.isNotEmpty(searchParam.getKeywords()))
queryWrapper.like("m.member_no|m.username|m.nickname|m.mobile", searchParam.getKeywords());
if (ObjectUtil.defaultIfNull(searchParam.getMemberId(), 0) > 0)
queryWrapper.eq("mal.member_id", searchParam.getMemberId());
if (ObjectUtil.isNotEmpty(searchParam.getFromType()))
queryWrapper.eq("mal.from_type", searchParam.getFromType());
if (ObjectUtil.isNotEmpty(searchParam.getCreateTime()))
QueryMapperUtils.buildByTime(queryWrapper, "mal.create_time", searchParam.getCreateTime());
IPage<MemberAccountLogVo> iPage = memberAccountLogMapper.selectJoinPage(new Page<>(page, limit), MemberAccountLogVo.class, queryWrapper);
List<MemberAccountLogListVo> list = new LinkedList<>();
@ -86,6 +92,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 获取会员账户信息
*
* @param memberId
* @return
*/
@ -106,6 +113,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 查询佣金统计
*
* @param searchParam
* @return
*/
@ -115,7 +123,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
SumCommissionVo vo = new SumCommissionVo();
BigDecimal zero = (new BigDecimal(0));
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0){
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0) {
MemberAccountVo memberAccountInfo = this.getMemberAccountInfo(searchParam.getMemberId());
vo.setCommission(memberAccountInfo.getCommission());
vo.setCommissionCashOuting(memberAccountInfo.getCommissionCashOuting());
@ -147,6 +155,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 查询余额统计
*
* @param searchParam
* @return
*/
@ -155,15 +164,15 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
Integer siteId = RequestUtils.siteId();
SumBalanceVo vo = new SumBalanceVo();
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0){
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0) {
MemberAccountVo memberAccountInfo = this.getMemberAccountInfo(searchParam.getMemberId());
vo.setBalance(memberAccountInfo == null ? new BigDecimal(0) : memberAccountInfo.getBalance());
vo.setMoney(memberAccountInfo == null ? new BigDecimal(0) : memberAccountInfo.getMoney());
} else {
Member member = memberMapper.selectOne(new QueryWrapper<Member>()
.select("SUM(balance) AS balance,SUM(money) AS money")
.eq("site_id", siteId));
.select("SUM(balance) AS balance,SUM(money) AS money")
.eq("site_id", siteId));
vo.setBalance(member == null ? new BigDecimal(0) : member.getBalance());
vo.setMoney(member == null ? new BigDecimal(0) : member.getMoney());
@ -174,6 +183,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 查询积分统计
*
* @param searchParam
* @return
*/
@ -182,7 +192,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
Integer siteId = RequestUtils.siteId();
SumPointVo vo = new SumPointVo();
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0){
if (ObjectUtil.isNotEmpty(searchParam.getMemberId()) && searchParam.getMemberId() > 0) {
MemberAccountVo memberAccountInfo = this.getMemberAccountInfo(searchParam.getMemberId());
MemberAccountLog memberAccountLog = memberAccountLogMapper.selectOne(new QueryWrapper<MemberAccountLog>()
.select("SUM(account_data) AS account_sum")
@ -211,6 +221,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 调整积分
*
* @param param
*/
public void adjustPoint(AdjustAccountParam param) {
@ -219,6 +230,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
/**
* 调整余额
*
* @param param
*/
public void adjustBalance(AdjustAccountParam param) {

View File

@ -10,27 +10,36 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.query.MPJQueryWrapper;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.common.utils.mapper.QueryMapperUtils;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.entity.member.Member;
import com.niu.core.entity.member.MemberLabel;
import com.niu.core.enums.member.MemberRegisterChannelEnum;
import com.niu.core.enums.member.MemberRegisterTypeEnum;
import com.niu.core.mapper.member.MemberLabelMapper;
import com.niu.core.mapper.member.MemberMapper;
import com.niu.core.service.admin.member.param.*;
import com.niu.core.service.admin.member.IMemberService;
import com.niu.core.service.admin.member.vo.*;
import com.niu.core.service.admin.member.param.MemberAddParam;
import com.niu.core.service.admin.member.param.MemberModifyParam;
import com.niu.core.service.admin.member.param.MemberParam;
import com.niu.core.service.admin.member.param.MemberSearchParam;
import com.niu.core.service.admin.member.vo.MemberAllListVo;
import com.niu.core.service.admin.member.vo.MemberInfoVo;
import com.niu.core.service.admin.member.vo.MemberLabelAllListVo;
import com.niu.core.service.admin.member.vo.MemberListVo;
import com.niu.core.service.core.member.ICoreMemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* 会员实现
@ -68,13 +77,13 @@ public class MemberServiceImpl implements IMemberService {
// 查询条件
if (ObjectUtil.isNotEmpty(searchParam.getKeyword())) {
queryWrapper.like("member_no", searchParam.getKeyword()).or()
queryWrapper.and(i -> i.like("member_no", searchParam.getKeyword()).or()
.like("username", searchParam.getKeyword()).or()
.like("nickname", searchParam.getKeyword()).or()
.like("mobile", searchParam.getKeyword());
.like("mobile", searchParam.getKeyword()));
}
if(ObjectUtil.isNotNull(searchParam.getIsDel()) && ObjectUtil.isNotEmpty(searchParam.getKeyword())){
if (ObjectUtil.isNotNull(searchParam.getIsDel()) && ObjectUtil.isNotEmpty(searchParam.getKeyword())) {
queryWrapper.eq("is_del", searchParam.getIsDel());
}
if (ObjectUtil.isNotEmpty(searchParam.getMemberLevel())) {
@ -83,6 +92,9 @@ public class MemberServiceImpl implements IMemberService {
if (ObjectUtil.isNotEmpty(searchParam.getRegisterChannel())) {
queryWrapper.eq("register_channel", searchParam.getRegisterChannel());
}
if (ObjectUtil.isNotEmpty(searchParam.getMemberLabel())) {
queryWrapper.like("member_label", searchParam.getMemberLabel());
}
if (ObjectUtil.isNotEmpty(searchParam.getRegisterType())) {
queryWrapper.eq("register_type", searchParam.getRegisterType());
}
@ -90,12 +102,13 @@ public class MemberServiceImpl implements IMemberService {
QueryMapperUtils.buildByTime(queryWrapper, "m.create_time", searchParam.getCreateTime());
}
List<Member> memberList=new ArrayList<>();
if(page>0 && limit>0){
IPage<Member> iPage = memberMapper.selectPage(new Page<>(page, limit), queryWrapper);
memberList=iPage.getRecords();
}else {
memberList=memberMapper.selectList(queryWrapper);
IPage<Member> iPage = null;
List<Member> memberList = new ArrayList<>();
if (page > 0 && limit > 0) {
iPage = memberMapper.selectPage(new Page<>(page, limit), queryWrapper);
memberList = iPage.getRecords();
} else {
memberList = memberMapper.selectList(queryWrapper);
}
List<MemberListVo> list = new LinkedList<>();
for (Member item : memberList) {
@ -116,7 +129,7 @@ public class MemberServiceImpl implements IMemberService {
}
list.add(vo);
}
return PageResult.build(page, limit,list.size()).setData(list);
return PageResult.build(page, limit, iPage == null ? list.size() : iPage.getTotal()).setData(list);
}
/**
@ -186,10 +199,10 @@ public class MemberServiceImpl implements IMemberService {
addParam.setMemberNo(iCoreMemberService.createMemberNo(siteId));
} else {
Member memberNoIsExist = memberMapper.selectOne(new QueryWrapper<Member>()
.select("member_id")
.eq("site_id", siteId)
.eq("member_no", addParam.getMemberNo())
.last("limit 1"));
.select("member_id")
.eq("site_id", siteId)
.eq("member_no", addParam.getMemberNo())
.last("limit 1"));
Assert.isNull(memberNoIsExist, "会员编码已存在");
}

View File

@ -42,4 +42,12 @@ public class SiteAccountLogListVo implements Serializable {
}
return "";
}
public String getMoney() {
if (this.money.compareTo(BigDecimal.ZERO) == 1) {
return "+" + this.money.toString();
} else {
return this.money.toString();
}
}
}

View File

@ -1,6 +1,5 @@
package com.niu.core.service.admin.stat.impl;
import cn.hutool.core.io.unit.DataUnit;
import com.niu.core.common.utils.date.DateUtils;
import com.niu.core.entity.site.SiteGroup;
import com.niu.core.enums.common.SexEnum;
@ -19,9 +18,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class StatServiceImpl implements IStatService {
@ -36,6 +33,7 @@ public class StatServiceImpl implements IStatService {
ISiteGroupService siteGroupService;
@Resource
ICoreAddonService coreAddonService;
/**
* 首页统计数据
*
@ -43,44 +41,44 @@ public class StatServiceImpl implements IStatService {
*/
@Override
public StatInfoVo getIndexData() {
StatInfoVo statInfoVo=new StatInfoVo();
String[] createTimes=new String[2];
createTimes[0]=DateUtils.currInitDate();
createTimes[1]=DateUtils.currDate();
StatInfoVo statInfoVo = new StatInfoVo();
String[] createTimes = new String[2];
createTimes[0] = DateUtils.currInitDate();
createTimes[1] = DateUtils.currDate();
/**
* 会员统计类
*/
StatToDayVo statToDayVo=new StatToDayVo();
StatToDayVo statToDayVo = new StatToDayVo();
//总会员数
Integer totalMemberCount=coreMemberService.getMemberCount(new MemberStatSearchParam());
Integer totalMemberCount = coreMemberService.getMemberCount(new MemberStatSearchParam());
statToDayVo.setTotalMemberCount(totalMemberCount);
//今天注册总会员数
MemberStatSearchParam todayMemberParam=new MemberStatSearchParam();
MemberStatSearchParam todayMemberParam = new MemberStatSearchParam();
todayMemberParam.setCreateTime(createTimes);
statToDayVo.setTodayMemberCount(coreMemberService.getMemberCount(todayMemberParam));
//总站点数
statToDayVo.setTotalSiteCount(siteService.getSiteCountByCondition(new SiteSearchParam()));
//今日站点数
SiteSearchParam todaySiteParam=new SiteSearchParam();
SiteSearchParam todaySiteParam = new SiteSearchParam();
todaySiteParam.setCreateTime(createTimes);
todaySiteParam.setAppType(AppTypeEnum.SITE.getName());
statToDayVo.setTodaySiteCount(siteService.getSiteCountByCondition(todaySiteParam));
//正常站点数
SiteSearchParam normaSiteParam=new SiteSearchParam();
SiteSearchParam normaSiteParam = new SiteSearchParam();
normaSiteParam.setStatus(1);
normaSiteParam.setAppType(AppTypeEnum.SITE.getName());
statToDayVo.setNormaSiteCount(siteService.getSiteCountByCondition(normaSiteParam));
//到期站点数
SiteSearchParam expireSiteParam=new SiteSearchParam();
SiteSearchParam expireSiteParam = new SiteSearchParam();
expireSiteParam.setStatus(2);
expireSiteParam.setAppType(AppTypeEnum.SITE.getName());
statToDayVo.setExpireSiteCount(siteService.getSiteCountByCondition(expireSiteParam));
//即将到期站点数
SiteSearchParam weekExpireSiteParam=new SiteSearchParam();
String[] expireTimes=new String[2];
expireTimes[0]=DateUtils.currDate();
expireTimes[1]=DateUtils.getDateAddDay(7);
SiteSearchParam weekExpireSiteParam = new SiteSearchParam();
String[] expireTimes = new String[2];
expireTimes[0] = DateUtils.currDate();
expireTimes[1] = DateUtils.getDateAddDay(7);
weekExpireSiteParam.setStatus(1);
weekExpireSiteParam.setExpireTime(expireTimes);
weekExpireSiteParam.setAppType(AppTypeEnum.SITE.getName());
@ -89,8 +87,8 @@ public class StatServiceImpl implements IStatService {
/**
* 系统数据类
*/
StatSystemVo statSystemVo=new StatSystemVo();
statSystemVo=systemService.getSystemInfo();
StatSystemVo statSystemVo = new StatSystemVo();
statSystemVo = systemService.getSystemInfo();
statInfoVo.setTodayData(statToDayVo);
statInfoVo.setSystem(statSystemVo);
@ -98,25 +96,25 @@ public class StatServiceImpl implements IStatService {
/**
* 站点会员数据统计数据
*/
StatDateVo memberCountVo=new StatDateVo();
StatDateVo siteCountVo=new StatDateVo();
List<String> dates=new ArrayList<>();
List<Integer> memberValues=new ArrayList<>();
List<Integer> siteValues=new ArrayList<>();
Integer statNum=7;
for(Integer i=0; i<=statNum; i++){
StatDateVo memberCountVo = new StatDateVo();
StatDateVo siteCountVo = new StatDateVo();
List<String> dates = new ArrayList<>();
List<Integer> memberValues = new ArrayList<>();
List<Integer> siteValues = new ArrayList<>();
Integer statNum = 7;
for (Integer i = 0; i <= statNum; i++) {
String itemDay= DateUtils.getDateAddDay(i-statNum);
String[] startEndDate=DateUtils.getStartEndByDay(itemDay);
String itemDay = DateUtils.getDateAddDay(i - statNum);
String[] startEndDate = DateUtils.getStartEndByDay(itemDay);
MemberStatSearchParam itemMemberParam=new MemberStatSearchParam();
MemberStatSearchParam itemMemberParam = new MemberStatSearchParam();
itemMemberParam.setCreateTime(startEndDate);
Integer itemMemberCount=coreMemberService.getMemberCount(itemMemberParam);
Integer itemMemberCount = coreMemberService.getMemberCount(itemMemberParam);
dates.add(startEndDate[0]);
memberValues.add(itemMemberCount);
SiteSearchParam itemSiteParam=new SiteSearchParam();
SiteSearchParam itemSiteParam = new SiteSearchParam();
itemSiteParam.setCreateTime(startEndDate);
Integer itemSiteCount=siteService.getSiteCountByCondition(itemSiteParam);
Integer itemSiteCount = siteService.getSiteCountByCondition(itemSiteParam);
siteValues.add(itemSiteCount);
}
memberCountVo.setDate(dates);
@ -130,21 +128,21 @@ public class StatServiceImpl implements IStatService {
/**
* 会员性别类型统计
*/
StatTypeVo memberStat=new StatTypeVo();
List<String> sexlist=new ArrayList<>();
StatTypeVo memberStat = new StatTypeVo();
List<String> sexlist = new ArrayList<>();
sexlist.add(SexEnum.MAN.getName());
sexlist.add(SexEnum.WOMAN.getName());
sexlist.add(SexEnum.UNKNOWN.getName());
List<Integer> sexCountList=new ArrayList<>();
MemberStatSearchParam sexMemberParam=new MemberStatSearchParam();
List<Integer> sexCountList = new ArrayList<>();
MemberStatSearchParam sexMemberParam = new MemberStatSearchParam();
sexMemberParam.setSex(SexEnum.MAN.getValue());
Integer manSexCount=coreMemberService.getMemberCount(sexMemberParam);
Integer manSexCount = coreMemberService.getMemberCount(sexMemberParam);
sexMemberParam.setSex(SexEnum.WOMAN.getValue());
Integer womanSexCount=coreMemberService.getMemberCount(sexMemberParam);
Integer womanSexCount = coreMemberService.getMemberCount(sexMemberParam);
sexCountList.add(manSexCount);
sexCountList.add(womanSexCount);
sexCountList.add(totalMemberCount-manSexCount-womanSexCount);
sexCountList.add(totalMemberCount - manSexCount - womanSexCount);
memberStat.setType(sexlist);
memberStat.setValue(sexCountList);
statInfoVo.setMemberStat(memberStat);
@ -152,14 +150,14 @@ public class StatServiceImpl implements IStatService {
/**
* 站点分组 统计
*/
StatTypeVo siteGroupStat=new StatTypeVo();
List<String> grouplist=new ArrayList<>();
List<Integer> groupCountList=new ArrayList<>();
StatTypeVo siteGroupStat = new StatTypeVo();
List<String> grouplist = new ArrayList<>();
List<Integer> groupCountList = new ArrayList<>();
List<SiteGroup> groupList=siteGroupService.getAll();
for (SiteGroup siteGroup: groupList) {
List<SiteGroup> groupList = siteGroupService.getAll();
for (SiteGroup siteGroup : groupList) {
grouplist.add(siteGroup.getGroupName());
SiteSearchParam siteGroupParam=new SiteSearchParam();
SiteSearchParam siteGroupParam = new SiteSearchParam();
siteGroupParam.setGroupId(siteGroup.getGroupId());
groupCountList.add(siteService.getSiteCountByCondition(siteGroupParam));
}
@ -169,12 +167,12 @@ public class StatServiceImpl implements IStatService {
/**
* 所有应用安装统计
*/
StatAppVo appVo=new StatAppVo();
Integer totalAddonCount=coreAddonService.getLocalAddonCount();
Integer installAddonCount=coreAddonService.getAddonCountByCondition(new CoreAddonSearchParam());
StatAppVo appVo = new StatAppVo();
Integer totalAddonCount = coreAddonService.getLocalAddonCount();
Integer installAddonCount = coreAddonService.getAddonCountByCondition(new CoreAddonSearchParam());
appVo.setAppCount(totalAddonCount);
appVo.setAppInstalledCount(installAddonCount);
appVo.setAppNoInstalledCount(totalAddonCount-installAddonCount);
appVo.setAppNoInstalledCount(Math.max(totalAddonCount - installAddonCount, 0));
statInfoVo.setApp(appVo);
return statInfoVo;
}

View File

@ -175,8 +175,7 @@ public class SysAttachmentServiceImpl implements ISysAttachmentService {
* @param addParam
*/
public void addCategory(SysAttachmentCategoryParam addParam) {
if (addParam.getType() == null) throw new CommonException("type参数缺失");
if (ObjectUtil.isNotEmpty(addParam.getType())) throw new CommonException("type参数不能为空");
if (ObjectUtil.isEmpty(addParam.getType())) throw new CommonException("type参数不能为空");
SysAttachmentCategory model = new SysAttachmentCategory();
model.setSiteId(RequestUtils.siteId());

View File

@ -258,6 +258,7 @@ public class SysUserServiceImpl implements ISysUserService {
@Override
public SysUserInfoVo getUserInfoByUserName(String userName) {
SysUser model=sysUserMapper.selectOne(new QueryWrapper<SysUser>().eq("username", userName).last("limit 1"));
Assert.notNull(model, "账号或密码错误");
SysUserInfoVo vo = new SysUserInfoVo();
BeanUtils.copyProperties(model, vo);
return vo;

View File

@ -67,7 +67,7 @@ public class MemberAccountServiceImpl implements IMemberAccountService {
if (StrUtil.isNotEmpty(param.getAccountDataLt())) {
queryWrapper.lt("account_data", param.getAccountDataLt());
}
queryWrapper.orderByDesc(Arrays.asList("create_time"));
queryWrapper.orderByDesc("create_time");
IPage<MemberAccountLog> iPage = this.memberAccountLogMapper.selectPage(new Page<>(page, limit), queryWrapper);
List<AccountPointFlowVo> dataList = new LinkedList<>();

View File

@ -11,22 +11,16 @@ import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.utils.CollectUtils;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.common.utils.StringUtils;
import com.niu.core.common.utils.date.DateUtils;
import com.niu.core.common.utils.json.JsonLoadUtils;
import com.niu.core.common.utils.json.JsonModuleLoader;
import com.niu.core.entity.member.MemberSign;
import com.niu.core.mapper.member.MemberSignMapper;
import com.niu.core.service.admin.member.vo.SignConfigVo;
import com.niu.core.service.api.member.IMemberSignService;
import com.niu.core.service.api.member.param.*;
import com.niu.core.service.api.member.vo.*;
import com.niu.core.service.api.member.IMemberSignService;
import com.niu.core.service.core.member.ICoreMemberService;
import com.niu.core.service.core.sys.ICoreConfigService;
import com.niu.core.service.core.sys.ICoreSysConfigService;
import com.niu.core.service.core.sys.vo.CoreSysConfigVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -124,6 +118,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
model.setCreateTime(System.currentTimeMillis() / 1000);
model.setDays(days);
model.setDayAward(config.getDayAward().toString());
model.setContinueAward("");
if (days.equals(1)) model.setStartTime(System.currentTimeMillis() / 1000);
memberSignMapper.insert(model);
@ -162,7 +157,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
coreMemberService.memberGiftGrant(param.siteId(), param.memberId(), continueAward, continueAwardVar);
model.setContinueAward(continueAward.toString());
vo.setInfo("连签"+ days.toString() + "天恭喜您获得以下奖励");
vo.setInfo("连签" + days.toString() + "天恭喜您获得以下奖励");
vo.setAwards(continueAward);
memberSignMapper.updateById(model);
@ -232,7 +227,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
}
if (!signConfig.getContinueAward().isEmpty()) {
JSONArray continueAward = new JSONArray();
for(int i = 0; i < signConfig.getContinueAward().size(); i++) {
for (int i = 0; i < signConfig.getContinueAward().size(); i++) {
JSONObject awardItem = new JSONObject();
JSONObject item = signConfig.getContinueAward().getJSONObject(i);
awardItem.set("continue_sign", item.get("continue_sign"));
@ -247,7 +242,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
List<String> content = new ArrayList<>();
String icon = "";
for (String key: award.keySet()) {
for (String key : award.keySet()) {
if (award.getJSONObject(key).get("content") != null) {
content.add(award.getByPath(key + ".content.text", String.class));
icon = award.getByPath(key + ".content.icon", String.class);
@ -256,7 +251,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
JSONObject gift = new JSONObject();
if (content.size() > 0) {
gift.set("text", String.join("+", content));
gift.set("icon", content.size() > 1 ? "static/resource/images/member/sign/pack01.png" : icon);
gift.set("icon", content.size() > 1 ? "static/resource/images/member/sign/pack01.png" : icon);
}
awardItem.set("gift", new JSONObject().set("total", gift));
@ -292,7 +287,7 @@ public class MemberSignServiceImpl implements IMemberSignService {
}
if (!signConfig.getContinueAward().isEmpty()) {
JSONArray continueAward = new JSONArray();
for(int i = 0; i < signConfig.getContinueAward().size(); i++) {
for (int i = 0; i < signConfig.getContinueAward().size(); i++) {
JSONObject item = signConfig.getContinueAward().getJSONObject(i);
JSONObject gift = JSONUtil.parseObj(signConfig.getContinueAward().getJSONObject(i).toString());
gift.remove("continue_sign");

View File

@ -234,23 +234,25 @@ public class SysVerifyServiceImpl implements ISysVerifyService {
IPage<Verify> iPage = this.verifyMapper.selectPage(new Page<>(page, limit), queryWrapper);
List<SysVerifyRecordsVo> dataList = CollectUtils.convert(iPage.getRecords(), SysVerifyRecordsVo.class);
// 以下代码块=====>用以填充SysVerifyRecordsVo类对象的nickname, mobile, headimg属性
// 根据集合ID主键索引查询到对象列表
QueryWrapper withQueryWrapper = new QueryWrapper();
withQueryWrapper.select("member_id, nickname, mobile, headimg");
List<Integer> memberIdList = CollectBuildUtils.getKeyValueList(dataList, "verifierMemberId");
withQueryWrapper.in("member_id", memberIdList);
List<Member> memberList = memberMapper.selectList(withQueryWrapper);
// 先将数据分组然后放入结果集
Map<Integer, Member> memberMap = ObjectGroupUtils.group(memberList, "memberId");
dataList.stream().forEach(bean -> {
Member member = memberMap.get(bean.getVerifierMemberId());
if (member != null) {
MemberBriefInfoVo membervo = new MemberBriefInfoVo();
BeanUtils.copyProperties(member, membervo);
bean.setMember(membervo);
}
});
if (dataList.size() > 0) {
// 以下代码块=====>用以填充SysVerifyRecordsVo类对象的nickname, mobile, headimg属性
// 根据集合ID主键索引查询到对象列表
QueryWrapper withQueryWrapper = new QueryWrapper();
withQueryWrapper.select("member_id, nickname, mobile, headimg");
List<Integer> memberIdList = CollectBuildUtils.getKeyValueList(dataList, "verifierMemberId");
withQueryWrapper.in("member_id", memberIdList);
List<Member> memberList = memberMapper.selectList(withQueryWrapper);
// 先将数据分组然后放入结果集
Map<Integer, Member> memberMap = ObjectGroupUtils.group(memberList, "memberId");
dataList.stream().forEach(bean -> {
Member member = memberMap.get(bean.getVerifierMemberId());
if (member != null) {
MemberBriefInfoVo membervo = new MemberBriefInfoVo();
BeanUtils.copyProperties(member, membervo);
bean.setMember(membervo);
}
});
}
return PageResult.build(page, limit, iPage.getTotal()).setData(dataList);
}

View File

@ -2,7 +2,6 @@ package com.niu.core.service.api.sys.impl;
import cn.hutool.json.JSONObject;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.enums.member.GrowthRuleEnum;
import com.niu.core.service.api.sys.ITaskService;
import com.niu.core.service.core.member.ICoreMemberConfigService;
import com.niu.core.service.core.member.ICoreMemberService;
@ -53,6 +52,6 @@ public class TaskServiceImpl implements ITaskService {
}
return filteredObject;
}
return null;
return new JSONObject();
}
}

View File

@ -65,6 +65,7 @@ public class CoreMemberAccountServiceImpl implements ICoreMemberAccountService {
BigDecimal originalGetData = new BigDecimal(new Double(memberWrapper.getPropertyValue(StringUtils.toCamelCase(accountType + "_get")).toString()));
updateMemberWrapper.setPropertyValue(StringUtils.toCamelCase(accountType + "_get"), originalGetData.add(accountData));
}
memberMapper.updateById(memberModel);
// 账户变更事件
MemberAccountEvent accountEvent = new MemberAccountEvent();
@ -76,7 +77,5 @@ public class CoreMemberAccountServiceImpl implements ICoreMemberAccountService {
accountEvent.setAccountNewData(accountNewData);
accountEvent.setMemberId(memberId);
EventAndSubscribeOfPublisher.publishAll(accountEvent);
memberMapper.updateById(memberModel);
}
}

View File

@ -9,6 +9,7 @@ import com.niu.core.mapper.member.MemberLevelMapper;
import com.niu.core.mapper.member.MemberMapper;
import com.niu.core.service.core.member.ICoreMemberLevelService;
import com.niu.core.service.core.member.ICoreMemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -18,6 +19,7 @@ import java.util.Map;
@Service
@Slf4j
public class CoreMemberLevelServiceImpl implements ICoreMemberLevelService {
@Resource
@ -36,36 +38,41 @@ public class CoreMemberLevelServiceImpl implements ICoreMemberLevelService {
* @param memberId
*/
public void checkLevelUpgrade(Integer siteId, Integer memberId) {
Member member = memberMapper.selectOne(new QueryWrapper<Member>().select("member_id,growth,member_level").eq("member_id", memberId).eq("site_id", siteId));
if (member == null) return;
try {
Member member = memberMapper.selectOne(new QueryWrapper<Member>().select("member_id,growth,member_level").eq("member_id", memberId).eq("site_id", siteId));
if (member == null) return;
// 查询达到的等级
QueryWrapper upgradeQuery = new QueryWrapper<MemberLevel>();
upgradeQuery.eq("site_id", siteId);
upgradeQuery.le("growth", member.getGrowth());
if (member.getMemberLevel() > 0) {
MemberLevel memberLevel = memberLevelMapper.selectOne(new QueryWrapper<MemberLevel>().select("growth").eq("level_id", member.getMemberLevel()));
if (memberLevel != null) {
upgradeQuery.gt("growth", memberLevel.getGrowth());
}
}
upgradeQuery.orderByAsc("growth");
List<MemberLevel> upgrade = memberLevelMapper.selectList(upgradeQuery);
if (upgrade != null) {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("from_type", "level_upgrade");
vars.put("memo", "会员升级奖励");
for (MemberLevel level : upgrade) {
if (ObjectUtil.isNotEmpty(level.getLevelGifts()) && JSONUtil.isJson(level.getLevelGifts())) {
coreMemberService.memberGiftGrant(siteId, memberId, JSONUtil.parseObj(level.getLevelGifts()), vars);
// 查询达到的等级
QueryWrapper upgradeQuery = new QueryWrapper<MemberLevel>();
upgradeQuery.eq("site_id", siteId);
upgradeQuery.le("growth", member.getGrowth());
if (member.getMemberLevel() > 0) {
MemberLevel memberLevel = memberLevelMapper.selectOne(new QueryWrapper<MemberLevel>().select("growth").eq("level_id", member.getMemberLevel()));
if (memberLevel != null) {
upgradeQuery.gt("growth", memberLevel.getGrowth());
}
}
upgradeQuery.orderByAsc("growth");
List<MemberLevel> upgrade = memberLevelMapper.selectList(upgradeQuery);
MemberLevel end = upgrade.get(upgrade.size() - 1);
member.setMemberLevel(end.getLevelId());
memberMapper.updateById(member);
if (upgrade != null) {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("from_type", "level_upgrade");
vars.put("memo", "会员升级奖励");
for (MemberLevel level : upgrade) {
if (ObjectUtil.isNotEmpty(level.getLevelGifts()) && JSONUtil.isJson(level.getLevelGifts())) {
coreMemberService.memberGiftGrant(siteId, memberId, JSONUtil.parseObj(level.getLevelGifts()), vars);
}
}
MemberLevel end = upgrade.get(upgrade.size() - 1);
member.setMemberLevel(end.getLevelId());
memberMapper.updateById(member);
}
} catch (Exception e) {
log.info("会员检测升级异常");
e.printStackTrace();
}
}

View File

@ -9,6 +9,7 @@ import com.niu.core.service.core.site.ICoreSiteAccountService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Service
public class CoreSiteAccountServiceImpl implements ICoreSiteAccountService {
@ -41,7 +42,7 @@ public class CoreSiteAccountServiceImpl implements ICoreSiteAccountService {
SiteAccountLog model = new SiteAccountLog();
model.setSiteId(refund.getSiteId());
model.setType("refund");
model.setMoney(refund.getMoney());
model.setMoney(refund.getMoney().multiply(new BigDecimal("-1")));
model.setTradeNo(refund.getRefundNo());
model.setCreateTime(System.currentTimeMillis() / 1000);
siteAccountLogMapper.insert(model);
@ -57,7 +58,7 @@ public class CoreSiteAccountServiceImpl implements ICoreSiteAccountService {
SiteAccountLog model = new SiteAccountLog();
model.setSiteId(transfer.getSiteId());
model.setType("transfer");
model.setMoney(transfer.getMoney());
model.setMoney(transfer.getMoney().multiply(new BigDecimal("-1")));
model.setTradeNo(transfer.getTransferNo());
model.setCreateTime(System.currentTimeMillis() / 1000);
siteAccountLogMapper.insert(model);

View File

@ -140,7 +140,7 @@ public class CoreConfigServiceImpl implements ICoreConfigService {
addModel.setValue(valueJson.toString());
addModel.setCreateTime(System.currentTimeMillis() / 1000);
sysConfigMapper.insert(addModel);
cached.tag(cacheTagName).clear();
} else {
cached.tag(cacheTagName).clear();
model.setUpdateTime(System.currentTimeMillis() / 1000);

View File

@ -76,7 +76,7 @@ public class CorePrinterServiceImpl implements ICorePrinterService {
List<SysPrinterPrintTicketResult> results = CallbackPublisher.publishReturnList(event)
.stream()
.map(result -> (SysPrinterPrintTicketResult) result)
.collect(Collectors.toList());
.toList();
SysPrinterPrintTicketVo vo = new SysPrinterPrintTicketVo();
Optional<SysPrinterPrintTicketResult> error = results.stream().filter(result -> result.getCode() != 0).findFirst();

View File

@ -18,9 +18,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
</properties>
<dependencies>
@ -29,6 +29,36 @@
<artifactId>niucloud-core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>shop</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>sms-email</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>recharge</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>cms</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>shop_fenxiao</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.niu</groupId>
<artifactId>shop_giftcard</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 开发时热启动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -71,27 +101,6 @@
</execution>
</executions>
</plugin>
<!--
<plugin>
<groupId>com.jsecode.springboot</groupId>
<artifactId>ecode-springboot-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<executable>true</executable>
<allInOne>false</allInOne>
<classifier>exec</classifier>
<mainClass>com.niu.app.WebAppApplication</mainClass>
<distDir>../../../webroot/jar/lib</distDir>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
@ -105,12 +114,6 @@
<tasks>
<copy overwrite="true" file="target/web-app-exec.jar"
tofile="../webroot/jar/web-app-exec.jar"/>
<!--
<copy overwrite="true" file="target/classes/application.yml"
tofile="../webroot/jar/application.yml"/>
<copy overwrite="true" file="target/classes/application-prod.yml"
tofile="../webroot/jar/application-prod.yml"/>
-->
</tasks>
</configuration>
</execution>

View File

@ -24,7 +24,7 @@ spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/***?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password:
password:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
@ -55,7 +55,7 @@ spring:
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
# password:
password:
# 连接超时时间
timeout: 10s
lettuce:

View File

@ -24,7 +24,7 @@ spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/***?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password:
password:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:

View File

@ -102,5 +102,5 @@ system:
api-site-id-name: site-id
channel-name: channel
admin-domain:
wap-domain: "http://localhost:5174"
wap-domain:
web-domain:

View File

@ -31,6 +31,19 @@
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<SizeBasedTriggeringPolicy size="2MB"/>
</RollingFile>
<RollingFile name="ErrorRollingFile" fileName="./logs/error.log" filePattern="./logs/error-%d{yyyy-MM-dd}.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<Filters>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<SizeBasedTriggeringPolicy size="2MB"/>
</RollingFile>
<!--
<File name="ErrorLog" fileName="logs/niucloud-web-app.error.log">
@ -46,6 +59,7 @@
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="ErrorRollingFile"/>
</root>
<logger name="java.sql" level="info" additivity="false">
<AppenderRef ref="AspectConsole"/>

View File

@ -19,12 +19,12 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
<!-- 集成框架 -->
<spring-boot.version>2.7.18</spring-boot.version>
<spring-boot-satoken.version>1.38.0</spring-boot-satoken.version>
<spring-boot-satoken.version>1.39.0</spring-boot-satoken.version>
<swagger.version>3.0.0</swagger.version>
<quartz.version>2.7.2</quartz.version>
<log4j2.version>3.1.5</log4j2.version>

View File

@ -1,6 +1,6 @@
NODE_ENV = 'development'
# api请求地址
# api请求地址
VITE_APP_BASE_URL = ''
# 图片服务器地址

View File

@ -185,7 +185,7 @@
fixedStyleBg.value = false;
if (props.scrollBool == 1) {
let str = diyComponent.value.fixedBgColor;
let str = diyComponent.value.fixedBgColor || "";
let arr = str.split(',');
let num = diyComponent.value.fixedBgColor ? parseInt(arr[arr.length-1]) : 0;
if(!diyComponent.value.fixedBgColor || num == 0 ){

View File

@ -146,7 +146,7 @@
}
}
if (item.growth > info.value.growth && !isSet) {
if (item.growth > info.value.growth && item.level_id != info.value.member_level && !isSet) {
afterCurrIndex.value = index;
isSet = true;
}
@ -164,7 +164,7 @@
}else{
//
info.value.member_level_name = list[0].level_name;
upgradeGrowth.value = list[0].growth;
upgradeGrowth.value = list[0].growth - info.value.growth;
afterCurrIndex.value = 0;
currIndex.value = 1;
}

View File

@ -0,0 +1,50 @@
import { redirect, img, getToken } from '@/utils/common';
export function useGoods(params: any = {}) {
const baseTagStyle = (data:any)=>{
let style = "";
if(data.color_json.text_color){
style += `color:${data.color_json.text_color};`;
}
if(data.color_json.border_color){
style += `border-color: ${data.color_json.border_color};`;
}
if(data.color_json.bg_color){
style += `background-color: ${data.color_json.bg_color};`;
}
return style;
}
// 价格类型
const priceType = (data:any) =>{
let type = "";
if(data.member_discount && getToken() && data.goodsSku.member_price != data.goodsSku.price) {
type = 'member_price' // 会员价
}
return type;
}
// 商品价格
const goodsPrice = (data:any) => {
let price = "0.00";
if (data.member_discount && getToken() && data.goodsSku.member_price != data.goodsSku.price) {
price = data.goodsSku.member_price ? data.goodsSku.member_price : data.goodsSku.price // 会员价
} else {
price = data.goodsSku ? data.goodsSku.price : data.price; //兼容商品推荐组件
}
return parseFloat(price);
}
// 错误图片展示
const errorImgFn = (data: any, type: any) =>{
data[type] = '';
}
return {
baseTagStyle: baseTagStyle,
goodsPrice: goodsPrice,
priceType: priceType,
error: errorImgFn
}
}

View File

@ -1,21 +1,2 @@
{
"shop_fenxiao.pages.index": "分销中心",
"shop_fenxiao.pages.zone": "分销专区",
"shop_fenxiao.pages.level": "分销商等级",
"shop_fenxiao.pages.child_fenxiao": "分销商",
"shop_fenxiao.pages.goods": "分销商品",
"shop_fenxiao.pages.team": "团队",
"shop_fenxiao.pages.ranking_list": "排行榜",
"shop_fenxiao.pages.agent_list": "渠道代理",
"shop_fenxiao.pages.bill": "账单",
"shop_fenxiao.pages.order": "分销订单",
"shop_fenxiao.pages.order_detail": "订单详情",
"shop_fenxiao.pages.apply": "分销商申请",
"shop_fenxiao.pages.task_rewards": "任务奖励",
"shop_fenxiao.pages.task_detail": "任务奖励详情",
"shop_fenxiao.pages.task_rewards_detail": "任务奖励明细",
"shop_fenxiao.pages.sale": "销售奖励",
"shop_fenxiao.pages.sale_detail": "销售奖励详情",
"shop_fenxiao.pages.sale_ranking": "销售排行榜",
"shop_fenxiao.pages.promote_code": "分销推广"
}

View File

@ -34,4 +34,4 @@
"pages.verify.detail": "核销详情",
"pages.verify.record": "核销记录",
"pages.webview.index": ""
}
}

View File

@ -1,316 +1,320 @@
{
"pages": [ // pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "app/pages/index/index",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.index.index%",
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
}
"pages": [
// pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "app/pages/index/index",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.index.index%",
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
{
"path": "app/pages/auth/agreement",
"style": {
"navigationBarTitleText": "%pages.auth.agreement%"
}
},
{
"path": "app/pages/auth/bind",
"style": {
"navigationBarTitleText": "%pages.auth.bind%"
}
},
{
"path": "app/pages/auth/login",
"style": {
"navigationBarTitleText": "%pages.auth.login%"
}
},
{
"path": "app/pages/auth/register",
"style": {
"navigationBarTitleText": "%pages.auth.register%"
}
},
{
"path": "app/pages/auth/resetpwd",
"style": {
"navigationBarTitleText": "%pages.auth.resetpwd%"
}
},
{
"path": "app/pages/index/diy",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.index.diy%",
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
}
},
{
"path": "app/pages/index/close",
"style": {
"navigationBarTitleText": "%pages.index.close%"
}
},
{
"path": "app/pages/index/nosite",
"style": {
"navigationBarTitleText": "%pages.index.nosite%"
}
},
{
"path": "app/pages/member/apply_cash_out",
"style": {
"navigationBarTitleText": "%pages.member.apply_cash_out%"
},
"needLogin": true
},
{
"path": "app/pages/member/commission",
"style": {
"navigationBarTitleText": "%pages.member.commission%"
},
"needLogin": true
},
{
"path": "app/pages/member/balance",
"style": {
"navigationBarTitleText": "%pages.member.balance%"
},
"needLogin": true
},
{
"path": "app/pages/member/level",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.member.level%"
},
"needLogin": true
},
{
"path": "app/pages/member/detailed_account",
"style": {
"navigationBarTitleText": "%pages.member.detailed_account%"
}
},
{
"path": "app/pages/member/cash_out",
"style": {
"navigationBarTitleText": "%pages.member.cash_out%"
}
},
{
"path": "app/pages/member/cash_out_detail",
"style": {
"navigationBarTitleText": "%pages.member.cash_out_detail%"
}
},
{
"path": "app/pages/member/index",
"style": {
"navigationBarTitleText": "%pages.member.index%",
// #ifndef H5
"navigationStyle": "custom",
// #endif
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
}
},
{
"path": "app/pages/member/personal",
"style": {
"navigationBarTitleText": "%pages.member.personal%"
},
"needLogin": true
},
{
"path": "app/pages/member/point",
"style": {
"navigationBarTitleText": "%pages.member.point%"
},
"needLogin": true
},
{
"path": "app/pages/member/point_detail",
"style": {
"navigationBarTitleText": "%pages.member.point_detail%"
},
"needLogin": true
},
{
"path": "app/pages/member/account",
"style": {
"navigationBarTitleText": "%pages.member.account%"
},
"needLogin": true
},
{
"path": "app/pages/member/account_edit",
"style": {
"navigationBarTitleText": "%pages.member.account_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/address",
"style": {
"navigationBarTitleText": "%pages.member.address%"
},
"needLogin": true
},
{
"path": "app/pages/member/address_edit",
"style": {
"navigationBarTitleText": "%pages.member.address_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/location_address_edit",
"style": {
"navigationBarTitleText": "%pages.member.address_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/sign_in",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.member.sign_in%"
},
"needLogin": true
},
{
"path": "app/pages/pay/browser",
"style": {
"navigationBarTitleText": "%pages.pay.browser%"
}
},
{
"path": "app/pages/pay/result",
"style": {
"navigationBarTitleText": "%pages.pay.result%"
}
},
{
"path": "app/pages/setting/index",
"style": {
"navigationBarTitleText": "%pages.setting.index%"
},
"needLogin": true
},
{
"path": "app/pages/webview/index",
"style": {
"navigationBarTitleText": "%pages.webview.index%"
}
},
{
"path": "app/pages/index/develop",
"style": {
"navigationBarTitleText": "%pages.index.develop%"
}
},
{
"path": "app/pages/verify/index",
"style": {
"navigationBarTitleText": "%pages.verify.index%"
},
"needLogin": true
},
{
"path": "app/pages/verify/verify",
"style": {
"navigationBarTitleText": "%pages.verify.verify%"
},
"needLogin": true
},
{
"path": "app/pages/verify/detail",
"style": {
"navigationBarTitleText": "%pages.verify.detail%"
},
"needLogin": true
},
{
"path": "app/pages/verify/record",
"style": {
"navigationBarTitleText": "%pages.verify.record%"
},
"needLogin": true
},
{
"path": "app/pages/weapp/order_shipping",
"style": {
"navigationBarTitleText": "%pages.weapp.order_shipping%"
}
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
],
"subPackages": [{
"root": "addon",
"pages": [
// {{ PAGE_BEGAIN }}
// {{ PAGE_END }}}
{
"path": "end"
}
]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#F8F8F8",
"backgroundColorTop": "#F8F8F8",
"backgroundColorBottom": "#F8F8F8"
}
},
"tabBar": {
"list": [{
"pagePath": "app/pages/index/index"
},
{
"pagePath": "app/pages/member/index"
}
]
{
"path": "app/pages/auth/agreement",
"style": {
"navigationBarTitleText": "%pages.auth.agreement%"
}
},
"uniIdRouter": {},
"easycom": {
"custom": {
"diy-group": "@/addon/components/diy/group/index.vue",
"fixed-group": "@/addon/components/fixed/group/index.vue",
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
{
"path": "app/pages/auth/bind",
"style": {
"navigationBarTitleText": "%pages.auth.bind%"
}
},
{
"path": "app/pages/auth/login",
"style": {
"navigationBarTitleText": "%pages.auth.login%"
}
},
{
"path": "app/pages/auth/register",
"style": {
"navigationBarTitleText": "%pages.auth.register%"
}
},
{
"path": "app/pages/auth/resetpwd",
"style": {
"navigationBarTitleText": "%pages.auth.resetpwd%"
}
},
{
"path": "app/pages/index/diy",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.index.diy%",
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
}
},
{
"path": "app/pages/index/close",
"style": {
"navigationBarTitleText": "%pages.index.close%"
}
},
{
"path": "app/pages/index/nosite",
"style": {
"navigationBarTitleText": "%pages.index.nosite%"
}
},
{
"path": "app/pages/member/apply_cash_out",
"style": {
"navigationBarTitleText": "%pages.member.apply_cash_out%"
},
"needLogin": true
},
{
"path": "app/pages/member/commission",
"style": {
"navigationBarTitleText": "%pages.member.commission%"
},
"needLogin": true
},
{
"path": "app/pages/member/balance",
"style": {
"navigationBarTitleText": "%pages.member.balance%"
},
"needLogin": true
},
{
"path": "app/pages/member/level",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.member.level%"
},
"needLogin": true
},
{
"path": "app/pages/member/detailed_account",
"style": {
"navigationBarTitleText": "%pages.member.detailed_account%"
}
},
{
"path": "app/pages/member/cash_out",
"style": {
"navigationBarTitleText": "%pages.member.cash_out%"
}
},
{
"path": "app/pages/member/cash_out_detail",
"style": {
"navigationBarTitleText": "%pages.member.cash_out_detail%"
}
},
{
"path": "app/pages/member/index",
"style": {
"navigationBarTitleText": "%pages.member.index%",
// #ifndef H5
"navigationStyle": "custom",
// #endif
"usingComponents": {
"diy-group": "../../../../addon/components/diy/group/index",
"fixed-group": "../../../../addon/components/fixed/group/index"
},
"componentPlaceholder": {
"diy-group": "view",
"fixed-group": "view"
}
}
},
{
"path": "app/pages/member/personal",
"style": {
"navigationBarTitleText": "%pages.member.personal%"
},
"needLogin": true
},
{
"path": "app/pages/member/point",
"style": {
"navigationBarTitleText": "%pages.member.point%"
},
"needLogin": true
},
{
"path": "app/pages/member/point_detail",
"style": {
"navigationBarTitleText": "%pages.member.point_detail%"
},
"needLogin": true
},
{
"path": "app/pages/member/account",
"style": {
"navigationBarTitleText": "%pages.member.account%"
},
"needLogin": true
},
{
"path": "app/pages/member/account_edit",
"style": {
"navigationBarTitleText": "%pages.member.account_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/address",
"style": {
"navigationBarTitleText": "%pages.member.address%"
},
"needLogin": true
},
{
"path": "app/pages/member/address_edit",
"style": {
"navigationBarTitleText": "%pages.member.address_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/location_address_edit",
"style": {
"navigationBarTitleText": "%pages.member.address_edit%"
},
"needLogin": true
},
{
"path": "app/pages/member/sign_in",
"style": {
// #ifndef H5
"navigationStyle": "custom",
// #endif
"navigationBarTitleText": "%pages.member.sign_in%"
},
"needLogin": true
},
{
"path": "app/pages/pay/browser",
"style": {
"navigationBarTitleText": "%pages.pay.browser%"
}
},
{
"path": "app/pages/pay/result",
"style": {
"navigationBarTitleText": "%pages.pay.result%"
}
},
{
"path": "app/pages/setting/index",
"style": {
"navigationBarTitleText": "%pages.setting.index%"
},
"needLogin": true
},
{
"path": "app/pages/webview/index",
"style": {
"navigationBarTitleText": "%pages.webview.index%"
}
},
{
"path": "app/pages/index/develop",
"style": {
"navigationBarTitleText": "%pages.index.develop%"
}
},
{
"path": "app/pages/verify/index",
"style": {
"navigationBarTitleText": "%pages.verify.index%"
},
"needLogin": true
},
{
"path": "app/pages/verify/verify",
"style": {
"navigationBarTitleText": "%pages.verify.verify%"
},
"needLogin": true
},
{
"path": "app/pages/verify/detail",
"style": {
"navigationBarTitleText": "%pages.verify.detail%"
},
"needLogin": true
},
{
"path": "app/pages/verify/record",
"style": {
"navigationBarTitleText": "%pages.verify.record%"
},
"needLogin": true
},
{
"path": "app/pages/weapp/order_shipping",
"style": {
"navigationBarTitleText": "%pages.weapp.order_shipping%"
}
}
],
"subPackages": [
{
"root": "addon",
"pages": [
// {{ PAGE_BEGAIN }}
// {{ PAGE_END }}}
{
"path": "end"
}
]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#F8F8F8",
"backgroundColorTop": "#F8F8F8",
"backgroundColorBottom": "#F8F8F8"
},
"tabBar": {
"list": [
{
"pagePath": "app/pages/index/index"
},
{
"pagePath": "app/pages/member/index"
}
]
},
"uniIdRouter": {},
"easycom": {
"custom": {
"diy-group": "@/addon/components/diy/group/index.vue",
"fixed-group": "@/addon/components/fixed/group/index.vue",
"^u-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
"diy-(\W.*)": "@/app/components/diy/$1/index.vue",
"fixed-(\W.*)": "@/app/components/fixed/$1/index.vue"
}
}
}

View File

@ -23,12 +23,13 @@ const useMemberStore = defineStore('member', {
setToken(token)
await this.getMemberInfo()
},
async getMemberInfo() {
async getMemberInfo(callback: any = null) {
if (!this.token) return
await getMemberInfo().then((res: any) => {
this.info = res.data
uni.setStorageSync('wap_member_info', this.info)
uni.setStorageSync('wap_member_id', res.data.member_id)
if (callback) callback();
}).catch(async() => {
await this.logout()
})

View File

@ -474,4 +474,42 @@ button[type='primary'],uni-button[type='primary']{
.mescroll-upwarp{
opacity: 0;
}
/******************** mescroll state **********************/
/******************** mescroll state **********************/
.base-tag {
display: flex;
justify-content: center;
align-items: center;
height: 34rpx;
font-size: 18rpx;
padding: 0 8rpx;
color: #333;
border-radius: 4rpx;
background-color: #fff;
margin-right: 8rpx;
box-sizing: border-box;
margin-top: 8rpx;
border: 2rpx solid transparent;
&.middle{
height: 40rpx;
padding: 0 12rpx;
border-radius: 8rpx;
font-size: 20rpx;
margin-right: 16rpx;
}
}
.img-tag {
display: block;
height: 34rpx;
width: auto;
border-radius: 4rpx;
margin-right: 14rpx;
box-sizing: border-box;
margin-top: 8rpx;
&.middle{
height: 38rpx;
border-radius: 8rpx;
margin-right: 16rpx;
}
}

View File

@ -27,6 +27,14 @@ export function addCoupon(params: Record<string, any>) {
return request.post(`shop/goods/coupon`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @returns
*/
export function getCouponStatusList() {
return request.get(`shop/goods/coupon/status`)
}
/**
*
* @param params
@ -35,7 +43,14 @@ export function addCoupon(params: Record<string, any>) {
export function getCouponList(params: Record<string, any>) {
return request.get(`shop/goods/coupon`, { params })
}
/**
*
* @param params
* @returns
*/
export function getCouponSelectList(params: Record<string, any>) {
return request.get(`shop/goods/coupon/select`, { params })
}
/**
*
* @param params
@ -286,4 +301,244 @@ export function deleteActiveExchange(id: number) {
*/
export function getActiveExchangeStatus() {
return request.get(`shop/active/exchange/status`)
}
}
/************ 新人专享 ****************/
/**
*
* @returns
*/
export function getActiveNewcomerConfig() {
return request.get(`shop/active/newcomer/config`);
}
/**
*
* @param params
* @returns
*/
export function editActiveNewcomerConfig(params: Record<string, any>) {
return request.put(`shop/active/newcomer/config`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
* -
* @param params
* @returns
*/
export function getNewcomerGoodsList(params: Record<string, any>) {
return request.get('shop/active/newcomer/goods/select', { params })
}
/**
* -
* @param params
* @returns
*/
export function getNewcomerSelectGoodsList(params: Record<string, any>) {
return request.get('shop/active/newcomer/goods/selectgoodssku', { params })
}
/************ 商品榜单 ****************/
/**
*
* @param params
* @returns
*/
export function setRankConfig(params: Record<string, any>) {
return request.post('shop/good/rank/config', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @returns
*/
export function getRankConfig() {
return request.get(`shop/good/rank/config`)
}
/**
*
* @param params
* @returns
*/
export function getRankPageList(params: Record<string, any>) {
return request.get(`shop/good/rank`, { params })
}
/**
*
* @returns
*/
export function optionData() {
return request.get(`shop/good/rank/dict`)
}
/**
*
* @param rank_id
* @returns
*/
export function getRankInfo(rank_id: number) {
return request.get(`shop/good/rank/${ rank_id }`);
}
/**
*
* @param params
* @returns
*/
export function addGoodRank(params: Record<string, any>) {
return request.post('shop/good/rank', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
*
* @param params
* @returns
*/
export function editGoodRank(params: Record<string, any>) {
return request.put(`shop/good/rank/${ params.id }`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
*
* @param params
* @returns
*/
export function editRankStatus(params: Record<string, any>) {
return request.put(`shop/goods/rank/status`, params, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
*
* @param id
* @returns
*/
export function deleteGoodRank(id: number) {
return request.delete(`shop/good/rank/${ id }`, { showSuccessMessage: true })
}
/**
*
* @param params
* @returns
*/
export function batchDelete(params: Record<string, any>) {
return request.put(`shop/good/rank/batchDelete`, params, { showSuccessMessage: true })
}
/**
*
* @param params
* @returns
*/
export function modifyGoodsRankSort(params: Record<string, any>) {
return request.put(`shop/good/rank/sort`, params, { showSuccessMessage: true })
}
/**
*
* @param params
* @returns
*/
export function getSelectRankPageList(params: Record<string, any>) {
return request.get(`shop/good/rank/select`, { params })
}
/************ 满减 ****************/
/**
*
* @param params
* @returns
*/
export function getManjianList(params: Record<string, any>) {
return request.get(`shop/manjian`, { params })
}
/**
*
* @returns
*/
export function getManjianStatusList() {
return request.get(`shop/manjian/status`)
}
/**
*
* @param params
* @returns
*/
export function addManjian(params: Record<string, any>) {
return request.post('shop/manjian', params)
}
/**
*
* @param params
* @returns
*/
export function editManjian(params: Record<string, any>) {
return request.put(`shop/manjian/${ params.id }`, params)
}
/**
*
* @param params
* @returns
*/
export function getManjianInfo(params: Record<string, any>) {
return request.get(`shop/manjian/init`, { params });
}
/**
*
* @param params
* @returns
*/
export function goodsCheck(params: Record<string, any>) {
return request.post('shop/manjian/goods/check', params)
}
/**
*
* @param params
* @returns
*/
export function getManjianMemberPageList(params: Record<string, any>) {
return request.get(`shop/manjian/member/${ params.id }`, { params })
}
/**
*
* @param manjian_id
* @returns
*/
export function closeManjian(manjian_id: number) {
return request.put(`shop/manjian/close/${ manjian_id }`, {}, {
showErrorMessage: true,
showSuccessMessage: true
})
}
/**
*
* @param manjian_id
* @returns
*/
export function deleteManjian(manjian_id: number) {
return request.delete(`shop/manjian/${ manjian_id }`, { showSuccessMessage: true })
}

View File

@ -0,0 +1,45 @@
{
"basicInfoTab":"基础设置",
"bannerList":"顶部广告图",
"activeStatus":"是否启用",
"validityType":"有效期",
"validityDay":"天数",
"validityDayPlaceholder":"请输入有效天数",
"validityDayTips":"有效天数不可小于等于0",
"validityDayTipsLeft":"达成门槛立即生效,",
"validityDayTipsRight":"天有效期",
"validityTime":"固定时间",
"validityTimePlaceholder":"请选择有效期截止时间",
"validityTimePlaceholderTwo":"请先选择参与门槛时间",
"validityTimePlaceholderThree":"有效期截止时间不可小于参与门槛时间",
"validityTimeTips":"达成门槛立即生效,有效期截止为",
"validityTimeTipsTwo":"修改有效期将同步更新所有未参与活动用户的结束时间",
"participationWay":"参与门槛",
"neverOrder":"从未下过单的会员",
"assignTimeOrder":"指定时间内未下过单的会员",
"assignTimeRegister":"指定时间内注册的会员",
"appointTimePlaceholder":"请选择指定时间",
"activityGoods":"活动商品",
"selectGoods":"选择商品",
"goodsSkuIdsPlaceholder":"请选择商品",
"limitNum":"限购数量",
"limitNumPlaceholder":"请输入限购数量",
"limitNumTips":"限购数量不可小于等于0",
"limitNumTipsThree":"限购数量不可超过已选商品数量",
"oldPrice":"原价",
"newcomerPrice":"新人价",
"newcomerPricePlaceholder":"请输入新人价",
"newcomerPriceTips":"[新人价]格式错误",
"newcomerPriceTipsOne":"新人价不可小于0",
"newcomerPriceTipsTwo":"新人价不可大于原价",
"batchOperation":"批量操作",
"batchEmptySelectedGoodsTips": "请选择要操作的商品",
"activeDesc":"规则说明",
"activeDescPlaceholder":"请输入规则说明",
"useDefaultActiveDesc": "使用默认说明",
"image":"图片上传",
"imagePlaceholder":"请上传图片",
"toLink":"跳转链接",
"toLinkPlaceholder":"请输入跳转链接",
"addConfigList":"添加广告图"
}

View File

@ -0,0 +1,57 @@
{
"orderNo":"订单编号",
"orderNoPlaceholder": "请输入订单编号",
"orderStatus": "订单状态",
"orderStatusPlaceholder": "请选择订单状态",
"orderFrom": "订单类型",
"orderFromPlaceholder": "请选择订单类型",
"payTime": "支付时间",
"orderGoods": "商品",
"goodsPriceNumber": "单价(元)/数量",
"goodsPriceNumberTips": "新人价商品购买数量为1时单价显示新人价购买数量大于1时单价显示原价或折扣价或会员价",
"orderMoney": "实付金额(元)",
"startDate": "开始时间",
"endDate": "结束时间",
"piece": "件",
"createTime": "创建时间",
"activeRefund": "主动退款",
"notes": "备注",
"offlinePayment": "线下支付",
"orderClose": "关闭订单",
"editPrice": "修改价格",
"editAddress": "修改地址",
"sendOutGoods": "发货",
"confirmTakeDelivery": "确认收货",
"all": "全部",
"toBeShipped": "待发货",
"shipped": "已发货",
"receivedGoods": "已收货",
"completed": "已完成",
"closed": "已关闭",
"refunding": "退款中",
"notesDetail": "备注信息",
"delivery": "订单发货",
"company": "物流公司",
"companyPlaceholder": "请选择物流公司",
"expressNumber": "物流单号",
"expressNumberPlaceholder": "请输入物流单号",
"orderGoodsIdsPlaceholder": "请选择订单项",
"virtualDelivery": "虚拟发货",
"goodsName": "商品名称",
"num": "商品数量",
"orderCloseTips": "关闭订单后该订单将无法支付,是否确认关闭?",
"orderFinishTips": "是否确认用户已经收货?",
"orderGoodsPlaceholder": "请选择要发货的商品",
"deliveryStatusName": "发货状态",
"fromType": "订单来源",
"payType": "支付类型",
"orderInfo": "订单信息",
"refundStatusName": "退款状态",
"outTradeNo": "交易流水号",
"exportOrderType": "导出订单类型",
"shopOrder": "订单数据表",
"shopOrderGoods": "订单商品表",
"point":"积分"
}

View File

@ -40,7 +40,7 @@
<el-form-item :label="t('customerName')">
<div>
<el-input v-model.trim="formData.customer_name" clearable class="input-width" maxlength="50" />
<el-input v-model.trim="formData.customer_name" clearable class="input-width" maxlength="20" />
<div class="flex items-center mt-[5px] text-[12px] text-[#999] leading-[20px]">
<span>{{ t('customerNameTips') }}</span>
<a class="ml-[3px] text-[var(--el-color-primary)]" target="_blank" href="https://www.yuque.com/kdnjishuzhichi/rg4owd">{{t('examine')}}</a>
@ -54,28 +54,28 @@
<el-form-item :label="t('customerPwd')">
<div>
<el-input v-model.trim="formData.customer_pwd" clearable class="input-width" maxlength="50" />
<el-input v-model.trim="formData.customer_pwd" clearable class="input-width" maxlength="20" />
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('customerPwdTips') }}</div>
</div>
</el-form-item>
<el-form-item :label="t('sendSite')">
<div>
<el-input v-model.trim="formData.send_site" clearable class="input-width" maxlength="50" />
<el-input v-model.trim="formData.send_site" clearable class="input-width" maxlength="20" />
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('sendSiteTips') }}</div>
</div>
</el-form-item>
<el-form-item :label="t('sendStaff')">
<div>
<el-input v-model.trim="formData.send_staff" clearable class="input-width" maxlength="50" />
<el-input v-model.trim="formData.send_staff" clearable class="input-width" maxlength="20" />
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('sendStaffTips') }}</div>
</div>
</el-form-item>
<el-form-item :label="t('monthCode')">
<div>
<el-input v-model.trim="formData.month_code" clearable class="input-width" maxlength="50" />
<el-input v-model.trim="formData.month_code" clearable class="input-width" maxlength="20" />
<div class="mt-[5px] text-[12px] text-[#999] leading-[20px]">{{ t('monthCodeTips') }}</div>
</div>
</el-form-item>

View File

@ -0,0 +1,293 @@
<template>
<!-- 内容 -->
<div class="content-wrap" v-show="diyStore.editTab == 'content'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('styleRecommend') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('selectStyle')" class="flex">
<span class="text-primary flex-1 cursor-pointer" @click="showTitleStyle">{{ diyStore.editComponent.style.title }}</span>
<el-icon>
<ArrowRight />
</el-icon>
</el-form-item>
</el-form>
<el-dialog v-model="showTitleDialog" :title="t('selectStyle')" width="460px">
<div class="flex flex-wrap">
<template v-for="(item,index) in styleList" :key="index">
<div :class="{ 'border-primary': selectStyle.value == item.value }" @click="changeTitleStyle(item)" class="flex items-center justify-center overflow-hidden w-[200px] h-[100px] mr-[12px] mb-[12px] cursor-pointer border bg-[#eee]">
<img :src="img(item.url)" />
</div>
</template>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showTitleDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="confirmTitleStyle">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('titleContent') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('image')">
<upload-image v-model="diyStore.editComponent.textImg" :limit="1"/>
</el-form-item>
<el-form-item :label="t('subTitle')" v-show="diyStore.editComponent && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<el-input v-model.trim="diyStore.editComponent.subTitle.text" :placeholder="t('subTitlePlaceholder')" clearable maxlength="8" show-word-limit />
</el-form-item>
<el-form-item :label="t('link')" v-show="diyStore.editComponent && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<diy-link v-model="diyStore.editComponent.subTitle.link"/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t("selectSource") }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('goodsSelectPopupSelectGoodsButton')">
<el-radio-group v-model="diyStore.editComponent.source" :title="t('goodsSelectPopupSelectGoodsButton')">
<el-radio label="all">{{ t('goodsSelectPopupAllGoods') }}</el-radio>
<el-radio label="custom">{{ t('manualSelectionSources') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="t('goodsNum')" v-if="diyStore.editComponent.source == 'all' || diyStore.editComponent.source == 'category'">
<el-slider class="goods-list-slider" show-input v-model="diyStore.editComponent.num" :min="1" max="20" size="small" />
</el-form-item>
<el-form-item :label="t('customGoods')" v-if="diyStore.editComponent.source == 'custom'">
<newcomer-goods-select-popup ref="goodsSelectPopupRef" v-model="diyStore.editComponent.goods_ids" :min="1" :max="99" mode="sku" />
</el-form-item>
</el-form>
</div>
</div>
<!-- 样式 -->
<div class="style-wrap" v-show="diyStore.editTab == 'style'">
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('goodsStyle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('topRounded')">
<el-slider v-model="diyStore.editComponent.topElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
</el-form-item>
<el-form-item :label="t('bottomRounded')">
<el-slider v-model="diyStore.editComponent.bottomElementRounded" show-input size="small" class="ml-[10px] diy-nav-slider" :max="50" />
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap" v-if="diyStore.editComponent && diyStore.editComponent.style && diyStore.editComponent.style.value == 'style-3'">
<h3 class="mb-[10px]">{{ t('subTitleStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('textColor')">
<el-color-picker v-model="diyStore.editComponent.subTitle.textColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('subTextBgColor')">
<el-color-picker v-model="diyStore.editComponent.subTitle.startColor" show-alpha :predefine="diyStore.predefineColors"/>
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]"/>
<el-color-picker v-model="diyStore.editComponent.subTitle.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('countDownStyle') }}</h3>
<el-form label-width="90px" class="px-[10px]">
<el-form-item :label="t('newcomerNumberColor')">
<el-color-picker v-model="diyStore.editComponent.countDown.numberColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('newcomerNumberBg')">
<el-color-picker v-model="diyStore.editComponent.countDown.numberBg.startColor" show-alpha :predefine="diyStore.predefineColors"/>
<icon name="iconfont iconmap-connect" size="20px" class="block !text-gray-400 mx-[5px]"/>
<el-color-picker v-model="diyStore.editComponent.countDown.numberBg.endColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
<el-form-item :label="t('newcomerOtherColor')">
<el-color-picker v-model="diyStore.editComponent.countDown.otherColor" show-alpha :predefine="diyStore.predefineColors"/>
</el-form-item>
</el-form>
</div>
<!-- 组件样式 -->
<slot name="style"></slot>
</div>
</template>
<script lang="ts" setup>
import { t } from '@/lang'
import { img } from '@/utils/common'
import useDiyStore from '@/stores/modules/diy'
import { ref, reactive } from 'vue'
import newcomerGoodsSelectPopup from '@/addon/shop/views/goods/components/newcomer-goods-select-popup.vue'
const diyStore:any = useDiyStore()
diyStore.editComponent.ignore = ['componentBgUrl'] //
//
diyStore.editComponent.verify = (index: number) => {
const res = { code: true, message: '' }
if(diyStore.value[index].source == 'custom'){
if(diyStore.value[index].goods_ids.length == 0){
res.code = false
res.message = t('goodsPlaceholder')
}
}
return res
}
//
const showTitleDialog = ref(false)
const showTitleStyle = () => {
selectStyle.title = diyStore.editComponent.style.title;
selectStyle.value = diyStore.editComponent.style.value;
showTitleDialog.value = true
}
const changeTitleStyle = (item:any) => {
selectStyle.title = item.title;
selectStyle.value = item.value;
}
const confirmTitleStyle = () => {
diyStore.editComponent.style.title = selectStyle.title;
diyStore.editComponent.style.value = selectStyle.value;
initStyle(diyStore.editComponent.style.value);
showTitleDialog.value = false
}
const styleList = reactive([
{
url : 'addon/shop/diy/newcomer/style_01.png',
title:'风格1',
value:'style-1'
},{
url : 'addon/shop/diy/newcomer/style_02.png',
title:'风格2',
value:'style-2'
},{
url : 'addon/shop/diy/newcomer/style_03.png',
title:'风格3',
value:'style-3'
},{
url : 'addon/shop/diy/newcomer/style_04.png',
title:'风格4',
value:'style-4'
}
])
const initStyle = (style: any) => {
if (style == 'style-1') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_01.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 0, 0, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "#ff6D1A";
diyStore.editComponent.componentEndBgColor = "rgba(255, 70, 56, 1)";
diyStore.editComponent.componentGradientAngle = "to right";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 10;
diyStore.editComponent.topElementRounded = 10;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-2') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_02.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 44, 54, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(102, 102, 102, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentEndBgColor = "";
diyStore.editComponent.componentGradientAngle = "to bottom";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 5;
diyStore.editComponent.topElementRounded = 5;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-3') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_03.png";
diyStore.editComponent.subTitle.text = "查看更多";
diyStore.editComponent.subTitle.textColor = "rgba(239, 0, 12, 1)";
diyStore.editComponent.subTitle.startColor = "rgba(255, 248, 217, 1)";
diyStore.editComponent.subTitle.endColor = "rgba(255, 254, 251, 1)";
diyStore.editComponent.subTitle.link.name = "";
diyStore.editComponent.countDown.numberColor = "rgba(239, 0, 12, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "rgba(255, 248, 217, 1)";
diyStore.editComponent.countDown.numberBg.endColor = "rgba(255, 253, 246, 1)";
diyStore.editComponent.countDown.otherColor = "rgba(255, 253, 246, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 12, 16, 1)";
diyStore.editComponent.componentEndBgColor = "rgba(255, 101, 18, 1)";
diyStore.editComponent.componentGradientAngle = "to right";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 0;
diyStore.editComponent.topElementRounded = 0;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
} else if (style == 'style-4') {
diyStore.editComponent.textImg = "addon/shop/diy/newcomer/style_title_02.png";
diyStore.editComponent.countDown.numberColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.countDown.numberBg.startColor = "";
diyStore.editComponent.countDown.numberBg.endColor = "";
diyStore.editComponent.countDown.otherColor = "rgba(255, 253, 253, 1)";
diyStore.editComponent.textColor = "#303133";
diyStore.editComponent.pageStartBgColor = "";
diyStore.editComponent.pageEndBgColor = "";
diyStore.editComponent.pageGradientAngle = "to bottom";
diyStore.editComponent.componentStartBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentEndBgColor = "rgba(255, 255, 255, 1)";
diyStore.editComponent.componentGradientAngle = "to bottom";
diyStore.editComponent.bottomRounded = 12;
diyStore.editComponent.topRounded = 12;
diyStore.editComponent.elementBgColor = "";
diyStore.editComponent.bottomElementRounded = 10;
diyStore.editComponent.topElementRounded = 10;
diyStore.editComponent.margin.top = 10;
diyStore.editComponent.margin.bottom = 0;
diyStore.editComponent.margin.both = 10;
}
}
const selectStyle = reactive({
title: diyStore.editComponent.style.title,
value: diyStore.editComponent.style.value
})
initStyle(diyStore.editComponent.style.value);
defineExpose({})
</script>
<style lang="scss" scoped></style>
<style lang="scss">
.goods-list-slider {
.el-slider__input {
width: 100px;
}
}
</style>

View File

@ -0,0 +1,703 @@
<template>
<div>
<div @click="show">
<slot>
<el-button>{{ t('goodsSelectPopupSelectGoodsButton') }}</el-button>
<div class="inline-block ml-[10px] text-[14px]" v-show="goodsIds.length">
<span>{{ t('goodsSelectPopupSelect') }}</span>
<span class="text-primary mx-[2px]">{{ goodsIds.length }}</span>
<span>{{ t('goodsSelectPopupPiece') }}</span>
</div>
</slot>
</div>
<el-dialog v-model="showDialog" :title="t('goodsSelectPopupSelectGoodsDialog')" width="1000px" :close-on-press-escape="false" :destroy-on-close="true" :close-on-click-modal="false">
<el-form :inline="true" :model="goodsTable.searchParam" ref="searchFormRef">
<el-form-item prop="select_type" class="form-item-wrap">
<el-select v-model="goodsTable.searchParam.select_type" @change="handleSelectTypeChange">
<el-option :label="t('goodsSelectPopupAllGoods')" value="all" />
<el-option :label="t('goodsSelectPopupSelectedGoods')" value="selected" />
</el-select>
</el-form-item>
<el-form-item :label="t('goodsSelectPopupGoodsName')" prop="keyword" class="form-item-wrap">
<el-input v-model.trim="goodsTable.searchParam.keyword" :placeholder="t('goodsSelectPopupGoodsNamePlaceholder')" maxlength="60" />
</el-form-item>
<el-form-item :label="t('goodsSelectPopupGoodsCategory')" prop="goods_category" class="form-item-wrap">
<el-cascader v-model="goodsTable.searchParam.goods_category"
:options="goodsCategoryOptions" :placeholder="t('goodsSelectPopupGoodsCategoryPlaceholder')"
clearable :props="{ value: 'value', label: 'label', emitPath:false }" />
</el-form-item>
<el-form-item :label="t('goodsSelectPopupGoodsType')" prop="goods_type" class="form-item-wrap">
<el-select v-model="goodsTable.searchParam.goods_type" :placeholder="t('goodsSelectPopupGoodsTypePlaceholder')" clearable>
<el-option v-for="item in goodsType" :key="item.type" :label="item.name" :value="item.type" />
</el-select>
</el-form-item>
<el-form-item class="form-item-wrap">
<el-button type="primary" @click="loadGoodsList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
<div class="table w-[100%]" v-loading="goodsTable.loading">
<div class="table-head flex items-center bg-[#f5f7f9] py-[8px]">
<div class="w-[3%]"></div>
<div class="w-[7%]">
<el-checkbox v-model="staircheckAll" :indeterminate="isStairIndeterminate" @change="handleCheckAllChange" />
</div>
<div class="w-[50%]">商品信息</div>
<div class="w-[20%]">商品价格</div>
<div class="w-[20%]">库存</div>
</div>
<div class="table-body h-[350px] overflow-y-auto">
<div v-for="(row,rowIndex) in goodsTable.data" :key="rowIndex" class="flex flex-col">
<!-- 内容 -->
<div class="flex items-center border-solid border-[#e5e7eb] py-[8px] border-b-[1px]">
<div v-if="prop.mode == 'spu'" class="w-[3%]"></div>
<div v-if="prop.mode == 'sku' && row.skuList.length > 1" class="w-[3%] cursor-pointer text-center !text-[10px]" @click="secondLevelArrowChange(row)" :class="{'iconfont iconxiangyoujiantou': row.skuList.length, 'arrow-show': row.isShow}"></div>
<div v-if="prop.mode == 'sku' && row.skuList.length <= 1" class="w-[3%]"></div>
<div class="w-[7%]">
<el-checkbox v-model="row.secondLevelCheckAll" :indeterminate="row.isSecondLevelIndeterminate" @change="secondLevelHandleCheckAllChange($event,row)" />
</div>
<div class="flex items-center cursor-pointer w-[50%]">
<div class="min-w-[60px] h-[60px] flex items-center justify-center">
<el-image v-if="row.goods_cover_thumb_small" class="w-[60px] h-[60px]" :src="img(row.goods_cover_thumb_small)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[60px] h-[60px]" src="@/addon/shop/assets/goods_default.png" />
</div>
</template>
</el-image>
<img v-else class="w-[60px] h-[60px]" src="@/addon/shop/assets/goods_default.png" fit="contain" />
</div>
<div class="ml-2">
<span :title="row.goods_name" class="multi-hidden leading-[1.4]">{{ row.goods_name }}</span>
<span class="text-primary text-[12px]">{{ row.goods_type_name }}</span>
</div>
</div>
<div class="w-[20%]">{{ row.skuList.length > 1 ? row.goodsSku.price : row.goodsSku.newcomer_price }}</div>
<div class="w-[20%]">{{row.stock}}</div>
</div>
<div v-show="prop.mode == 'sku' && row.skuList.length > 1">
<!-- 子级 -->
<div v-for="(item,index) in row.skuList" :key="index" class="flex items-center py-[8px] border-solid border-transparent border-b-[1px]" :class="{'hidden': !row.isShow, 'border-[#e5e7eb]': index == (row.skuList.length-1)}">
<div class="w-[6%]"></div>
<div class="w-[4%]">
<el-checkbox v-model="item.threeLevelCheckAll" @change="subChildHandleCheckAllChange($event,row,item)" />
</div>
<div class="flex items-center cursor-pointer w-[50%]">
<div class="min-w-[60px] h-[60px] flex items-center justify-center">
<el-image v-if="item.sku_image" class="w-[60px] h-[60px]" :src="img(item.sku_image)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[60px] h-[60px]" src="@/addon/shop/assets/goods_default.png" />
</div>
</template>
</el-image>
<img v-else class="w-[60px] h-[60px]" src="@/addon/shop/assets/goods_default.png" fit="contain" />
</div>
<div class="ml-2">
<span :title="item.sku_name || row.goods_name" class="multi-hidden leading-[1.4]">{{ item.sku_name || row.goods_name }}</span>
<span class="text-primary text-[12px]">{{ row.goods_type_name }}</span>
</div>
</div>
<div class="w-[20%] flex">{{ item.newcomer_price }}</div>
<div class="w-[20%] flex">{{ item.stock }}</div>
</div>
</div>
</div>
<div v-if="!goodsTable.data.length && !goodsTable.loading" class="h-[60px] flex items-center justify-center border-solid border-[#e5e7eb] py-[12px] border-b-[1px]">
暂无数据
</div>
</div>
</div>
<div class="mt-[16px] flex">
<div class="flex items-center flex-1">
<div class="layui-table-bottom-left-container mr-[10px]" v-show="selectGoodsNum">
<span>{{ t('goodsSelectPopupBeforeTip') }}</span>
<span class="text-primary mx-[2px]">{{ selectGoodsNum }}</span>
<span>{{ t('goodsSelectPopupAfterTip') }}</span>
</div>
<el-button type="primary" link @click="clear" v-show="selectGoodsNum">{{ t('goodsSelectPopupClearGoods') }}</el-button>
</div>
<el-pagination v-model:current-page="goodsTable.page" v-model:page-size="goodsTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="goodsTable.total"
@size-change="loadGoodsList()" @current-change="loadGoodsList" />
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="save">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { t } from '@/lang'
import { ref, reactive, computed, nextTick } from 'vue'
import { cloneDeep } from 'lodash-es'
import { img,deepClone } from '@/utils/common'
import { ElMessage } from 'element-plus'
import { getCategoryTree, getGoodsType } from '@/addon/shop/api/goods'
import { getNewcomerSelectGoodsList, getNewcomerGoodsList } from '@/addon/shop/api/marketing'
const prop = defineProps({
modelValue: {
type: String,
default: ''
},
max: {
type: Number,
default: 0
},
min: {
type: Number,
default: 0
},
mode: {
type: String,
default: 'spu' // spusku
},
way: {
type: String,
default: '' // single
},
})
const emit = defineEmits(['update:modelValue','goodsSelect'])
// prop.mode sku_goods_
let replacePrefix = prop.mode == "sku" ? 'sku_' : 'goods_';
const isStairIndeterminate = ref(false);
const staircheckAll = ref(false);
const goodsIds: any = computed({
get () {
return prop.modelValue
},
set (value) {
emit('update:modelValue', value)
}
})
const showDialog = ref(false)
//
const selectGoods: any = reactive({})
// id
const selectGoodsId: any = reactive([])
//
const selectGoodsNum: any = computed(() => {
return Object.keys(selectGoods).length
})
const goodsTable = reactive({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
keyword: '',
goods_category: [],
select_type: 'all',
goods_ids: '',
verify_goods_ids: '',
verify_sku_ids: '',
goods_type: ''
}
})
const searchFormRef = ref()
// /
const handleSelectTypeChange = (value: any) => {
loadGoodsList()
}
//
const goodsCategoryOptions: any = reactive([])
//
const goodsType: any = reactive([])
//
const initData = () => {
//
getCategoryTree().then((res) => {
const data = res.data
if (data) {
const goodsCategoryTree: any = []
data.forEach((item: any) => {
const children: any = []
if (item.child_list) {
item.child_list.forEach((childItem: any) => {
children.push({
value: childItem.category_id,
label: childItem.category_name
})
})
}
goodsCategoryTree.push({
value: item.category_id,
label: item.category_name,
children
})
})
goodsCategoryOptions.splice(0, goodsCategoryOptions.length, ...goodsCategoryTree)
}
})
//
getGoodsType().then((res) => {
const data = res.data
if (data) {
for (const k in data) {
goodsType.push(data[k])
}
}
})
}
initData()
const goodsListTableRef = ref()
//
const multipleSelection: any = ref([])
//
const secondLevelArrowChange = (data)=>{
data.isShow = !data.isShow;
}
//
const handleCheckAllChange = (isSelect) =>{
isStairIndeterminate.value = false;
goodsTable.data.forEach((item,index) => {
item.secondLevelCheckAll = isSelect;
item.skuList.forEach((subItem, subIndex) => {
subItem.threeLevelCheckAll = isSelect;
});
});
if (isSelect) {
goodsTable.data.forEach((item: any) => {
if(prop.mode == 'spu') {
selectGoods[replacePrefix + item.goods_id] = item
selectGoodsId.push(item.goods_id)
}else{
item.skuList.forEach((skuItem:any)=>{
selectGoodsId.push(skuItem.sku_id);
selectGoods[replacePrefix + skuItem.sku_id] = deepClone(skuItem);
selectGoods[replacePrefix + skuItem.sku_id].goods_name = item.goods_name; //
selectGoods[replacePrefix + skuItem.sku_id].goods_type_name = item.goods_type_name;
selectGoods[replacePrefix + skuItem.sku_id].goods_type = item.goods_type;
})
}
})
} else {
//
goodsTable.data.forEach((item: any) => {
if(prop.mode == 'spu') {
selectGoodsId.splice(selectGoodsId.indexOf(item.goods_id), 1)
delete selectGoods[replacePrefix + item.goods_id]
}else{
item.skuList.forEach((skuItem:any)=>{
selectGoodsId.splice(selectGoodsId.indexOf(skuItem.sku_id), 1)
delete selectGoods[replacePrefix + skuItem.sku_id]
})
}
})
}
}
//
const secondLevelHandleCheckAllChange = (isSelect,row)=>{
row.skuList.forEach((item,index) => {
item.threeLevelCheckAll = isSelect;
});
detectionAllSelect();
if(prop.mode == 'spu'){
if (isSelect) {
selectGoodsId.push(row.goods_id)
selectGoods[replacePrefix + row.goods_id] = deepClone(row)
} else {
selectGoodsId.splice(selectGoodsId.indexOf(row.goods_id),1)
//
delete selectGoods[replacePrefix + row.goods_id]
}
}else{
if (isSelect) {
row.skuList.forEach((item,index) => {
selectGoodsId.push(item.sku_id);
selectGoods[replacePrefix + item.sku_id] = deepClone(item);
selectGoods[replacePrefix + item.sku_id].goods_name = row.goods_name; //
selectGoods[replacePrefix + item.sku_id].goods_type_name = row.goods_type_name;
selectGoods[replacePrefix + item.sku_id].goods_type = row.goods_type;
});
} else {
row.skuList.forEach((item,index) => {
selectGoodsId.splice(selectGoodsId.indexOf(item.sku_id),1)
//
delete selectGoods[replacePrefix + item.sku_id]
});
}
}
// 使
// setTimeout(() => {
// goodsListTableRef.value.toggleRowExpansion(...Object.values(spreadTableData),true)
// }, 0);
// prop.maxprop.max
if(prop.max && prop.max > 0 && Object.keys(selectGoods).length > 0 && Object.keys(selectGoods).length > prop.max){
let len = Object.keys(selectGoods).length;
len = len - prop.max;
let goodsIdCopy = cloneDeep(selectGoodsId);
goodsIdCopy.forEach((item,index,arr) => {
if(index < len){
let indent = selectGoodsId.indexOf(item)
delete selectGoods[replacePrefix+selectGoodsId[indent]]
selectGoodsId.splice(indent,1)
}
});
setGoodsSelected();
}
}
//
const subChildHandleCheckAllChange = (selected: any,parentData: any,data: any)=>{
let selectNum = 0;
parentData.skuList.forEach((item,index) => {
if(item.threeLevelCheckAll){
selectNum++;
}
});
if(selectNum > 0 && selectNum != parentData.skuList.length){
parentData.secondLevelCheckAll = false;
parentData.isSecondLevelIndeterminate = true;
}else if(selectNum == parentData.skuList.length){
parentData.isSecondLevelIndeterminate = false;
parentData.secondLevelCheckAll = true
}else{
parentData.isSecondLevelIndeterminate = false;
parentData.secondLevelCheckAll = false;
}
detectionAllSelect();
let currSku = deepClone(data)
if(selected){
selectGoodsId.push(currSku.sku_id);
currSku.goods_name = parentData.goods_name; //
currSku.goods_type_name = parentData.goods_type_name;
currSku.goods_type = parentData.goods_type;
selectGoods[replacePrefix + currSku.sku_id] = currSku;
}else{
selectGoodsId.splice(selectGoodsId.indexOf(currSku.sku_id),1)
//
delete selectGoods[replacePrefix + currSku.sku_id]
}
}
//
const detectionAllSelect = ()=> {
let selectNum = 0;
goodsTable.data.forEach((item,index) => {
if(item.secondLevelCheckAll){
selectNum++;
}
});
if(selectNum > 0 && selectNum != goodsTable.data.length){
staircheckAll.value = false;
isStairIndeterminate.value = true;
}else if(selectNum > 0 && selectNum == goodsTable.data.length){
isStairIndeterminate.value = false;
staircheckAll.value = true
}else{
isStairIndeterminate.value = false;
staircheckAll.value = false;
}
}
/**
* 获取商品列表
*/
const loadGoodsList = (page: number = 1, callback: any = null) => {
isStairIndeterminate.value = false;
staircheckAll.value = false;
goodsTable.loading = true;
goodsTable.data = [];
goodsTable.page = page
const searchData = cloneDeep(goodsTable.searchParam);
if (searchData.select_type == 'selected') {
const goods_ids = <any>[]
for (let k in selectGoods) {
goods_ids.push(parseInt(k.replace(replacePrefix, '')))
}
searchData[replacePrefix+'ids'] = goods_ids
} else {
searchData[replacePrefix+'ids'] = '';
}
getNewcomerGoodsList({
page: goodsTable.page,
limit: goodsTable.limit,
...searchData
}).then(res => {
let goodsTableData = cloneDeep(res.data.data);
goodsTableData.forEach((item: any) => {
item.isShow = false;
item.isSecondLevelIndeterminate = false;
item.secondLevelCheckAll = false;
})
if(prop.mode == "sku") {
goodsTableData.forEach((item: any) => {
if (item.skuList.length) {
item.skuList.forEach((skuItem: any) => {
skuItem.threeLevelCheckAll = false;
skuItem.goods_type = item.goods_type;
})
}
})
}
if (callback) callback(prop.mode == "spu" ? res.data.verify_goods_ids : res.data.verify_sku_ids, res.data.select_goods_list)
setGoodsSelected();
goodsTable.data = goodsTableData
goodsTable.total = res.data.total
goodsTable.loading = false
}).catch(() => {
goodsTable.loading = false
})
}
// spu
const setGoodsSelected = () => {
nextTick(() => {
if(prop.mode == "spu"){
for (let i = 0; i < goodsTable.data.length; i++) {
goodsTable.data[i].secondLevelCheckAll = false;
if (selectGoods[replacePrefix + goodsTable.data[i].goods_id]) {
goodsTable.data[i].secondLevelCheckAll = true;
}
}
}else{
let isAllSelectSku = true;
for (let i = 0; i < goodsTable.data.length; i++) {
goodsTable.data[i].secondLevelCheckAll = false;
isAllSelectSku = true;
goodsTable.data[i].isSecondLevelIndeterminate = false;
goodsTable.data[i].skuList.forEach((item,index) => {
item.threeLevelCheckAll = false;
if (selectGoods[replacePrefix + item.sku_id]) {
goodsTable.data[i].isSecondLevelIndeterminate = true;
item.threeLevelCheckAll = true;
}else{
isAllSelectSku = false;
}
});
if(isAllSelectSku){
goodsTable.data[i].isSecondLevelIndeterminate = false;
goodsTable.data[i].secondLevelCheckAll = true;
}
}
}
detectionAllSelect();
});
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadGoodsList()
}
const show = () => {
for (let k in selectGoods) {
delete selectGoods[k];
}
replacePrefix = prop.mode == "sku" ? 'sku_' : 'goods_';
// idid
if (prop.mode == 'sku') {
goodsTable.searchParam.verify_sku_ids = goodsIds.value;
} else {
goodsTable.searchParam.verify_goods_ids = goodsIds.value;
}
getGoodsSkuNoPageListFn();
loadGoodsList(1, (verify_ids: any) => {
//
if (goodsIds.value && goodsIds.value.length) {
goodsIds.value.splice(0, goodsIds.value.length, ...verify_ids)
selectGoodsId.splice(0, selectGoodsId.length, ...verify_ids)
if(Object.keys(selectGoods).length){
for(let key in selectGoods){
let num = Number(key.split(replacePrefix)[1]);
if(goodsIds.value.indexOf(num) == -1){
delete selectGoods[key];
}
}
}
}
})
showDialog.value = true
}
const getGoodsSkuNoPageListFn = () =>{
const searchData = cloneDeep(goodsTable.searchParam);
getNewcomerSelectGoodsList({...searchData}).then((res:any)=>{
const selectGoodsData = res.data;
//
if (prop.mode == 'sku') {
for (let i = 0; i < selectGoodsData.length; i++) {
selectGoodsData[i].skuList.forEach((item: any) => {
if (goodsIds.value.indexOf(item.sku_id) != -1) {
item.goods_name = selectGoodsData[i].goods_name; //
item.goods_type_name = selectGoodsData[i].goods_type_name;
item.goods_type = selectGoodsData[i].goods_type;
selectGoods[replacePrefix + item.sku_id] = item;
}
});
}
} else {
for (let i = 0; i < selectGoodsData.length; i++) {
if (goodsIds.value.indexOf(selectGoodsData[i].goods_id) != -1) {
selectGoods[replacePrefix + selectGoodsData[i].goods_id] = selectGoodsData[i];
}
}
}
if(Object.keys(selectGoods).length && goodsIds.value.length){
for(let key in selectGoods){
let num = Number(key.split(replacePrefix)[1]);
if(goodsIds.value.indexOf(num) == -1){
delete selectGoods[key];
}
}
}
setGoodsSelected();
})
}
//
const clear = () => {
for (let k in selectGoods) {
delete selectGoods[k];
}
setGoodsSelected();
}
const save = () => {
if (prop.min && selectGoodsNum.value < prop.min) {
ElMessage({
type: 'warning',
message: `${t('goodsSelectPopupGoodsMinTip')}${prop.min}${t('goodsSelectPopupPiece')}`,
});
return;
}
if (prop.max && prop.max > 0 && selectGoodsNum.value && selectGoodsNum.value > prop.max) {
ElMessage({
type: 'warning',
message: `${t('goodsSelectPopupGoodsMaxTip')}${prop.max}${t('goodsSelectPopupPiece')}`,
});
return;
}
if(prop.way == 'single'){
let realTypeNum = 0;
let virtualTypeNum = 0;
for (let k in selectGoods) {
if(selectGoods[k].goods_type == "virtual"){
virtualTypeNum++;
}else if(selectGoods[k].goods_type == "real"){
realTypeNum++;
}
}
if (realTypeNum != Object.keys(selectGoods).length && virtualTypeNum != Object.keys(selectGoods).length) {
ElMessage({
type: 'warning',
message: `${t('wayPlaceholder')}`,
});
return;
}
}
let ids: any = [];
for (let k in selectGoods) {
ids.push(parseInt(k.replace(replacePrefix, '')));
}
goodsIds.value.splice(0, goodsIds.value.length, ...ids)
emit('goodsSelect',selectGoods)
initSearchParam();
showDialog.value = false
}
//
const initSearchParam = ()=>{
goodsTable.searchParam.keyword = '';
goodsTable.searchParam.goods_category = [];
goodsTable.searchParam.select_type = 'all';
goodsTable.searchParam.goods_ids = '';
goodsTable.searchParam.verify_goods_ids = '';
goodsTable.searchParam.verify_sku_ids = '';
goodsTable.searchParam.goods_type = '';
}
defineExpose({
showDialog,
selectGoods,
selectGoodsNum
})
</script>
<style lang="scss" scoped>
.form-item-wrap {
margin-right: 10px !important;
margin-bottom: 10px !important;
&.last-child {
margin-right: 0 !important;
}
}
.arrow-show{
transform: rotate(90deg);
}
</style>

View File

@ -48,7 +48,7 @@
<el-table-column :label="t('sumCount')" min-width="160">
<template #default="{ row }">
<span v-if="row.receive_type == 1 && row.sum_count != '-1'">{{ row.remain_count || '' }} / {{ row.sum_count || '' }}</span>
<span v-if="row.receive_type == 1 && row.sum_count != '-1'">{{ row.remain_count || 0 }} / {{ row.sum_count || 0 }}</span>
<span v-else>不限量</span>
</template>
</el-table-column>

View File

@ -0,0 +1,474 @@
<template>
<div v-loading="loading">
<el-card class="box-card !border-none main-container" shadow="never">
<div class="flex justify-between items-center mb-[10px]">
<span class="text-page-title">{{ pageName }}</span>
</div>
<!-- <el-tabs v-model="activeName">
<el-tab-pane :label="t('basicInfoTab')" name="basic"> -->
<el-alert type="warning" :closable="false" class="!mb-[0px]">
<template #default>
<p class="mb-[5px]">* 新人专享活动旨在通过专属优惠提升新老客户的转化率达到参与门槛的用户可以享受特定商品的限时新人价优惠</p>
<p class="mb-[5px]">* 每位用户限购1件新人专享商品超出1件的部分将按正常价购买</p>
<p class="mb-[5px]">* 订单支付成功后将视为用户已参与过新人专享活动</p>
<p class="mb-[5px]">* 若订单中的单个商品发生退款用户将无法重新参与新人专享活动只有当整个订单全部退货后用户方可重新参与该活动</p>
</template>
</el-alert>
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form">
<el-card class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-sm pl-[15px]">{{ t('basicInfoTab') }}</h3>
<el-form-item :label="t('activeStatus')">
<el-switch v-model="formData.active_status" active-value="active" inactive-value="close" />
</el-form-item>
<template v-if="formData.active_status==='active'">
<el-form-item :label="t('participationWay')">
<el-radio-group v-model="formData.participation_way">
<el-radio label="never_order">{{ t('neverOrder') }}</el-radio>
<el-radio label="assign_time_order">{{ t('assignTimeOrder') }}</el-radio>
<el-radio label="assign_time_register">{{ t('assignTimeRegister') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="appoint_time" v-if="formData.participation_way != 'never_order'">
<div class="date-picker mr-[5px]">
<el-date-picker class="!w-[200px]" v-model="formData.appoint_time" value-format="YYYY-MM-DD HH:mm:ss" type="datetime"/>
</div>
<span v-if="formData.participation_way === 'assign_time_order'">之前未下过单的会员</span>
<span v-else>之后注册的会员</span>
</el-form-item>
<el-form-item :label="t('validityType')">
<el-radio-group v-model="formData.validity_type">
<el-radio label="day">{{ t('validityDay') }}</el-radio>
<el-radio label="date">{{ t('validityTime') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="validity_day" v-if="formData.validity_type==='day'">
<span>{{ t('validityDayTipsLeft') }}</span>
<div class="flex items-center mx-[5px]">
<el-input v-model.trim="formData.validity_day" @keyup="filterNumber($event)" @blur="()=>{if(formData.validity_day>0) formData.validity_day = parseInt(formData.validity_day)}" clearable class="input-width-short" maxlength="3" />
</div>
<span>{{ t('validityDayTipsRight') }}</span>
<div class="form-tip">{{ t('validityTimeTipsTwo') }}</div>
</el-form-item>
<el-form-item prop="validity_time" v-if="formData.validity_type==='date'">
<span>{{ t('validityTimeTips') }}</span>
<div class="flex items-center px-[5px] w-[200px] date-picker">
<el-date-picker v-model="formData.validity_time" value-format="YYYY-MM-DD HH:mm:ss" type="datetime" />
</div>
<div class="form-tip">{{ t('validityTimeTipsTwo') }}</div>
</el-form-item>
<el-form-item :label="t('activeDesc')">
<div class="flex">
<el-input v-model="formData.active_desc" :placeholder="t('activeDescPlaceholder')" type="textarea" maxlength="500" show-word-limit rows="5" class="!w-[400px]" clearable />
<el-button class="ml-[20px]" type="primary" @click="defaultActiveDescEvent()" plain>{{ t('useDefaultActiveDesc') }}</el-button>
</div>
</el-form-item>
</template>
</el-card>
<el-card v-if="formData.active_status==='active'" class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-sm pl-[15px]">{{ t('bannerList') }}</h3>
<div v-for="(item,index) in formData.banner_list" :key="index">
<el-form-item :label="t('image')" :prop="`banner_list.${index}.imageUrl`" :rules="[{
required: true,
trigger: 'change',
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(t('imagePlaceholder'))
}
callback()
}
}]">
<upload-image v-model="item.imageUrl" :limit="1"/>
</el-form-item>
<!-- :prop="`banner_list.${index}.toLink.name`" :rules="[{
required: true,
trigger: 'change',
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(t('toLinkPlaceholder'))
}
callback()
}
}]" -->
<el-form-item :label="t('toLink')" >
<diy-link v-model="item.toLink"/>
</el-form-item>
<!-- <span v-if="formData.banner_list.length>1" class="cursor-pointer absolute top-[-8px] right-[-8px] delete" @click="deleteConfigList(index)"><el-icon color="#bbbbbb" size="20px"><CircleCloseFilled /></el-icon></span> -->
</div>
</el-card>
<el-card v-if="formData.active_status==='active'" class="box-card !border-none" shadow="never">
<h3 class="panel-title !text-sm pl-[15px]">{{ t('activityGoods') }}</h3>
<el-form-item :label="t('selectGoods')" prop="goodsSkuIds">
<goods-select-popup ref="goodsSelectPopupRef" v-model="formData.goodsSkuIds" @goodsSelect="goodsSelect" mode="sku" :min="1" :max="99" />
</el-form-item>
<el-form-item v-if="formData.goodsSkuList && formData.goodsSkuList.length">
<div class="">
<el-table class="sku_list !w-[1400px]" ref="goods_listTableRef" :data="formData.goodsSkuList" size="large" max-height="480" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column :label="t('goodsSelectPopupGoodsInfo')" min-width="300">
<template #default="{ row }">
<div class="flex items-center cursor-pointer">
<div class="min-w-[60px] h-[60px] flex items-center justify-center">
<el-image v-if="row.sku_image" class="w-[60px] h-[60px]" :src="img(row.sku_image)" fit="contain">
<template #error>
<div class="image-slot">
<img class="w-[60px] h-[60px]" src="@/addon/shop/assets/goods_default.png" />
</div>
</template>
</el-image>
<img v-else class="w-[70px] h-[60px]" src="@/addon/shop/assets/goods_default.png" fit="contain" />
</div>
<div class="ml-2">
<span :title="row.sku_name" class="multi-hidden">{{ row.sku_name ? row.goods_name + ' ' + row.sku_name : row.goods_name }}</span>
<span class="text-primary text-[12px]">{{ row.goods_type_name }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column :label="t('oldPrice')" min-width="120">
<template #default="{ row }">
<div>{{ row.price }}</div>
</template>
</el-table-column>
<el-table-column :label="t('newcomerPrice')" min-width="120">
<template #default="{ row,$index }">
<el-form-item :prop="'goodsSkuList.'+ $index + '.newcomer_price'" :rules="[{
trigger: 'blur',
validator: (rule: any, value: any, callback: any) => {
if(!value){
callback(t('newcomerPricePlaceholder'))
}else if (isNaN(value) || !regExp.digit.test(value)) {
callback(t('newcomerPriceTips'))
} else if (parseFloat(value) <0) {
callback(t('newcomerPriceTipsOne'))
}if (parseFloat(value) > parseFloat(row.price)) {
callback(t('newcomerPriceTipsTwo'))
}else{
callback();
}
}
}]" class="sku-form-item-wrap">
<el-input v-model.trim="row.newcomer_price" clearable placeholder="0" maxlength="8" />
</el-form-item>
</template>
</el-table-column>
<el-table-column prop="stock" :label="t('goodsSelectPopupStock')" min-width="120" align="right" />
<el-table-column :label="t('operation')" align="right" min-width="160">
<template #default="{ row,$index }">
<el-button type="primary" link @click="deleteGoodsEvent(row,$index)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex items-center mb-[15px] mt-[10px] pl-[14px]">
<el-checkbox v-model="toggleCheckbox" size="large" class="!mr-[15px]" @change="toggleChange" :indeterminate="isIndeterminate">
<span>已选 {{ multipleSelection.length }} </span>
</el-checkbox>
<label>{{ t('batchOperation') }}</label>
<el-input v-model.trim="newcomer_price" clearable class="!w-[130px] ml-[10px]" :placeholder="t('newcomerPricePlaceholder')" maxlength="8" />
<el-button class="ml-[10px]" type="primary" @click="saveBatch">{{ t('confirm') }}</el-button>
</div>
</div>
</el-form-item>
<!-- <el-form-item :label="t('limitNum')" prop="limit_num" v-if="formData.goodsSkuList && formData.goodsSkuList.length">-->
<!-- <div>-->
<!-- <div class="flex items-center">-->
<!-- <el-input v-model.trim="formData.limit_num" @keyup="filterNumber($event)" @blur="()=>{if(formData.limit_num>0) formData.limit_num = parseInt(formData.limit_num)}" clearable class="!w-[200px]" maxlength="3" />-->
<!-- </div>-->
<!-- </div>-->
<!-- </el-form-item>-->
</el-card>
<!-- </el-form>
</el-tab-pane>
<el-tab-pane :label="t('bannerList')" name="banner"> -->
<!-- <el-form class="page-form" :model="formData" label-width="120px" ref="bannerFormRef"> -->
<!-- <div class="flex w-full justify-center">
<el-button class="w-[400px]" @click="addConfigList">{{ t('addConfigList') }}</el-button>
</div> -->
</el-form>
<!-- </el-tab-pane>
</el-tabs> -->
</el-card>
<!-- 提交按钮 -->
<div class="fixed-footer-wrap">
<div class="fixed-footer h-[48px]">
<el-button type="primary" @click="onSave">{{ t('save') }}</el-button>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref,computed } from 'vue'
import { t } from '@/lang'
import { useRoute } from 'vue-router'
import {FormInstance, ElMessage} from 'element-plus'
import { filterNumber,img, deepClone } from '@/utils/common'
import { getActiveNewcomerConfig,editActiveNewcomerConfig } from "@/addon/shop/api/marketing";
import goodsSelectPopup from '@/addon/shop/views/goods/components/goods-select-popup.vue'
const route = useRoute()
const pageName = route.meta.title
const loading = ref(true)
const formData = ref({
active_status:'active',
banner_list:[
{imageUrl: '', toLink: {name: ''}},
],
validity_type:'day',
validity_day:7,
validity_time:'',
participation_way:'never_order',
appoint_time:'',
goodsSkuIds:<Array<any>>[],
goodsSkuList:<Array<any>>[],
goods_data:<any>'',
limit_num:1,
active_desc:''
})
//
//
const regExp = {
required: /[\S]+/,
number: /^\d{0,10}$/,
digit: /^\d{0,10}(.?\d{0,2})$/,
special: /^\d{0,10}(.?\d{0,3})$/
}
const formRules = computed(() => {
return {
appoint_time: [
{ required: true, message: t('appointTimePlaceholder'), trigger: 'change' }
],
validity_day: [
{ required: true, validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(t('validityDayPlaceholder'))
}else if(parseInt(value)<=0){
callback(t('validityDayTips'))
}else {
callback()
}
}, trigger: 'blur' }
],
validity_time: [
{ required: true,validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(t('validityTimePlaceholder'))
}else if(formData.value.participation_way != 'never_order'){
if(!formData.value.appoint_time){
callback(t('validityTimePlaceholderTwo'))
}else if(new Date(value).getTime()<=new Date(formData.value.appoint_time).getTime()){
callback(t('validityTimePlaceholderThree'))
}else{
callback()
}
}else {
callback()
}
}, trigger: 'change' }
],
goodsSkuIds: [
{ required: true, message: t('goodsSkuIdsPlaceholder'), trigger: 'blur' }
],
active_desc: [
{ required: true, message: t('activeDescPlaceholder'), trigger: 'blur' }
],
// limit_num:[
// { required: true, validator: (rule: any, value: any, callback: any) => {
// if (!value) {
// callback(t('limitNumPlaceholder'))
// }else if(parseInt(value)<=0){
// callback(t('limitNumTips'))
// }else if(parseInt(value)>formData.value.goodsSkuIds.length) {
// callback(t('limitNumTipsThree'))
// }else{
// callback()
// }
//
// }, trigger: 'blur' }
// ]
}
})
const formRef = ref<FormInstance>()
const bannerFormRef = ref<FormInstance>()
//
const goodsSelect = (value: any) => {
// formData.value.goodsSkuList.splice(0,formData.value.goodsSkuList.length);
let arr = []
for (let key in value) {
let goods_sku: any = value[key];
let sku: any = {
goods_id: goods_sku.goods_id,
sku_id: goods_sku.sku_id,
goods_type_name: goods_sku.goods_type_name,
price: goods_sku.price,
sku_image: goods_sku.sku_image,
goods_name: goods_sku.goods_name,
sku_name: goods_sku.sku_name,
stock: goods_sku.stock,
newcomer_price: "", //
};
if (formData.value.goodsSkuList.length) {
formData.value.goodsSkuList.forEach((el: any) => {
if (el.sku_id == sku.sku_id) {
sku = Object.assign(sku, el)
}
})
}
arr.push(deepClone(sku))
}
formData.value.goodsSkuList = arr;
}
//
const toggleCheckbox = ref()
//
const isIndeterminate = ref(false)
//
const toggleChange = (value: any) => {
isIndeterminate.value = false
goods_listTableRef.value.toggleAllSelection()
}
const goods_listTableRef = ref()
//
const multipleSelection: any = ref([])
//
const handleSelectionChange = (val: []) => {
multipleSelection.value = val
toggleCheckbox.value = false
if (multipleSelection.value.length > 0 && multipleSelection.value.length < formData.value.goodsSkuList.length) {
isIndeterminate.value = true
} else {
isIndeterminate.value = false
}
if (multipleSelection.value.length == formData.value.goodsSkuList.length) {
toggleCheckbox.value = true
}
}
const newcomer_price = ref(null)
const saveBatch = () => {
if (!multipleSelection.value.length) {
ElMessage({
type: 'warning',
message: `${t('batchEmptySelectedGoodsTips')}`
})
return
}
if(!newcomer_price.value){
ElMessage({
type: 'warning',
message: `${t('newcomerPricePlaceholder')}`
})
}else if (isNaN(newcomer_price.value) || !regExp.digit.test(newcomer_price.value)) {
ElMessage({
type: 'warning',
message: `${t('newcomerPriceTips')}`
})
return
} else if (parseFloat(newcomer_price.value) <0) {
ElMessage({
type: 'warning',
message: `${t('newcomerPriceTipsOne')}`
})
return
}
formData.value.goodsSkuList.forEach((item: any) => {
if(multipleSelection.value.some((el: any) => el.sku_id == item.sku_id)){
item.newcomer_price = newcomer_price.value
}
})
}
//
const deleteGoodsEvent = (row: any, index: any) => {
formData.value.goodsSkuList.splice(index, 1);
formData.value.goodsSkuIds.splice(formData.value.goodsSkuIds.indexOf(row.sku_id), 1);
}
const getActiveNewcomerConfigFn = () => {
getActiveNewcomerConfig().then((res: any) => {
Object.keys(formData.value).forEach((key) => {
if(res.data[key]) formData.value[key] = res.data[key]
})
formData.value.goodsSkuIds = []
if(formData.value.banner_list.length == 0) formData.value.banner_list.push({imageUrl: '', toLink: {name: ''}})
formData.value.goodsSkuList = res.data.active_goods.map((item: any) => {
formData.value.goodsSkuIds.push(item.sku_id)
item.newcomer_price = item.active_goods_value.newcomer_price
return item
});
loading.value = false;
}).catch(() => {
loading.value = false
})
}
getActiveNewcomerConfigFn()
/**** 提交 ****/
const preventDuplication = ref(false)
const onSave = async () => {
if (preventDuplication.value) return
await formRef.value?.validate(async (valid) => {
if (valid) {
preventDuplication.value = true
formData.value.goods_data = JSON.stringify(formData.value.goodsSkuList.map((item: any) => {
return {
goods_id: item.goods_id,
sku_id: item.sku_id,
price: item.price,
newcomer_price: item.newcomer_price,
}
}))
editActiveNewcomerConfig(formData.value).then(() => {
newcomer_price.value = null
getActiveNewcomerConfigFn()
preventDuplication.value = false
}).catch(() => {
preventDuplication.value = false
})
}
})
}
/**
* 使用默认说明
*/
const defaultActiveDescEvent = () => {
formData.value.active_desc = `1、新人价是面向${formData.value.participation_way==='never_order'?t('neverOrder'):formData.value.participation_way==='assign_time_order'?t('assignTimeOrder'):t('assignTimeRegister')}提供的一种专属优惠价格,同一账号仅限享受一次优惠;\n2、仅限${formData.value.participation_way==='never_order'?t('neverOrder'):formData.value.participation_way==='assign_time_order'?formData.value.appoint_time+'之前未下过单的会员':formData.value.appoint_time+'之后注册的会员'}可参与;\n3、活动有效期${formData.value.validity_type=='day'?'参与活动后'+formData.value.validity_day+'天内':formData.value.validity_time+'后截止'}`;
}
// const deleteConfigList = (index:number)=>{
// formData.value.banner_list.splice(index,1)
// }
// const addConfigList = ()=>{
// formData.value.banner_list.push({imageUrl:'',toLink:{name: ''}})
// }
</script>
<style lang="scss" scoped>
.main-container {
min-height: calc(100vh - 64px - 48px - 30px);
}
.sku_list :deep(.cell) {
// min-height: 60px !important;
overflow: initial !important;
}
.input-width-short{
width: 100px;
}
.date-picker :deep(.el-input__wrapper){
width: 200px !important;
}
</style>

View File

@ -0,0 +1,293 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-page-title">{{ pageName }}</span>
</div>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="orderTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('orderInfo')" prop='search_name'>
<el-select v-model="orderTable.searchParam.search_type" clearable class="input-item">
<el-option :label="t('orderNo')" value="order_no"></el-option>
<el-option :label="t('outTradeNo')" value="out_trade_no"></el-option>
</el-select>
<el-input class="input-item ml-3" v-model.trim="orderTable.searchParam.search_name" />
</el-form-item>
<el-form-item :label="t('payType')" prop='pay_type'>
<el-select v-model="orderTable.searchParam.pay_type" clearable class="input-item">
<el-option v-for="(item, index) in payTypeData" :key="index" :label="item.name" :value="item.key"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('fromType')" prop='order_from'>
<el-select v-model="orderTable.searchParam.order_from" clearable class="input-item">
<el-option v-for="(item, index) in orderFromData" :key="index" :label="item" :value="index"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="t('createTime')" prop="create_time">
<el-date-picker v-model="orderTable.searchParam.create_time" type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
:end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item :label="t('payTime')" prop="pay_time">
<el-date-picker v-model="orderTable.searchParam.pay_time" type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss" :start-placeholder="t('startDate')"
:end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadOrderList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<el-tabs v-model="activeName" class="demo-tabs" @tab-change="handleClick">
<el-tab-pane :label="t('all')" name=""></el-tab-pane>
<el-tab-pane :label="t('toBeShipped')" name="2"></el-tab-pane>
<el-tab-pane :label="t('shipped')" name="3"></el-tab-pane>
<el-tab-pane :label="t('completed')" name="5"></el-tab-pane>
<el-tab-pane :label="t('closed')" name="-1"></el-tab-pane>
</el-tabs>
<div>
<el-table :data="orderTable.data" size="large" class="table-top">
<el-table-column :label="t('orderGoods')" min-width="200" />
<el-table-column :label="t('goodsPriceNumber')" min-width="150" />
<el-table-column :label="t('orderMoney')" min-width="150" />
<el-table-column :label="t('orderStatus')" min-width="100" />
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="100" />
</el-table>
</div>
<div class="table-body min-h-[150px]" v-loading="orderTable.loading">
<div v-if="!orderTable.loading">
<template v-if="orderTable.data.length">
<div v-for="(item, index) in orderTable.data" :key="index">
<div class="flex items-center justify-between bg-[#f7f8fa] mt-[10px] border-[#e4e7ed] border-solid border-b-[1px] px-3 h-[35px] text-[12px] text-[#666]">
<div>
<span>{{ t('orderNo') }}{{ (item as any).order_no }}</span>
<span class="ml-5">{{ t('createTime') }}{{ (item as any).create_time }}</span>
<!-- <span class="ml-5">{{ t('orderFrom') }}{{ (item as any).order_form_name }}</span> -->
<span class="ml-5" v-if="item.pay">{{ t('payType') }}{{ (item as any).pay.type_name }}</span>
</div>
</div>
<el-table :data="item.order_goods" size="large" :show-header="false" :span-method="arraySpanMethod">
<template #empty>
<span>{{ !orderTable.loading ? t('emptyData') : '' }}</span>
</template>
<!-- <el-table-column :label="t('orderNo')" min-width="250">
<template #default="{ row }">
<span class="text-[14px]">{{ row.order_no }}</span>
</template>
</el-table-column> -->
<el-table-column min-width="200">
<template #default="{ row }">
<div class="flex cursor-pointer">
<div class="flex items-center min-w-[50px] mr-[10px]">
<img class="w-[50px] h-[50px]" v-if="row.goods_image_thumb_small" :src="img(row.goods_image_thumb_small)" alt="">
<img class="w-[50px] h-[50px]" v-else src="@/addon/shop/assets/goods_default.png" alt="">
</div>
<div class="flex flex-col">
<p class="multi-hidden text-[14px]">{{ row.goods_name }}</p>
<span class="text-[12px] text-[#999]">{{ row.sku_name }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column min-width="150">
<template #header>
<div style="display: inline-flex; align-items: center">
<span class="mr-[5px]">{{ t('goodsPriceNumber') }}</span>
<el-tooltip class="box-item" effect="light" placement="top">
<template #content>{{t('goodsPriceNumberTips')}}</template>
<el-icon color="#666">
<QuestionFilled />
</el-icon>
</el-tooltip>
</div>
</template>
<template #default="{ row }">
<div class="flex flex-col">
<span class="text-[13px]">{{ row.price }}</span>
<span v-if="row.extend && row.extend.newcomer_price" class="text-[13px] mt-[5px]">
<span v-if="parseFloat(row.extend.newcomer_price) && row.num > 1">{{ row.num }}{{ t('piece') }}<span class="text-[#999]">第1{{ t('piece') }}{{parseFloat(row.extend.newcomer_price).toFixed(2)}}/{{ t('piece') }}{{row.num>2?'2~'+row.num:'2'}}{{ t('piece') }}{{parseFloat(row.price).toFixed(2)}}/{{ t('piece') }}</span></span>
<span v-else>{{ row.num }}{{ t('piece') }}</span>
</span>
<span v-else class="text-[13px] mt-[5px]">{{ row.num }}{{ t('piece') }}</span>
</div>
</template>
</el-table-column>
<el-table-column :label="t('orderMoney')" min-width="150" class-name="border-0 border-l-[1px] border-solid border-[var(--el-table-border-color)]">
<template #default="{ row }">
<span class="text-[14px]">{{ item.order_money }}</span>
</template>
</el-table-column>
<el-table-column :label="t('orderStatus')" min-width="100">
<template #default="{ row }">
<span class="text-[14px]">{{ item.status_name.name }}</span>
</template>
</el-table-column>
<el-table-column :label="t('operation')" fixed="right" align="right" min-width="100">
<template #default="{ row }">
<el-button type="primary" link @click="detailEvent(item)">{{ t('info') }}</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
</div>
</div>
<div class="mt-[16px] flex justify-end">
<el-pagination v-model:current-page="orderTable.page" v-model:page-size="orderTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="orderTable.total"
@size-change="loadOrderList()" @current-change="loadOrderList" />
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { t } from '@/lang'
import { getOrderList, getOrderStatus, getOrderPayType, getOrderFrom } from '@/addon/shop/api/order'
import { img,setTablePageStorage,getTablePageStorage } from '@/utils/common'
import { FormInstance } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
const router = useRouter()
const pageName = route.meta.title
const activeName = ref('')
const statusData = ref([])
const payTypeData = ref<any[]>([])
const orderFromData = ref([])
const setFormData = async () => {
statusData.value = await (await getOrderStatus()).data
payTypeData.value = await (await getOrderPayType()).data
orderFromData.value = await (await getOrderFrom()).data
}
setFormData()
interface OrderTable {
page: number
limit: number
total: number
loading: boolean
data: any[]
searchParam: any,
}
const orderTable = reactive<OrderTable>({
page: 1,
limit: 10,
total: 0,
loading: true,
data: [],
searchParam: {
search_type: 'order_no',
search_name: '',
pay_type: '',
order_from: '',
status: '',
create_time: [],
pay_time: [],
activity_type:'newcomer_discount'
}
})
const searchFormRef = ref<FormInstance>()
/**
* 获取订单列表
*/
const loadOrderList = (page: number = 1) => {
orderTable.loading = true
orderTable.page = page
getOrderList({
page: orderTable.page,
limit: orderTable.limit,
...orderTable.searchParam
}).then(res => {
orderTable.loading = false
orderTable.data = res.data.data.map((el: any) => {
el.order_goods.forEach((v: any) => {
v.rowNum = el.order_goods.length
})
return el
})
orderTable.total = res.data.total
setTablePageStorage(orderTable.page, orderTable.limit, orderTable.searchParam);
}).catch(() => {
orderTable.loading = false
})
}
loadOrderList(getTablePageStorage(orderTable.searchParam).page);
//
const arraySpanMethod = ({
row,
column,
rowIndex,
columnIndex
}:any) => {
if (rowIndex === 0) {
if (columnIndex > 1) {
return [row.rowNum, 1]
} else {
return [1, 1]
}
} else {
if (columnIndex > 1) {
return [0, 0]
} else {
return [1, 1]
}
}
}
const handleClick = (event: any) => {
orderTable.searchParam.status = event
loadOrderList()
}
//
const detailEvent = (data: any) => {
const url = router.resolve({
path: '/shop/order/detail',
query: {
order_id: data.order_id
}
})
window.open(url.href)
}
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()
loadOrderList()
}
</script>
<style lang="scss" scoped>
.table-top :deep(.el-table__body-wrapper) {
display: none;
}
:deep(.el-table) {
--el-table-row-hover-bg-color: var(--el-transfer-border-color);
}
/* 多行超出隐藏 */
.multi-hidden {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.input-item {
width: 150px !important;
}
</style>

View File

@ -12,7 +12,7 @@
<div>
<p class="!text-sm">
<span>{{ t('closeOrderInfoLeft') }}</span>
<el-input v-model="formData.close_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<el-input v-model.trim="formData.close_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<span>{{ t('closeOrderInfoRight') }}</span>
</p>
<p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('closeOrderInfoBottom') }}</p>
@ -28,7 +28,7 @@
<div>
<p class="!text-sm">
<span>{{ t('confirmLeft') }}</span>
<el-input v-model="formData.finish_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<el-input v-model.trim="formData.finish_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<span>{{ t('confirmRight') }}</span>
</p>
<p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('confirmBottom') }}</p>
@ -44,7 +44,7 @@
<div>
<p class="!text-sm">
<span>{{ t('refundLeft') }}</span>
<el-input v-model="formData.refund_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<el-input v-model.trim="formData.refund_length" class="!w-[120px] mx-[10px]" @keyup="filterNumber($event)" clearable />
<span>{{ t('refundRight') }}</span>
</p>
<p class="text-[12px] text-[#a9a9a9] leading-normal mt-[5px]">{{ t('refundBottom') }}</p>

View File

@ -24,7 +24,7 @@
<el-form-item :label="t('deliveryType')">
<div class="input-width">{{ formData.order_main.delivery_type_name }}</div>
</el-form-item>
<div>
<div v-if="formData.order_main.delivery_type == 'express' || formData.order_main.delivery_type == 'local_delivery'">
<el-form-item :label="t('takerName')">
<div class="input-width">{{ formData.order_main.taker_name }}</div>
</el-form-item>

Binary file not shown.

View File

@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip

View File

@ -71,7 +71,7 @@
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
<java.version>17</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>

View File

@ -17,9 +17,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
</properties>
<dependencies>

View File

@ -1,5 +1,6 @@
package com.niu.shop.controller.adminapi.goods;
import cn.hutool.core.util.ObjectUtil;
import com.niu.core.common.domain.Result;
import com.niu.core.common.domain.PageResult;
import com.niu.shop.service.admin.goods.param.*;
@ -10,6 +11,7 @@ import com.niu.core.common.domain.PageParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
/**
@ -52,9 +54,9 @@ public class AttrController {
* @return Result<ShopGoodsAttrInfoVo>
*/
@GetMapping("/{id}")
public Result<ShopGoodsAttrInfoVo> info(@Validated @PathVariable Integer id) {
public Result info(@Validated @PathVariable Integer id) {
ShopGoodsAttrInfoVo info = goodsAttrService.info(id);
return Result.success(info);
return Result.success(ObjectUtil.defaultIfNull(info, new LinkedList<>()));
}
/**

View File

@ -5,7 +5,6 @@ import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.domain.Result;
import com.niu.shop.service.admin.marketing.ICouponService;
import com.niu.shop.service.admin.marketing.param.ShopActiveParam;
import com.niu.shop.service.admin.marketing.param.ShopCouponParam;
import com.niu.shop.service.admin.marketing.param.ShopCouponSearchParam;
import com.niu.shop.service.admin.marketing.vo.ShopCouponInfoVo;
@ -15,7 +14,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 优惠券控制器
@ -33,11 +31,13 @@ public class CouponController {
public Result<JSONObject> init() {
return Result.success(couponService.getInit());
}
/**
* 优惠券列表
* @param pageParam 分页
*
* @param pageParam 分页
* @param searchParam 搜索条件
* @return Result<PageResult<ShopCouponListVo>>
* @return Result<PageResult < ShopCouponListVo>>
*/
@GetMapping("")
public Result<PageResult<ShopCouponListVo>> list(@Validated PageParam pageParam,
@ -48,6 +48,7 @@ public class CouponController {
/**
* 优惠券详情
*
* @param id 主键ID
* @return Result<ShopCouponInfoVo>
*/
@ -59,6 +60,7 @@ public class CouponController {
/**
* 优惠券添加
*
* @param addParam 添加参数
* @return AjaxResult<Object>
*/
@ -70,6 +72,7 @@ public class CouponController {
/**
* 优惠券编辑
*
* @param editParam 编辑参数
* @return Result<Object>
*/
@ -81,6 +84,7 @@ public class CouponController {
/**
* 优惠券删除
*
* @param id 参数
* @return Result<Object>
*/
@ -92,6 +96,7 @@ public class CouponController {
/**
* 获取会员优惠券列表
*
* @param pageParam
* @param id
* @param keywords
@ -101,35 +106,39 @@ public class CouponController {
public Result<PageResult<ShopCouponMemberListVo>> getMemberCoupon(@Validated PageParam pageParam, Integer id, String keywords) {
return Result.success(couponService.getMemberCoupon(pageParam, id, keywords));
}
/**
* 获取选中优惠券
* @param couponIds
*
* @param couponId
* @return
*/
@GetMapping("/selected")
public List<ShopCouponListVo> getSelectedLists(@Validated @RequestBody String couponIds){
return couponService.getSelectedList(couponIds);
public Result<?> getSelectedLists(@Validated @RequestParam("coupon_id") String couponId) {
return Result.success(couponService.getSelectedList(couponId));
}
/**
* 设置优惠券领用状态
*
* @param status
* @param id
* @return
*/
@PutMapping("setstatus/{status}")
public Result<Object> setCouponStatus(@Validated @PathVariable("status") Integer status, @Validated @RequestBody Integer id){
public Result<Object> setCouponStatus(@Validated @PathVariable("status") Integer status, @Validated @RequestBody Integer id) {
couponService.setStatus(id, status);
return Result.success();
}
/**
* 优惠券失效
*
* @param id
* @return
*/
@PutMapping("invalid/{id}")
public Result<Object> couponInvalid(@Validated @PathVariable("id") Integer id){
public Result<Object> couponInvalid(@Validated @PathVariable("id") Integer id) {
couponService.couponInvalid(id);
return Result.success();
}

View File

@ -1,13 +1,13 @@
package com.niu.shop.controller.adminapi.marketing;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.Result;
import com.niu.shop.service.admin.marketing.IShopNewcomerMemberRecordsService;
import com.niu.shop.service.admin.marketing.IShopNewcomerService;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectPageParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectSkuParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSetConfigParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* 新人专享会员参与记录表控制器
@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("adminapi/shop/active/newcomer")
public class ShopNewcomerMemberRecordsController {
private final IShopNewcomerMemberRecordsService shopNewcomerMemberRecordsService;
private final IShopNewcomerService shopNewcomerMemberRecordsService;
@GetMapping("/config")
Result<?> getConfig() {
@ -26,9 +26,19 @@ public class ShopNewcomerMemberRecordsController {
}
@PutMapping("/config")
Result<?> setConfig(ShopNewcomerSetConfigParam param) {
Result<?> setConfig(@RequestBody ShopNewcomerSetConfigParam param) {
shopNewcomerMemberRecordsService.setConfig(param);
return Result.success();
}
@GetMapping("/goods/selectgoodssku")
Result<?> getSelectSku(ShopNewcomerSelectSkuParam param) {
return Result.success(shopNewcomerMemberRecordsService.getSelectSku(param));
}
@GetMapping("/goods/select")
Result<?> select(PageParam pageParam, ShopNewcomerSelectPageParam param) {
return Result.success(shopNewcomerMemberRecordsService.getSelectPage(pageParam, param));
}
}

View File

@ -1,15 +1,16 @@
package com.niu.shop.controller.adminapi.order;
import com.niu.core.common.domain.Result;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.domain.Result;
import com.niu.shop.service.admin.order.IShopInvoiceService;
import com.niu.shop.service.admin.order.param.ShopInvoiceParam;
import com.niu.shop.service.admin.order.param.ShopInvoiceSearchParam;
import com.niu.shop.service.admin.order.vo.ShopInvoiceInfoVo;
import com.niu.shop.service.admin.order.vo.ShopInvoiceListVo;
import com.niu.core.common.domain.PageParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
@ -25,9 +26,10 @@ public class ShopInvoiceController {
/**
* 发票列表
* @param pageParam 分页
*
* @param pageParam 分页
* @param searchParam 搜索条件
* @return Result<PageResult<ShopInvoiceListVo>>
* @return Result<PageResult < ShopInvoiceListVo>>
*/
@GetMapping("/invoice")
public Result<PageResult<ShopInvoiceListVo>> lists(@Validated PageParam pageParam, ShopInvoiceSearchParam searchParam) {
@ -37,6 +39,7 @@ public class ShopInvoiceController {
/**
* 发票详情
*
* @return
*/
@GetMapping("/invoice/{id}")
@ -47,11 +50,12 @@ public class ShopInvoiceController {
/**
* 发票编辑
*
* @param shopInvoiceParam 开票参数
* @return Result<Object>
*/
@PostMapping("/invoice/{id}")
public Result<Object> invoicing(Integer id, @Validated @RequestBody ShopInvoiceParam shopInvoiceParam) {
@PutMapping("/invoice/{id}")
public Result<Object> invoicing(@PathVariable Integer id, @Validated @RequestBody ShopInvoiceParam shopInvoiceParam) {
shopInvoiceService.invoicing(id, shopInvoiceParam);
return Result.success();
}

View File

@ -10,7 +10,6 @@ import com.niu.shop.service.api.marketing.param.ShopCouponReceiveParam;
import com.niu.shop.service.api.marketing.param.ShopCouponSearchParam;
import com.niu.shop.service.api.marketing.vo.ShopCouponInfoVo;
import com.niu.shop.service.api.marketing.vo.ShopCouponListVo;
import com.niu.shop.service.api.marketing.vo.ShopCouponMemberListVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -30,9 +29,10 @@ public class CouponController {
/**
* 优惠券列表
* @param pageParam 分页
*
* @param pageParam 分页
* @param searchParam 搜索条件
* @return Result<PageResult<ShopCouponListVo>>
* @return Result<PageResult < ShopCouponListVo>>
*/
@GetMapping("/coupon")
public Result<PageResult<ShopCouponListVo>> list(@Validated PageParam pageParam,
@ -43,6 +43,7 @@ public class CouponController {
/**
* 优惠券详情
*
* @param id 主键ID
* @return Result<ShopCouponInfoVo>
*/
@ -54,30 +55,33 @@ public class CouponController {
/**
* 优惠券领取
*
* @param receiveParam
* @return
*/
@SaCheckLogin
@PostMapping("/coupon")
public Result<Object> receive(@Validated @RequestBody ShopCouponReceiveParam receiveParam) {
public Result<?> receive(@Validated @RequestBody ShopCouponReceiveParam receiveParam) {
couponService.receive(receiveParam);
return Result.success();
return Result.success("领取成功");
}
/**
* 会员优惠券列表
*
* @param pageParam
* @param status
* @return
*/
@SaCheckLogin
@GetMapping("/member/coupon")
public Result<Object> memberCouponList(@Validated PageParam pageParam,String type, Integer status) {
public Result<Object> memberCouponList(@Validated PageParam pageParam, String type, Integer status) {
return Result.success(couponService.getMemberPage(pageParam, status, type));
}
/**
* 会员优惠券状态数量
*
* @return
*/
@SaCheckLogin
@ -88,6 +92,7 @@ public class CouponController {
/**
* 会员优惠券数量
*
* @return
*/
@SaCheckLogin
@ -98,6 +103,7 @@ public class CouponController {
/**
* 获取优惠券列表组件调用
*
* @param couponIds
* @param num
* @return
@ -109,21 +115,22 @@ public class CouponController {
/**
* 优惠券二维码
*
* @param id
* @return
*/
@GetMapping("/coupon/qrcode/{id}")
public Result<Object> qrcode( @PathVariable("id") Integer id)
{
public Result<Object> qrcode(@PathVariable("id") Integer id) {
return null;
}
/**
* 获取优惠券类型
*
* @return
*/
@GetMapping("/coupon_type")
public Result<Object> getCouponType(){
public Result<Object> getCouponType() {
return Result.success(couponService.getCouponType());
}

View File

@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@RequestMapping("adminapi/shop/newcomer")
@RequestMapping("api/shop/newcomer")
public class ShopNewcomerMemberRecordsController {
private final IShopNewcomerService shopNewcomerService;

View File

@ -3,9 +3,9 @@ package com.niu.shop.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigDecimal;
/**
* 请填写功能名称实体
@ -15,7 +15,7 @@ public class ShopStat implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
@TableId(value = "id", type = IdType.AUTO)
private Integer id; //
private Integer siteId; // 站点id
private String date; // 日期

View File

@ -3,10 +3,9 @@ package com.niu.shop.entity.active;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigDecimal;
import java.math.BigDecimal;
/**
* 店铺营销活动实体
@ -16,11 +15,12 @@ public class ShopActiveGoods implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="active_goods_id", type= IdType.AUTO)
@TableId(value = "active_goods_id", type = IdType.AUTO)
private Integer activeGoodsId; // 活动商品id
private Integer activeId; // 活动id
private Integer siteId; // 站点id
private Integer goodsId; // 商品id
private Integer skuId; // 商品规格id
private String activeGoodsType; // 商品活动类型单品独立商品店铺整体商品
private String activeClass; // 商品活动类别
private String activeGoodsLabel; // 活动商品标签针对活动有标签

View File

@ -12,8 +12,8 @@ public class ShopOrderInvoice implements Serializable {
private static final long serialVersionUID = 1L;
private String isInvoice = "2"; // 是否需要发票
private String[] invoiceType; // 发票类型
private String[] invoiceContent; // 发票内容
private String[] invoiceType = new String[]{}; // 发票类型
private String[] invoiceContent = new String[]{}; // 发票内容
}

View File

@ -6,8 +6,12 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ActiveClassEnum {
DISCOUNT("discount","限时折扣"),
EXCHANGE("exchange","积分兑换");
DISCOUNT("discount", "限时折扣"),
EXCHANGE("exchange", "积分兑换"),
MANJIANSONG("manjiansong", "满减送"),
NEWCOMER_DISCOUNT("newcomer_discount", "新人专享"),
GIFTCARD("giftcard ", "礼品卡"),
;
private final String type;
@ -16,14 +20,13 @@ public enum ActiveClassEnum {
/**
* 通过type获取当前名称
*
* @param type
* @return
*/
public static String getNameByType(String type){
for(ActiveClassEnum item : ActiveClassEnum.values())
{
if(item.getType().equals(type))
{
public static String getNameByType(String type) {
for (ActiveClassEnum item : ActiveClassEnum.values()) {
if (item.getType().equals(type)) {
return item.getName();
}
}

View File

@ -1,6 +1,5 @@
package com.niu.shop.enums.active;
import com.niu.shop.enums.order.OrderDeliveryTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ -10,8 +9,8 @@ import java.util.Map;
@Getter
@AllArgsConstructor
public enum ActiveStatusEnum {
NOT_ACTIVE("not_active","未开始"),
ACTIVE("active","进行中"),
NOT_ACTIVE("not_active", "未开始"),
ACTIVE("active", "进行中"),
END("end", "已结束"),
CLOSE("close", "已关闭");
@ -23,8 +22,7 @@ public enum ActiveStatusEnum {
public static Map<String, String> getMap() {
Map<String, String> map = new HashMap<>();
for(ActiveStatusEnum item : ActiveStatusEnum.values())
{
for (ActiveStatusEnum item : ActiveStatusEnum.values()) {
map.put(item.getStatus(), item.getName());
}
return map;
@ -32,17 +30,25 @@ public enum ActiveStatusEnum {
/**
* 通过status获取当前名称
*
* @param status
* @return
*/
public static String getNameByStatus(String status){
for(ActiveStatusEnum item : ActiveStatusEnum.values())
{
if(item.getStatus().equals(status))
{
public static String getNameByStatus(String status) {
for (ActiveStatusEnum item : ActiveStatusEnum.values()) {
if (item.getStatus().equals(status)) {
return item.getName();
}
}
return "";
}
public static ActiveStatusEnum getEnumByStatus(String status) {
for (ActiveStatusEnum item : ActiveStatusEnum.values()) {
if (item.getStatus().equals(status)) {
return item;
}
}
return null;
}
}

View File

@ -6,8 +6,9 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ActiveTypeEnum {
MEMBER("member","会员活动"),
GOODS("goods","商品活动"),
MEMBER("member", "会员活动"),
GOODS("goods", "商品活动"),
NEWCOMER_DISCOUNT("newcomer_discount", "新人专享"),
SHOP("shop", "店铺活动");
private final String type;
@ -16,14 +17,13 @@ public enum ActiveTypeEnum {
/**
* 通过type获取当前名称
*
* @param type
* @return
*/
public static String getNameByType(String type){
for(ActiveTypeEnum item : ActiveTypeEnum.values())
{
if(item.getType().equals(type))
{
public static String getNameByType(String type) {
for (ActiveTypeEnum item : ActiveTypeEnum.values()) {
if (item.getType().equals(type)) {
return item.getName();
}
}

View File

@ -1,17 +1,30 @@
package com.niu.shop.enums.delivery;
import cn.hutool.core.util.ObjectUtil;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum ElectronicSheetPayTypeEnum {
CASH_PAYMENT("现付"),
FREIGHT_COLLECT("到付"),
MONTHLY_STATEMENT("月结");
CASH_PAYMENT(1, "现付"),
FREIGHT_COLLECT(2, "到付"),
MONTHLY_STATEMENT(3, "月结");
private final int value;
private final String payType;
ElectronicSheetPayTypeEnum(String payType) {
ElectronicSheetPayTypeEnum(int value, String payType) {
this.value = value;
this.payType = payType;
}
public static String getPayTypeByType(Integer type) {
return Arrays.stream(ElectronicSheetPayTypeEnum.values())
.filter(t -> ObjectUtil.equal(t.getValue(), type))
.map(ElectronicSheetPayTypeEnum::getPayType)
.findFirst()
.orElse("");
}
}

View File

@ -33,8 +33,10 @@ public class ActiveEndJob extends AbstractJobProvider implements IJobProvider {
.select("active_id")
);
if (ObjectUtil.isNotEmpty(activeList)) {
for (ShopActive item: activeList) {
coreActiveService().end(item.getActiveId());
for (ShopActive item : activeList) {
if (item.getEndTime() != null && item.getEndTime() != 0) {
coreActiveService().end(item.getActiveId());
}
}
}
}

View File

@ -0,0 +1,29 @@
package com.niu.shop.job.marketing;
import com.niu.core.common.component.context.SpringContext;
import com.niu.core.common.component.job.AbstractJobProvider;
import com.niu.core.common.component.job.IJobProvider;
import com.niu.core.common.component.job.annotation.JobProvider;
import com.niu.shop.service.core.marketing.ICoreShopNewcomerService;
import org.quartz.JobExecutionContext;
@SuppressWarnings("unused")
@JobProvider(key = "NewcomerSaveAfterJob", name = "新人专享活动修改后更新会员活动有效期", describe = "新人专享活动修改后更新会员活动有效期", source = "shop")
public class NewcomerSaveAfterJob extends AbstractJobProvider implements IJobProvider {
private volatile boolean init = false;
private ICoreShopNewcomerService coreShopNewcomerService;
@Override
public void exec(JobExecutionContext context) {
if (!init) {
init();
init = true;
}
coreShopNewcomerService.afterSave();
}
private void init() {
coreShopNewcomerService = SpringContext.bean(ICoreShopNewcomerService.class);
}
}

View File

@ -0,0 +1,112 @@
package com.niu.shop.listener.marketing;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.niu.core.common.annotation.EventCallback;
import com.niu.shop.entity.active.ShopActive;
import com.niu.shop.entity.active.ShopActiveGoods;
import com.niu.shop.enums.active.ActiveClassEnum;
import com.niu.shop.enums.active.ActiveStatusEnum;
import com.niu.shop.event.marketing.GoodsMarketCalculateEventDefiner;
import com.niu.shop.mapper.active.ShopActiveGoodsMapper;
import com.niu.shop.mapper.active.ShopActiveMapper;
import com.niu.shop.service.core.marketing.ICoreShopNewcomerService;
import com.niu.shop.service.core.order.vo.OrderCreateDataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
@Slf4j
@Component
@EventCallback("shop")
public class ShopNewcomerCalculateListener extends GoodsMarketCalculateEventDefiner {
private ShopActiveMapper shopActiveMapper;
private ShopActiveGoodsMapper shopActiveGoodsMapper;
private ICoreShopNewcomerService coreShopNewcomerService;
@Override
public GoodsMarketCalculateResult handleCallback(GoodsMarketCalculateEvent event) {
log.debug("参与新人专享活动ShopNewcomerCalculate: {}", JSON.toJSONString(event));
OrderCreateDataVo.Sku skuInfo = event.getSkuInfo();
OrderCreateDataVo orderObj = event.getVo();
boolean isNewcomer = coreShopNewcomerService.checkIfNewcomer(orderObj.getSiteId(), orderObj.getMemberId());
if (!isNewcomer || ObjectUtil.hasEmpty(orderObj.getExtendData(), skuInfo) ||
!orderObj.getExtendData().getStr("activity_type", "").equals(ActiveClassEnum.NEWCOMER_DISCOUNT.getType())) {
return null;
}
LambdaQueryWrapper<ShopActiveGoods> shopActiveGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopActiveGoodsLambdaQueryWrapper.eq(ShopActiveGoods::getGoodsId, skuInfo.getGoodsId())
.eq(ShopActiveGoods::getSkuId, skuInfo.getSkuId())
.eq(ShopActiveGoods::getActiveClass, ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
ShopActiveGoods activeGoods = shopActiveGoodsMapper.selectOne(shopActiveGoodsLambdaQueryWrapper);
if (ObjectUtil.isEmpty(activeGoods)) {
return null;
}
ShopActive shopActive = shopActiveMapper.selectById(activeGoods.getActiveId());
if (!shopActive.getActiveStatus().equals(ActiveStatusEnum.ACTIVE.getStatus())) {
return null;
}
BigDecimal newcomerPrice = JSON.parseObject(activeGoods.getActiveGoodsValue()).getBigDecimal("newcomer_price");
skuInfo.setNewcomerPrice(newcomerPrice);
skuInfo.setIsNewcomer(1);
JSONObject extend = new JSONObject();
extend.set("is_newcomer", 1)
.set("newcomer_price", newcomerPrice);
skuInfo.setExtend(extend);
OrderCreateDataVo.Discount discount = discountFormat(ListUtil.of(skuInfo.getSkuId()), skuInfo.getMemberPrice(),
activeGoods.getActiveId(), shopActive.getActiveDesc());
orderObj.getDiscount().put(ActiveClassEnum.NEWCOMER_DISCOUNT.getType(), discount);
if (skuInfo.getNum() == 1) {
skuInfo.setPrice(newcomerPrice);
skuInfo.setGoodsMoney(skuInfo.getPrice().multiply(BigDecimal.valueOf(skuInfo.getNum())));
} else {
skuInfo.setGoodsMoney(newcomerPrice.add(skuInfo.getMemberPrice().multiply(new BigDecimal(skuInfo.getNum() - 1))));
}
GoodsMarketCalculateResult result = new GoodsMarketCalculateResult();
result.setSkuInfo(skuInfo);
return result;
}
private OrderCreateDataVo.Discount discountFormat(List<Integer> goodsIds, BigDecimal money, Integer discountTypeId, String activeDesc) {
OrderCreateDataVo.Discount discount = new OrderCreateDataVo.Discount();
discount.setMatchGoodsIds(goodsIds.toArray(new Integer[]{}));
discount.setType("discount");
discount.setNum(1);
discount.setMoney(money);
discount.setDiscountType(ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
discount.setDiscountTypeId(discountTypeId);
discount.setContent("新人专享");
discount.setTitle(activeDesc);
return discount;
}
@Autowired
public void setCoreShopNewcomerService(ICoreShopNewcomerService coreShopNewcomerService) {
this.coreShopNewcomerService = coreShopNewcomerService;
}
@Autowired
public void setShopActiveGoodsMapper(ShopActiveGoodsMapper shopActiveGoodsMapper) {
this.shopActiveGoodsMapper = shopActiveGoodsMapper;
}
@Autowired
public void setShopActiveMapper(ShopActiveMapper shopActiveMapper) {
this.shopActiveMapper = shopActiveMapper;
}
}

View File

@ -84,7 +84,7 @@ public class VerifyCreateListener extends VerifyCreateEventDefiner {
JSONObject diyItem = new JSONObject();
JSONArray diyList = new JSONArray();
diyList.add(new JSONObject().set("title", "订单编号").set("value", order.getOrderNo()));
diyList.add(new JSONObject().set("title", "支付时间").set("value", DateUtil.date(order.getPayTime() * 1000)));
diyList.add(new JSONObject().set("title", "支付时间").set("value", DateUtil.formatDateTime(new Date(order.getPayTime() * 1000))));
diyItem.set("title", "订单信息");
diyItem.set("list", diyList);
diy.add(diyItem);

View File

@ -81,19 +81,12 @@ public class ShopDeliveryElectronicSheetServiceImpl implements IShopDeliveryElec
}
queryWrapper.orderByDesc(ShopDeliveryElectronicSheet::getId);
IPage<ShopDeliveryElectronicSheet> iPage = shopDeliveryElectronicSheetMapper.selectPage(new Page<>(page, limit), queryWrapper);
Set<Integer> expressCompanyIds = iPage.getRecords().stream().map(ShopDeliveryElectronicSheet::getExpressCompanyId).collect(Collectors.toSet());
final Map<Integer, ShopDeliveryCompany> companyMap = new HashMap<>();
if (ObjectUtil.isNotEmpty(expressCompanyIds)) {
LambdaQueryWrapper<ShopDeliveryCompany> companyQueryWrapper = new LambdaQueryWrapper<>();
companyQueryWrapper.eq(ShopDeliveryCompany::getSiteId, RequestUtils.siteId());
companyQueryWrapper.in(ShopDeliveryCompany::getCompanyId, expressCompanyIds);
companyMap.putAll(shopDeliveryCompanyMapper.selectList(companyQueryWrapper)
.stream().collect(Collectors.toMap(ShopDeliveryCompany::getCompanyId, e -> e)));
}
return iPage.getRecords().stream().map(item -> BeanUtil.toBean(item, ShopDeliveryElectronicSheetListVo.class)).collect(Collectors.toList());
return shopDeliveryElectronicSheetMapper.selectPage(new Page<>(page, limit), queryWrapper)
.getRecords()
.stream()
.map(item -> BeanUtil.toBean(item, ShopDeliveryElectronicSheetListVo.class))
.collect(Collectors.toList());
}
/**
@ -109,7 +102,9 @@ public class ShopDeliveryElectronicSheetServiceImpl implements IShopDeliveryElec
Integer limit = pageParam.getLimit();
LambdaQueryWrapper<ShopDeliveryElectronicSheet> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByDesc(ShopDeliveryElectronicSheet::getId);
queryWrapper.eq(ShopDeliveryElectronicSheet::getSiteId, RequestUtils.siteId())
.orderByDesc(ShopDeliveryElectronicSheet::getIsDefault)
.orderByDesc(ShopDeliveryElectronicSheet::getId);
if (pagesParam.getExpressCompanyId() != null && pagesParam.getExpressCompanyId() > 0) {
queryWrapper.eq(ShopDeliveryElectronicSheet::getExpressCompanyId, pagesParam.getExpressCompanyId());
@ -135,6 +130,7 @@ public class ShopDeliveryElectronicSheetServiceImpl implements IShopDeliveryElec
ShopDeliveryElectronicSheetPageVo vo = BeanUtil.toBean(item, ShopDeliveryElectronicSheetPageVo.class);
ShopDeliveryCompany company = companyMap.getOrDefault(item.getExpressCompanyId(), new ShopDeliveryCompany());
vo.setCompany(new ShopDeliveryElectronicSheetPageVo.Company(company.getCompanyName(), company.getExpressNoElectronicSheet()));
vo.setPayTypeName(ElectronicSheetPayTypeEnum.getPayTypeByType(item.getPayType()));
return vo;
}).collect(Collectors.toList());
return PageResult.build(page, limit, iPage.getTotal()).setData(list);
@ -185,6 +181,10 @@ public class ShopDeliveryElectronicSheetServiceImpl implements IShopDeliveryElec
model.setCreateTime(System.currentTimeMillis() / 1000);
model.setUpdateTime(System.currentTimeMillis() / 1000);
shopDeliveryElectronicSheetMapper.insert(model);
if (addParam.getIsDefault() == 1) {
setDefault(model.getId());
}
}
/**

View File

@ -33,6 +33,7 @@ public class ShopDeliveryElectronicSheetPageVo implements Serializable {
private String createTime; // 创建时间
private String updateTime; // 修改时间
private Company company;
private String payTypeName;
@NoArgsConstructor
@AllArgsConstructor

View File

@ -1,15 +1,8 @@
package com.niu.shop.service.admin.goods;
import com.niu.core.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.service.IService;
import com.niu.shop.entity.goods.ShopGoodsSku;
import com.niu.shop.entity.goods.ShopGoodsSpec;
import com.niu.shop.service.admin.goods.param.ShopGoodsServiceSearchParam;
import com.niu.shop.service.admin.goods.param.ShopGoodsSkuParam;
import com.niu.shop.service.admin.goods.param.ShopGoodsSkuSearchParam;
import com.niu.core.common.domain.PageParam;
import com.niu.shop.service.admin.goods.vo.ShopGoodsServiceListVo;
import com.niu.shop.service.admin.goods.vo.ShopGoodsSkuInfoVo;
import com.niu.shop.service.admin.goods.vo.ShopGoodsSkuListVo;
import com.niu.shop.service.api.goods.vo.ShopGoodsSkuVo;
import java.util.List;
@ -17,7 +10,7 @@ import java.util.List;
/**
* 商品规格服务接口
*/
public interface IShopGoodsSkuService {
public interface IShopGoodsSkuService extends IService<ShopGoodsSku> {
void insertAll(List<ShopGoodsSku> list);

View File

@ -866,7 +866,7 @@ public class ShopGoodsServiceImpl implements IShopGoodsService {
list.add(vo);
}
}
if (ObjectUtil.isNotEmpty(searchParam.getVerifySkuIds()) && ObjectUtil.isNotEmpty(searchParam.getSkuIds())) {
QueryWrapper<ShopGoodsSku> skuWrapper = new QueryWrapper<>();
skuWrapper.in("sku_id", searchParam.getSkuIds()).groupBy("goods_id").select("sku_id");

View File

@ -83,6 +83,7 @@ public class ShopVirtualGoodsServiceImpl implements IShopVirtualGoodsService {
sku.setSkuImage(model.getGoodsCover());
sku.setSalePrice(addParam.getPrice());
sku.setIsDefault(1);
sku.setSkuSpecFormat("");
skuData.add(sku);
} else {
if (addParam.getGoodsSkuData().keySet().size() == 0) throw new CommonException("请添加商品规格");

View File

@ -1,21 +1,24 @@
package com.niu.shop.service.admin.marketing;
import com.baomidou.mybatisplus.extension.service.IService;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.shop.entity.active.ShopActive;
import com.niu.shop.service.admin.marketing.param.ShopActiveParam;
import com.niu.shop.service.admin.marketing.param.ShopDiscountSearchParam;
import com.niu.core.common.domain.PageParam;
import com.niu.shop.service.admin.marketing.vo.ShopDiscountInfoVo;
import com.niu.shop.service.admin.marketing.vo.ShopDiscountListVo;
/**
* 店铺营销活动整体活动服务接口
*/
public interface IShopActiveService {
public interface IShopActiveService extends IService<ShopActive> {
/**
* 店铺营销活动整体活动列表
* @param pageParam 分页参数
*
* @param pageParam 分页参数
* @param searchParam 搜索参数
* @return PageResult<ShopActiveListVo>
*/
@ -23,6 +26,7 @@ public interface IShopActiveService {
/**
* 店铺营销活动整体活动详情
*
* @param id 主键ID
* @return ShopActiveInfoVo
*/
@ -30,19 +34,22 @@ public interface IShopActiveService {
/**
* 店铺营销活动整体活动添加
*
* @param addParam 添加参数
*/
void add(ShopActiveParam addParam);
/**
* 店铺营销活动整体活动编辑
* @param id 主键
*
* @param id 主键
* @param editParam 编辑参数
*/
void edit(Integer id, ShopActiveParam editParam);
/**
* 店铺营销活动整体活动删除
*
* @param id 主键ID
*/
void del(Integer id);

View File

@ -1,14 +0,0 @@
package com.niu.shop.service.admin.marketing;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSetConfigParam;
import com.niu.shop.service.admin.marketing.vo.ShopNewComerConfigVo;
/**
* 新人专享会员参与记录服务接口
*/
public interface IShopNewcomerMemberRecordsService {
void setConfig(ShopNewcomerSetConfigParam param);
ShopNewComerConfigVo getConfig();
}

View File

@ -0,0 +1,26 @@
package com.niu.shop.service.admin.marketing;
import com.niu.core.common.domain.PageParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectPageParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectSkuParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSetConfigParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerShopGoodsVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewComerSelectPageVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewcomerConfigVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewcomerSelectSkuVo;
import java.util.List;
/**
* 新人专享会员参与记录服务接口
*/
public interface IShopNewcomerService {
void setConfig(ShopNewcomerSetConfigParam param);
ShopNewcomerConfigVo getConfig();
ShopNewComerSelectPageVo<ShopNewcomerShopGoodsVo> getSelectPage(PageParam pageParam, ShopNewcomerSelectPageParam param);
List<ShopNewcomerSelectSkuVo> getSelectSku(ShopNewcomerSelectSkuParam param);
}

View File

@ -69,7 +69,7 @@ ICouponServiceImpl implements ICouponService {
JSONObject vo = new JSONObject();
JSONObject jsonObj = (JSONObject) json;
vo.put("value", jsonObj.getStr("category_id"));
vo.put("value", jsonObj.getInt("category_id"));
vo.put("label", jsonObj.getStr("category_name"));
if (jsonObj.getJSONArray("children") != null) {
JSONArray children = new JSONArray();
@ -77,7 +77,7 @@ ICouponServiceImpl implements ICouponService {
JSONObject childJsonObj = (JSONObject) child;
JSONObject childVo = new JSONObject();
childVo.put("value", childJsonObj.getStr("category_id"));
childVo.put("value", childJsonObj.getInt("category_id"));
childVo.put("label", childJsonObj.getStr("category_name"));
children.add(childVo);
});

View File

@ -3,18 +3,20 @@ package com.niu.shop.service.admin.marketing.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niu.core.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.shop.entity.active.ShopActive;
import com.niu.shop.mapper.active.ShopActiveMapper;
import com.niu.shop.service.admin.marketing.IShopActiveService;
import com.niu.shop.service.admin.marketing.param.ShopActiveParam;
import com.niu.shop.service.admin.marketing.param.ShopDiscountSearchParam;
import com.niu.shop.service.admin.marketing.IShopActiveService;
import com.niu.shop.service.admin.marketing.vo.ShopDiscountInfoVo;
import com.niu.shop.service.admin.marketing.vo.ShopDiscountListVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
@ -24,21 +26,22 @@ import java.util.List;
* 店铺营销活动整体活动实现
*/
@Service
public class ShopActiveServiceImpl implements IShopActiveService {
public class ShopActiveServiceImpl extends ServiceImpl<ShopActiveMapper, ShopActive> implements IShopActiveService {
@Resource
ShopActiveMapper shopActiveMapper;
/**
* 店铺营销活动整体活动列表
* @param pageParam 分页参数
*
* @param pageParam 分页参数
* @param searchParam 搜索参数
* @return PageResult<ShopActiveListVo>
*/
@Override
public PageResult<ShopDiscountListVo> list(PageParam pageParam, ShopDiscountSearchParam searchParam) {
Integer page = pageParam.getPage();
Integer limit =pageParam.getLimit();
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
QueryWrapper<ShopActive> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("active_id");
@ -55,6 +58,7 @@ public class ShopActiveServiceImpl implements IShopActiveService {
/**
* 店铺营销活动整体活动详情
*
* @param id 主键
* @return ShopActiveInfoVo
*/
@ -62,8 +66,8 @@ public class ShopActiveServiceImpl implements IShopActiveService {
public ShopDiscountInfoVo info(Integer id) {
ShopActive model = shopActiveMapper.selectOne(
new QueryWrapper<ShopActive>()
.eq("active_id", id)
.last("limit 1"));
.eq("active_id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在");
@ -74,6 +78,7 @@ public class ShopActiveServiceImpl implements IShopActiveService {
/**
* 店铺营销活动整体活动添加
*
* @param addParam 参数
*/
@Override
@ -110,8 +115,8 @@ public class ShopActiveServiceImpl implements IShopActiveService {
public void edit(Integer id, ShopActiveParam editParam) {
ShopActive model = shopActiveMapper.selectOne(
new QueryWrapper<ShopActive>()
.eq("active_id", id)
.last("limit 1"));
.eq("active_id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");
model.setActiveId(id);
@ -137,14 +142,15 @@ public class ShopActiveServiceImpl implements IShopActiveService {
/**
* 店铺营销活动整体活动删除
*
* @param id 主键ID
*/
@Override
public void del(Integer id) {
ShopActive model = shopActiveMapper.selectOne(
new QueryWrapper<ShopActive>()
.eq("active_id", id)
.last("limit 1"));
.eq("active_id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");

View File

@ -182,7 +182,7 @@ public class ShopDiscountServiceImpl implements IShopDiscountService {
);
int count = shopActiveGoodsMapper.selectJoinCount(wrapper);
if (count > 0) {
throw new AdminException("该商品已参加其他活动,请重新选择");
throw new AdminException("同一商品在一个时间段内只能参加一个限时折扣活动");
}
//数据添加
ShopActive activeModel = new ShopActive();
@ -282,28 +282,24 @@ public class ShopDiscountServiceImpl implements IShopDiscountService {
);
int count = shopActiveGoodsMapper.selectJoinCount(wrapper);
if (count > 0) {
throw new AdminException("该商品已参加其他活动,请重新选择");
throw new AdminException("同一商品在一个时间段内只能参加一个限时折扣活动");
}
//数据添加
ShopActive activeModel = new ShopActive();
activeModel.setSiteId(RequestUtils.siteId());
ShopActive activeModel = shopActiveMapper.selectOne(new QueryWrapper<ShopActive>().eq("active_id", id).eq("site_id", RequestUtils.siteId()));
Assert.notNull(activeModel, "活动不存在");
activeModel.setActiveName(shopDiscountParam.getActiveName());
activeModel.setActiveDesc(shopDiscountParam.getActiveDesc());
activeModel.setActiveType(ActiveTypeEnum.GOODS.getType());
activeModel.setActiveGoodsType(ActiveGoodsTypeEnum.GOODS_SINGLE.getType());
activeModel.setActiveGoodsInfo(shopDiscountParam.getGoodsData());
activeModel.setActiveClass("discount");
activeModel.setActiveClassCategory("discount");
activeModel.setActiveStatus(ActiveStatusEnum.NOT_ACTIVE.getStatus());
activeModel.setStartTime(DateUtils.StringToTimestamp(shopDiscountParam.getStartTime()));
activeModel.setEndTime(DateUtils.StringToTimestamp(shopDiscountParam.getEndTime()));
activeModel.setCreateTime(System.currentTimeMillis() / 1000);
//商品添加
activeModel.setUpdateTime(System.currentTimeMillis() / 1000);
List<ShopActiveGoods> activeGoodsList = new ArrayList<>();
for (int i = 0; i < goodsList.size(); i++) {
JSONObject goods = goodsList.getJSONObject(i);
ShopActiveGoods activeGoods = new ShopActiveGoods();
activeGoods.setActiveId(id);
activeGoods.setGoodsId(goods.getInt("goods_id"));
activeGoods.setSiteId(RequestUtils.siteId());
activeGoods.setActiveClass("discount");
@ -325,7 +321,7 @@ public class ShopDiscountServiceImpl implements IShopDiscountService {
}
activeGoodsList.add(activeGoods);
}
coreActiveService.add(activeModel, activeGoodsList);
coreActiveService.edit(activeModel, activeGoodsList);
}
/**

View File

@ -1,29 +0,0 @@
package com.niu.shop.service.admin.marketing.impl;
import com.niu.shop.mapper.newconsumer.ShopNewcomerMemberRecordsMapper;
import com.niu.shop.service.admin.marketing.IShopNewcomerMemberRecordsService;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSetConfigParam;
import com.niu.shop.service.admin.marketing.vo.ShopNewComerConfigVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* 新人专享会员参与记录实现
*/
@Service
@RequiredArgsConstructor
public class ShopNewcomerMemberRecordsServiceImpl implements IShopNewcomerMemberRecordsService {
private final ShopNewcomerMemberRecordsMapper shopNewcomerMemberRecordsMapper;
@Override
public void setConfig(ShopNewcomerSetConfigParam param) {
}
@Override
public ShopNewComerConfigVo getConfig() {
return null;
}
}

View File

@ -0,0 +1,448 @@
package com.niu.shop.service.admin.marketing.impl;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.common.utils.date.DateUtils;
import com.niu.core.enums.upload.UploadThumbTypeEnum;
import com.niu.core.service.core.sys.ICoreUploadService;
import com.niu.shop.entity.active.ShopActive;
import com.niu.shop.entity.active.ShopActiveGoods;
import com.niu.shop.entity.goods.ShopGoods;
import com.niu.shop.entity.goods.ShopGoodsSku;
import com.niu.shop.enums.active.ActiveClassEnum;
import com.niu.shop.enums.active.ActiveGoodsTypeEnum;
import com.niu.shop.enums.active.ActiveStatusEnum;
import com.niu.shop.enums.active.ActiveTypeEnum;
import com.niu.shop.enums.goods.GoodsTypeEnum;
import com.niu.shop.mapper.active.ShopActiveGoodsMapper;
import com.niu.shop.mapper.active.ShopActiveMapper;
import com.niu.shop.mapper.goods.ShopGoodsMapper;
import com.niu.shop.mapper.goods.ShopGoodsSkuMapper;
import com.niu.shop.service.admin.marketing.IShopNewcomerService;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectPageParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSelectSkuParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerSetConfigParam;
import com.niu.shop.service.admin.marketing.param.ShopNewcomerShopGoodsVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewComerSelectPageVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewcomerConfigVo;
import com.niu.shop.service.admin.marketing.vo.ShopNewcomerSelectSkuVo;
import com.niu.shop.service.core.marketing.ICoreActiveService;
import com.niu.shop.service.core.marketing.ICoreShopNewcomerService;
import com.niu.shop.service.core.marketing.model.ShopNewcomerActiveValue;
import com.niu.shop.service.core.marketing.model.ShopNewcomerGoodsData;
import com.niu.shop.service.core.marketing.vo.CoreShopNewcomerConfigVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* 新人专享会员参与记录实现
*/
@Service
@RequiredArgsConstructor
public class ShopNewcomerServiceImpl implements IShopNewcomerService {
private final ShopGoodsMapper shopGoodsMapper;
private final ShopActiveMapper shopActiveMapper;
private final ICoreActiveService coreActiveService;
private final ICoreUploadService coreUploadService;
private final ShopGoodsSkuMapper shopGoodsSkuMapper;
private final ShopActiveGoodsMapper shopActiveGoodsMapper;
private final ICoreShopNewcomerService coreShopNewcomerService;
@Override
@Transactional
public void setConfig(ShopNewcomerSetConfigParam param) {
List<ShopNewcomerGoodsData> goodsDataList = JSONArray.parseArray(param.getGoodsData(), ShopNewcomerGoodsData.class);
if (ActiveStatusEnum.ACTIVE.equals(ActiveStatusEnum.getEnumByStatus(param.getActiveStatus()))) {
checkGoods(goodsDataList);
}
ShopNewcomerActiveValue activeValue = new ShopNewcomerActiveValue();
activeValue.setValidityType(param.getValidityType());
activeValue.setValidityDay(param.getValidityDay());
activeValue.setValidityTime(ObjectUtil.isEmpty(param.getValidityTime()) ? 0 : DateUtils.StringToTimestamp(param.getValidityTime()));
activeValue.setParticipationWay(param.getParticipationWay());
activeValue.setAppointTime(ObjectUtil.isEmpty(param.getAppointTime()) ? 0 : DateUtils.StringToTimestamp(param.getAppointTime()));
activeValue.setLimitNum(param.getLimitNum());
activeValue.setBannerList(param.getBannerList());
List<ShopActiveGoods> activeGoods = new ArrayList<>(CollectionUtil.size(goodsDataList));
for (ShopNewcomerGoodsData goodsData : goodsDataList) {
ShopActiveGoods goods = new ShopActiveGoods();
goods.setSiteId(RequestUtils.siteId());
goods.setGoodsId(goodsData.getGoodsId());
goods.setActiveGoodsType(ActiveGoodsTypeEnum.GOODS_SINGLE.getType());
goods.setActiveClass(ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
goods.setActiveGoodsValue(JSON.toJSONString(goodsData));
goods.setSkuId(goodsData.getSkuId());
goods.setActiveGoodsStatus(param.getActiveStatus());
goods.setActiveGoodsPrice(NumberUtil.toBigDecimal(goodsData.getNewcomerPrice()));
activeGoods.add(goods);
}
LambdaQueryWrapper<ShopActive> activeLambdaQueryWrapper = new LambdaQueryWrapper<>();
activeLambdaQueryWrapper.eq(ShopActive::getSiteId, RequestUtils.siteId())
.eq(ShopActive::getActiveClass, ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
ShopActive active = shopActiveMapper.selectOne(activeLambdaQueryWrapper);
if (ObjectUtil.isEmpty(active)) {
ShopActive shopActive = new ShopActive();
shopActive.setActiveDesc(param.getActiveDesc());
shopActive.setSiteId(RequestUtils.siteId());
shopActive.setActiveGoodsInfo(param.getGoodsData());
shopActive.setActiveType(ActiveTypeEnum.GOODS.getType());
shopActive.setActiveGoodsType(ActiveGoodsTypeEnum.GOODS_SINGLE.getType());
shopActive.setActiveClass(ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
shopActive.setActiveValue(JSON.toJSONString(activeValue));
shopActive.setActiveStatus(param.getActiveStatus());
coreActiveService.add(shopActive, activeGoods);
return;
}
active.setSiteId(RequestUtils.siteId());
active.setActiveStatus(param.getActiveStatus());
active.setActiveDesc(param.getActiveDesc());
active.setActiveGoodsInfo(param.getGoodsData());
active.setActiveType(ActiveTypeEnum.GOODS.getType());
active.setActiveGoodsType(ActiveGoodsTypeEnum.GOODS_SINGLE.getType());
active.setActiveClass(ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
active.setActiveValue(JSON.toJSONString(activeValue));
activeGoods.forEach(goods -> goods.setActiveId(active.getActiveId()));
coreActiveService.edit(active, activeGoods);
}
@Override
public ShopNewcomerConfigVo getConfig() {
CoreShopNewcomerConfigVo config = coreShopNewcomerService.getConfig(RequestUtils.siteId());
ShopNewcomerConfigVo vo = new ShopNewcomerConfigVo();
BeanUtils.copyProperties(config, vo);
if (ObjectUtil.isEmpty(config)) {
return vo;
}
LambdaQueryWrapper<ShopActiveGoods> shopActiveGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopActiveGoodsLambdaQueryWrapper.eq(ShopActiveGoods::getSiteId, RequestUtils.siteId())
.eq(ShopActiveGoods::getActiveId, config.getActiveId())
.eq(ShopActiveGoods::getActiveClass, ActiveClassEnum.NEWCOMER_DISCOUNT.getType());
List<ShopActiveGoods> shopActiveGoods = shopActiveGoodsMapper.selectList(shopActiveGoodsLambdaQueryWrapper);
Set<Integer> goodsIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getGoodsId);
Map<Integer, ShopGoods> goodsMap = Collections.emptyMap();
if (ObjectUtil.isNotEmpty(goodsIds)) {
goodsMap = shopGoodsMapper.selectBatchIds(goodsIds).stream().collect(Collectors.toMap(ShopGoods::getGoodsId, e -> e));
}
Set<Integer> skuIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getSkuId);
Map<Integer, ShopGoodsSku> skuMap = Collections.emptyMap();
if (ObjectUtil.isNotEmpty(skuIds)) {
skuMap = shopGoodsSkuMapper.selectBatchIds(skuIds).stream().collect(Collectors.toMap(ShopGoodsSku::getSkuId, e -> e));
}
List<ShopNewcomerConfigVo.ActiveGoods> activeGoodsList = new ArrayList<>(shopActiveGoods.size());
for (ShopActiveGoods shopActiveGood : shopActiveGoods) {
ShopGoods goods = goodsMap.getOrDefault(shopActiveGood.getGoodsId(), new ShopGoods());
ShopGoodsSku sku = skuMap.getOrDefault(shopActiveGood.getSkuId(), new ShopGoodsSku());
ShopNewcomerConfigVo.ActiveGoods activeGoods = new ShopNewcomerConfigVo.ActiveGoods();
activeGoods.setGoodsId(shopActiveGood.getGoodsId());
activeGoods.setSkuId(shopActiveGood.getSkuId());
activeGoods.setGoodsName(goods.getGoodsName());
activeGoods.setGoodsType(goods.getGoodsType());
activeGoods.setGoodsTypeName(GoodsTypeEnum.getNameByType(goods.getGoodsType()));
activeGoods.setSkuName(sku.getSkuName());
activeGoods.setSkuImage(sku.getSkuImage());
activeGoods.setPrice(sku.getPrice());
activeGoods.setStock(sku.getStock());
if (shopActiveGood.getActiveGoodsValue().startsWith("[")) {
activeGoods.setActiveGoodsValue(JSONUtil.parseArray(shopActiveGood.getActiveGoodsValue()));
} else {
activeGoods.setActiveGoodsValue(JSONUtil.parseObj(shopActiveGood.getActiveGoodsValue()));
}
ShopNewcomerConfigVo.Goods goodsData = new ShopNewcomerConfigVo.Goods();
BeanUtils.copyProperties(goods, goodsData);
goodsData.setGoodsTypeName(GoodsTypeEnum.getNameByType(goods.getGoodsType()));
activeGoods.setGoods(goodsData);
ShopNewcomerConfigVo.GoodsSkuOne goodsSkuOne = new ShopNewcomerConfigVo.GoodsSkuOne();
BeanUtils.copyProperties(sku, goodsSkuOne);
activeGoods.setGoodsSkuOne(goodsSkuOne);
activeGoodsList.add(activeGoods);
}
vo.setActiveGoods(activeGoodsList);
return vo;
}
@Override
public ShopNewComerSelectPageVo<ShopNewcomerShopGoodsVo> getSelectPage(PageParam pageParam, ShopNewcomerSelectPageParam param) {
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
LambdaQueryWrapper<ShopActiveGoods> shopActiveGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopActiveGoodsLambdaQueryWrapper.eq(ShopActiveGoods::getSiteId, RequestUtils.siteId())
.eq(ShopActiveGoods::getActiveClass, ActiveClassEnum.NEWCOMER_DISCOUNT.getType())
.eq(ShopActiveGoods::getActiveGoodsStatus, ActiveStatusEnum.ACTIVE.getStatus());
List<ShopActiveGoods> shopActiveGoods = shopActiveGoodsMapper.selectList(shopActiveGoodsLambdaQueryWrapper);
Set<Integer> activeGoodsIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getGoodsId);
Set<Integer> activeSkuIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getSkuId);
LambdaQueryWrapper<ShopGoods> shopGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsLambdaQueryWrapper.eq(ShopGoods::getGoodsCategory, param.getGoodsCategory())
.eq(ShopGoods::getGoodsType, param.getGoodsType())
.eq(ShopGoods::getSiteId, RequestUtils.siteId())
.orderByDesc(ShopGoods::getSort)
.orderByDesc(ShopGoods::getCreateTime);
if (ObjectUtil.isNotEmpty(param.getKeyword())) {
shopGoodsLambdaQueryWrapper.and(wrapper ->
wrapper.like(ShopGoods::getGoodsName, param.getKeyword()).or().like(ShopGoods::getSubTitle, param.getKeyword()));
}
switch (param.getSelectType()) {
case "all":
shopGoodsLambdaQueryWrapper.gt(ShopGoods::getStock, 0)
.in(ShopGoods::getGoodsId, activeGoodsIds)
.eq(ShopGoods::getStatus, 1);
break;
case "selected":
shopGoodsLambdaQueryWrapper.in(ShopGoods::getGoodsId, param.getGoodsIds());
break;
}
Page<ShopGoods> iPage = shopGoodsMapper.selectPage(new Page<>(page, limit), shopGoodsLambdaQueryWrapper);
Set<Integer> goodsIds = CollStreamUtil.toSet(iPage.getRecords(), ShopGoods::getGoodsId);
LambdaQueryWrapper<ShopGoodsSku> shopGoodsSkuLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsSkuLambdaQueryWrapper.eq(ShopGoodsSku::getIsDefault, 1)
.eq(ShopGoodsSku::getSkuId, activeSkuIds)
.in(ShopGoodsSku::getGoodsId, goodsIds);
Map<Integer, List<ShopGoodsSku>> skuMap = shopGoodsSkuMapper.selectList(shopGoodsSkuLambdaQueryWrapper)
.stream()
.collect(Collectors.groupingBy(ShopGoodsSku::getGoodsId));
Map<Integer, ShopActiveGoods> activeGoodsMap = shopActiveGoods
.stream()
.collect(Collectors.toMap(ShopActiveGoods::getSkuId, e -> e));
List<ShopNewcomerShopGoodsVo> voList = new ArrayList<>(iPage.getRecords().size());
for (ShopGoods record : iPage.getRecords()) {
ShopNewcomerShopGoodsVo vo = new ShopNewcomerShopGoodsVo();
BeanUtils.copyProperties(record, vo);
List<ShopGoodsSku> skus = skuMap.getOrDefault(record.getGoodsId(), new ArrayList<>());
List<ShopNewcomerShopGoodsVo.GoodsSku> skuList = new ArrayList<>(skus.size());
for (ShopGoodsSku sku : skus) {
ShopActiveGoods activeGoods = activeGoodsMap.get(sku.getSkuId());
ShopNewcomerShopGoodsVo.GoodsSku skuVo = new ShopNewcomerShopGoodsVo.GoodsSku();
BeanUtils.copyProperties(sku, skuVo);
JSONObject activeGoodsValue = JSON.parseObject(activeGoods.getActiveGoodsValue());
BigDecimal newcomerPrice = Optional.ofNullable(activeGoodsValue.getBigDecimal("newcomer_price")).orElse(BigDecimal.ZERO);
skuVo.setNewcomerPrice(newcomerPrice);
skuList.add(skuVo);
if (sku.getIsDefault() == 1) {
if (!activeSkuIds.contains(sku.getSkuId())) {
skuVo.setNewcomerPrice(skuList.get(0).getNewcomerPrice());
}
vo.setGoodsSku(skuVo);
}
}
vo.setSkuList(skuList);
voList.add(vo);
}
ShopNewComerSelectPageVo<ShopNewcomerShopGoodsVo> vo = new ShopNewComerSelectPageVo<>(iPage, voList);
if (ObjectUtil.hasEmpty(param.getVerifySkuIds(), activeSkuIds)) {
return vo;
}
List<Integer> verifyGoodsId = Collections.emptyList();
if (ObjectUtil.isAllNotEmpty(param.getVerifyGoodsIds(), activeGoodsIds)) {
LambdaQueryWrapper<ShopGoods> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ShopGoods::getGoodsId, param.getVerifyGoodsIds())
.eq(ShopGoods::getStatus, 1);
verifyGoodsId = shopGoodsMapper.selectList(queryWrapper)
.stream()
.map(ShopGoods::getGoodsId)
.filter(activeGoodsIds::contains)
.collect(Collectors.toList());
}
List<Integer> verifySkuIds = Collections.emptyList();
if (ObjectUtil.isAllNotEmpty(param.getVerifyGoodsIds(), activeSkuIds)) {
LambdaQueryWrapper<ShopGoodsSku> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(ShopGoodsSku::getSkuId, param.getVerifySkuIds());
verifySkuIds = shopGoodsSkuMapper.selectList(queryWrapper)
.stream()
.map(ShopGoodsSku::getSkuId)
.filter(activeSkuIds::contains)
.collect(Collectors.toList());
}
return vo.setVerifyGoodsIds(verifyGoodsId)
.setVerifySkuIds(verifySkuIds);
}
@Override
public List<ShopNewcomerSelectSkuVo> getSelectSku(ShopNewcomerSelectSkuParam param) {
LambdaQueryWrapper<ShopActiveGoods> shopActiveGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopActiveGoodsLambdaQueryWrapper.eq(ShopActiveGoods::getSiteId, RequestUtils.siteId())
.eq(ShopActiveGoods::getActiveClass, ActiveClassEnum.NEWCOMER_DISCOUNT.getType())
.eq(ShopActiveGoods::getActiveGoodsStatus, ActiveStatusEnum.ACTIVE.getStatus());
List<ShopActiveGoods> shopActiveGoods = shopActiveGoodsMapper.selectList(shopActiveGoodsLambdaQueryWrapper);
Set<Integer> activeGoodsIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getGoodsId);
Set<Integer> activeSkuIds = CollStreamUtil.toSet(shopActiveGoods, ShopActiveGoods::getSkuId);
// 检测商品id集合是否存在移除不存在的商品id纠正数据准确性
List<ShopNewcomerSelectSkuVo> list = new LinkedList<>();
if (ObjectUtil.isAllNotEmpty(param.getVerifyGoodsIds(), activeGoodsIds)) {
LambdaQueryWrapper<ShopGoods> shopGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsLambdaQueryWrapper.in(ShopGoods::getGoodsId, param.getVerifyGoodsIds())
.eq(ShopGoods::getStatus, 1);
List<Integer> verifyGoodsIds = shopGoodsMapper.selectList(shopGoodsLambdaQueryWrapper)
.stream()
.map(ShopGoods::getGoodsId)
.filter(activeGoodsIds::contains)
.collect(Collectors.toList());
shopGoodsLambdaQueryWrapper.clear();
shopGoodsLambdaQueryWrapper.in(ShopGoods::getGoodsId, verifyGoodsIds)
.orderByDesc(ShopGoods::getSort)
.orderByDesc(ShopGoods::getCreateTime);
List<ShopGoods> shopGoods = shopGoodsMapper.selectList(shopGoodsLambdaQueryWrapper);
Set<Integer> goodsIds = CollStreamUtil.toSet(shopGoods, ShopGoods::getGoodsId);
LambdaQueryWrapper<ShopGoodsSku> shopGoodsSkuLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsSkuLambdaQueryWrapper.in(ShopGoodsSku::getGoodsId, goodsIds);
Map<Integer, List<ShopGoodsSku>> skuMap = shopGoodsSkuMapper.selectList(shopGoodsSkuLambdaQueryWrapper)
.stream()
.collect(Collectors.groupingBy(ShopGoodsSku::getGoodsId));
for (ShopGoods shopGood : shopGoods) {
ShopNewcomerSelectSkuVo vo = new ShopNewcomerSelectSkuVo();
BeanUtils.copyProperties(shopGood, vo);
vo.setGoodsTypeName(GoodsTypeEnum.getNameByType(shopGood.getGoodsType()));
vo.setGoodsCoverThumbSmall(coreUploadService.thumb(RequestUtils.siteId(), shopGood.getGoodsCover(), UploadThumbTypeEnum.SMALL.getType()).getDataMap().get(UploadThumbTypeEnum.SMALL.getType()));
vo.setGoodsCoverThumbMid(coreUploadService.thumb(RequestUtils.siteId(), shopGood.getGoodsCover(), UploadThumbTypeEnum.MID.getType()).getDataMap().get(UploadThumbTypeEnum.MID.getType()));
List<ShopGoodsSku> shopGoodsSkuList = skuMap.getOrDefault(shopGood.getGoodsId(), new ArrayList<>());
List<ShopNewcomerSelectSkuVo.Sku> skuList = new ArrayList<>(shopGoodsSkuList.size());
for (ShopGoodsSku sku : shopGoodsSkuList) {
ShopNewcomerSelectSkuVo.Sku skuVo = new ShopNewcomerSelectSkuVo.Sku();
BeanUtils.copyProperties(sku, skuVo);
JSONObject activeGoodsValue = JSON.parseObject(shopActiveGoods.get(sku.getSkuId()).getActiveGoodsValue());
skuVo.setNewcomerPrice(Optional.ofNullable(activeGoodsValue.getBigDecimal("newcomer_price")).orElse(BigDecimal.ZERO));
if (sku.getIsDefault() == 1) {
if (!activeSkuIds.contains(sku.getSkuId())) {
skuVo.setNewcomerPrice(skuList.get(0).getNewcomerPrice());
}
vo.setGoodsSku(skuVo);
}
skuList.add(skuVo);
}
list.add(vo);
}
}
// 检测商品id集合是否存在移除不存在的商品id纠正数据准确性
if (ObjectUtil.isAllNotEmpty(param.getVerifySkuIds(), activeSkuIds)) {
LambdaQueryWrapper<ShopGoodsSku> shopGoodsSkuLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsSkuLambdaQueryWrapper.in(ShopGoodsSku::getSkuId, param.getVerifySkuIds());
List<ShopGoodsSku> skus = shopGoodsSkuMapper.selectList(shopGoodsSkuLambdaQueryWrapper)
.stream()
.filter(sku -> activeSkuIds.contains(sku.getSkuId()))
.collect(Collectors.toList());
Set<Integer> skuIds = CollStreamUtil.toSet(skus, ShopGoodsSku::getSkuId);
shopGoodsSkuLambdaQueryWrapper.clear();
shopGoodsSkuLambdaQueryWrapper.in(ShopGoodsSku::getSkuId, skuIds);
Set<Integer> goodsIds = shopGoodsSkuMapper.selectList(shopGoodsSkuLambdaQueryWrapper)
.stream()
.map(ShopGoodsSku::getGoodsId)
.collect(Collectors.toSet());
LambdaQueryWrapper<ShopGoods> shopGoodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
shopGoodsLambdaQueryWrapper.in(ShopGoods::getGoodsId, goodsIds)
.orderByDesc(ShopGoods::getSort)
.orderByDesc(ShopGoods::getCreateTime);
List<ShopGoods> shopGoods = shopGoodsMapper.selectList(shopGoodsLambdaQueryWrapper);
shopGoodsSkuLambdaQueryWrapper.clear();
shopGoodsSkuLambdaQueryWrapper.in(ShopGoodsSku::getSkuId, skuIds)
.in(ShopGoodsSku::getGoodsId, CollStreamUtil.toSet(shopGoods, ShopGoods::getGoodsId));
Map<Integer, List<ShopGoodsSku>> goodsSkuMap = shopGoodsSkuMapper.selectList(shopGoodsSkuLambdaQueryWrapper)
.stream()
.collect(Collectors.groupingBy(ShopGoodsSku::getGoodsId));
Map<Integer, ShopActiveGoods> shopActiveGoodsMap = shopActiveGoods.stream().collect(Collectors.toMap(ShopActiveGoods::getSkuId, e -> e));
for (ShopGoods shopGood : shopGoods) {
ShopNewcomerSelectSkuVo vo = new ShopNewcomerSelectSkuVo();
BeanUtils.copyProperties(shopGood, vo);
List<ShopGoodsSku> skuList = goodsSkuMap.get(shopGood.getGoodsId());
if (ObjectUtil.hasEmpty(skus, shopActiveGoods)) {
continue;
}
List<ShopNewcomerSelectSkuVo.Sku> skuVoList = new ArrayList<>(skuList.size());
for (ShopGoodsSku sku : skuList) {
ShopNewcomerSelectSkuVo.Sku skuVo = new ShopNewcomerSelectSkuVo.Sku();
BeanUtils.copyProperties(sku, skuVo);
ShopActiveGoods activeGoods = shopActiveGoodsMap.get(sku.getSkuId());
JSONObject activeGoodsValue = JSON.parseObject(activeGoods.getActiveGoodsValue());
skuVo.setNewcomerPrice(Optional.ofNullable(activeGoodsValue.getBigDecimal("newcomer_price")).orElse(BigDecimal.ZERO));
if (sku.getIsDefault() == 1) {
skuVo.setNewcomerPrice(skuVoList.get(0).getNewcomerPrice());
}
skuVoList.add(skuVo);
}
list.add(vo);
}
}
return list;
}
private void checkGoods(List<ShopNewcomerGoodsData> goodsData) {
if (ObjectUtil.isEmpty(goodsData)) {
throw new RuntimeException("请选择参与活动商品");
}
for (ShopNewcomerGoodsData goods : goodsData) {
if (ObjectUtil.isEmpty(goods)) {
throw new RuntimeException("商品规格不能为空");
}
if (ObjectUtil.isEmpty(goods.getNewcomerPrice())) {
throw new RuntimeException("新人价不能为空");
}
}
}
}

View File

@ -84,14 +84,15 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
/**
* 积分兑换列表
* @param pageParam 分页参数
*
* @param pageParam 分页参数
* @param searchParam 搜索参数
* @return PageResult<ShopPointExchangeListVo>
*/
@Override
public PageResult<ShopPointExchangeListVo> list(PageParam pageParam, ShopPointExchangeSearchParam searchParam) {
Integer page = pageParam.getPage();
Integer limit =pageParam.getLimit();
Integer page = pageParam.getPage();
Integer limit = pageParam.getLimit();
QueryWrapper<ShopPointExchange> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("site_id", RequestUtils.siteId());
@ -119,8 +120,11 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
vo.setType(ShopPointExchangeTypeEnum.getNameByType(item.getType()));
vo.setStatusName(ShopPointExchangeStatusEnum.getNameByStatus(item.getStatus()));
vo.setGoodsCoverThumbBig(coreUploadService.thumb(RequestUtils.siteId(), vo.getImage(), UploadThumbTypeEnum.BIG.getType()).getDataMap().get(UploadThumbTypeEnum.SMALL.getType()));
vo.setGoodsCoverThumbSmall(coreUploadService.thumb(RequestUtils.siteId(), vo.getImage(), UploadThumbTypeEnum.SMALL.getType()).getDataMap().get(UploadThumbTypeEnum.SMALL.getType()));
if (ObjectUtil.isNotEmpty(vo.getImage())) {
String image = vo.getImage().split(",")[0];
vo.setGoodsCoverThumbBig(coreUploadService.thumb(RequestUtils.siteId(), image, UploadThumbTypeEnum.BIG.getType()).getDataMap().get(UploadThumbTypeEnum.SMALL.getType()));
vo.setGoodsCoverThumbSmall(coreUploadService.thumb(RequestUtils.siteId(), image, UploadThumbTypeEnum.SMALL.getType()).getDataMap().get(UploadThumbTypeEnum.SMALL.getType()));
}
vo.setCreateTime(DateUtils.timestampToString(item.getCreateTime()));
vo.setUpdateTime(DateUtils.timestampToString(item.getUpdateTime()));
@ -131,6 +135,7 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
/**
* 积分兑换详情
*
* @param id 主键
* @return ShopPointExchangeInfoVo
*/
@ -155,9 +160,8 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
// --- goods list ---
QueryWrapper<ShopGoodsSku> shopGoodsSkuQueryWrapper = new QueryWrapper<>();
shopGoodsSkuQueryWrapper.eq("site_id", RequestUtils.siteId());
shopGoodsSkuQueryWrapper.eq("goods_id", productDetail.getGoodsId());
shopGoodsSkuQueryWrapper.select("sku_spec_format,sku_id,site_id,sku_name,sku_image,sku_no,price as goods_price,stock as goods_stock");
shopGoodsSkuQueryWrapper.eq("site_id", RequestUtils.siteId())
.eq("goods_id", productDetail.getGoodsId());
List<ShopGoodsSku> shopGoodsSkus = shopGoodsSkuMapper.selectList(shopGoodsSkuQueryWrapper);
List<ShopPointExchangeInfoVo.GoodsSku> goodsList = shopGoodsSkus.stream()
@ -210,6 +214,7 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
/**
* 积分兑换添加
*
* @param addParam 参数
*/
@Override
@ -293,6 +298,7 @@ public class ShopPointExchangeServiceImpl implements IShopPointExchangeService {
/**
* 积分兑换删除
*
* @param id 主键ID
*/
@Override

View File

@ -0,0 +1,17 @@
package com.niu.shop.service.admin.marketing.param;
import lombok.Data;
import java.util.List;
@Data
public class ShopNewcomerSelectPageParam {
private String keyword;
private String goodsCategory;
private String goodsType;
private String selectType;
private List<Integer> goodsIds;
private List<Integer> skuIds;
private List<Integer> verifyGoodsIds;
private List<Integer> verifySkuIds;
}

View File

@ -0,0 +1,15 @@
package com.niu.shop.service.admin.marketing.param;
import lombok.Data;
import java.util.List;
@Data
public class ShopNewcomerSelectSkuParam {
private String keyword;
private String goodsCategory;
private String goodsType;
private List<Integer> goodsIds;
private List<Integer> verifyGoodsIds;
private List<Integer> verifySkuIds;
}

View File

@ -1,5 +1,6 @@
package com.niu.shop.service.admin.marketing.param;
import com.niu.shop.service.core.marketing.model.ShopNewcomerBannerList;
import lombok.Data;
import java.util.List;
@ -15,16 +16,5 @@ public class ShopNewcomerSetConfigParam {
private String participationWay;
private String appointTime;
private Integer limitNum;
private List<BannerList> bannerList;
@Data
public static class BannerList {
private String imageUrl;
private ToLink toLink;
@Data
public static class ToLink {
private String name;
}
}
private List<ShopNewcomerBannerList> bannerList;
}

View File

@ -0,0 +1,74 @@
package com.niu.shop.service.admin.marketing.param;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ShopNewcomerShopGoodsVo {
private Integer goodsId; // 商品id
private Integer siteId; // 站点id
private String goodsName; // 商品名称
private String goodsType; // 商品类型
private String goodsTypeName;
private String goodsCoverThumbSmall;
private String goodsCoverThumbMid;
private String subTitle; // 副标题
private String goodsCover; // 商品封面
private String goodsImage; // 商品图片
private String goodsCategory; // 商品分类
private String goodsDesc; // 商品介绍
private Integer brandId; // 商品品牌id
private String labelIds; // 标签组
private String serviceIds; // 商品服务
private String unit; // 单位
private Integer stock; // 商品库存总和
private Integer saleNum; // 销量
private Integer virtualSaleNum; // 虚拟销量
private Integer status; // 商品状态1.正常0下架
private Integer sort; // 排序
private String deliveryType; // 支持的配送方式
private Integer isFreeShipping; // 是否免邮
private String feeType; // 运费设置选择模板template固定运费fixed
private BigDecimal deliveryMoney; // 固定运费
private Integer deliveryTemplateId; // 运费模板
private Integer virtualAutoDelivery; // 虚拟商品是否自动发货
private String virtualReceiveType; // 虚拟商品收货方式auto自动收货artificial买家确认收货verify到店核销
private Integer virtualVerifyType; // 虚拟商品核销有效期类型0不限1购买后几日有效2指定过期日期
private Integer virtualIndate; // 虚拟到期时间
private Integer supplierId; // 供应商id
private Integer attrId; // 商品参数id
private String attrFormat; // 商品参数内容json格式
private Integer isDiscount; // 是否参与限时折扣
private String memberDiscount; // 会员等级折扣不参与会员折扣discount指定会员价fixed_price
private Integer posterId; // 海报id
private Long createTime; // 创建时间
private Long updateTime; // 修改时间
private GoodsSku goodsSku;
private List<GoodsSku> skuList;
@Data
public static class GoodsSku {
private Integer skuId; // 商品sku_id
private Integer siteId; // 站点id
private String skuName; // 商品sku名称
private String skuImage; // sku主图
private String skuNo; // 商品sku编码
private Integer goodsId; // 商品id
private String skuSpecFormat; // sku规格格式
private BigDecimal price; // sku单价
private BigDecimal marketPrice; // 划线价
private BigDecimal salePrice; // 实际卖价有活动显示活动价默认原价
private BigDecimal costPrice; // sku成本价
private Integer stock; // 商品sku库存
private BigDecimal weight; // 重量单位kg
private BigDecimal volume; // 体积单位立方米
private Integer saleNum; // 销量
private Integer isDefault; // 是否默认
private String memberPrice; // 会员价json格式指定会员价数据结构为{"level_1":"10.00","level_2":"10.00"}
private BigDecimal newcomerPrice;
}
}

View File

@ -1,30 +1,82 @@
package com.niu.shop.service.admin.marketing.vo;
import cn.hutool.json.JSON;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.niu.shop.service.core.marketing.model.ShopNewcomerBannerList;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ShopNewComerConfigVo {
public class ShopNewcomerConfigVo {
private Integer activeId;
private String activeStatus;
private String activeDesc;
private String goodsData;
private String validityType;
private Integer validityDay;
private String validityTime;
private String participationWay;
private String appointTime;
private Integer limitNum;
private List<BannerList> bannerList;
private List<ShopNewcomerBannerList> bannerList;
private List<ActiveGoods> activeGoods;
@Data
public static class BannerList {
private String imageUrl;
private ToLink toLink;
public static class ActiveGoods {
@JsonProperty("goods_id")
private Integer goodsId;
@JsonProperty("goods_name")
private String goodsName;
@JsonProperty("goods_type")
private String goodsType;
@JsonProperty("goods_type_name")
private String goodsTypeName;
@JsonProperty("sku_name")
private String skuName;
@JsonProperty("sku_id")
private Integer skuId;
@JsonProperty("sku_image")
private String skuImage;
private BigDecimal price;
private Integer stock;
@JsonProperty("active_goods_value")
private JSON activeGoodsValue;
private Goods goods;
@JsonProperty("goodsSkuOne")
private GoodsSkuOne goodsSkuOne;
}
@Data
public static class ToLink {
private String name;
}
@NoArgsConstructor
@Data
public static class Goods {
@JsonProperty("goods_type_name")
private String goodsTypeName;
@JsonProperty("goods_id")
private Integer goodsId;
@JsonProperty("goods_name")
private String goodsName;
@JsonProperty("goods_type")
private String goodsType;
}
@NoArgsConstructor
@Data
public static class GoodsSkuOne {
@JsonProperty("sku_id")
private Integer skuId;
@JsonProperty("sku_name")
private String skuName;
@JsonProperty("sku_image")
private String skuImage;
@JsonProperty("goods_id")
private Integer goodsId;
@JsonProperty("price")
private BigDecimal price;
@JsonProperty("stock")
private Integer stock;
}
}

View File

@ -0,0 +1,21 @@
package com.niu.shop.service.admin.marketing.vo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niu.core.common.domain.PageResult;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class ShopNewComerSelectPageVo<T> extends PageResult<T> {
private List<Integer> verifyGoodsIds;
private List<Integer> verifySkuIds;
public ShopNewComerSelectPageVo(Page<?> page, List<T> list) {
super(page.getCurrent(), page.getSize(), page.getTotal(), list);
}
}

View File

@ -0,0 +1,73 @@
package com.niu.shop.service.admin.marketing.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ShopNewcomerSelectSkuVo {
private Integer goodsId; // 商品id
private Integer siteId; // 站点id
private String goodsName; // 商品名称
private String goodsType; // 商品类型
private String subTitle; // 副标题
private String goodsCover; // 商品封面
private String goodsImage; // 商品图片
private String goodsCategory; // 商品分类
private String goodsDesc; // 商品介绍
private Integer brandId; // 商品品牌id
private String labelIds; // 标签组
private String serviceIds; // 商品服务
private String unit; // 单位
private Integer stock; // 商品库存总和
private Integer saleNum; // 销量
private Integer virtualSaleNum; // 虚拟销量
private Integer status; // 商品状态1.正常0下架
private Integer sort; // 排序
private String deliveryType; // 支持的配送方式
private Integer isFreeShipping; // 是否免邮
private String feeType; // 运费设置选择模板template固定运费fixed
private BigDecimal deliveryMoney; // 固定运费
private Integer deliveryTemplateId; // 运费模板
private Integer virtualAutoDelivery; // 虚拟商品是否自动发货
private String virtualReceiveType; // 虚拟商品收货方式auto自动收货artificial买家确认收货verify到店核销
private Integer virtualVerifyType; // 虚拟商品核销有效期类型0不限1购买后几日有效2指定过期日期
private Integer virtualIndate; // 虚拟到期时间
private Integer supplierId; // 供应商id
private Integer attrId; // 商品参数id
private String attrFormat; // 商品参数内容json格式
private Integer isDiscount; // 是否参与限时折扣
private String memberDiscount; // 会员等级折扣不参与会员折扣discount指定会员价fixed_price
private Integer posterId; // 海报id
private Long createTime; // 创建时间
private Long updateTime; // 修改时间
private List<Sku> skuList;
private Sku goodsSku;
private String goodsTypeName;
private String goodsCoverThumbSmall;
private String goodsCoverThumbMid;
@Data
public static class Sku {
private Integer skuId; // 商品sku_id
private Integer siteId; // 站点id
private String skuName; // 商品sku名称
private String skuImage; // sku主图
private String skuNo; // 商品sku编码
private Integer goodsId; // 商品id
private String skuSpecFormat; // sku规格格式
private BigDecimal price; // sku单价
private BigDecimal marketPrice; // 划线价
private BigDecimal salePrice; // 实际卖价有活动显示活动价默认原价
private BigDecimal costPrice; // sku成本价
private Integer stock; // 商品sku库存
private BigDecimal weight; // 重量单位kg
private BigDecimal volume; // 体积单位立方米
private Integer saleNum; // 销量
private Integer isDefault; // 是否默认
private String memberPrice; // 会员价json格式指定会员价数据结构为{"level_1":"10.00","level_2":"10.00"}
private BigDecimal newcomerPrice;
}
}

View File

@ -265,17 +265,16 @@ public class ShopOrderServiceImpl implements IShopOrderService {
corePayService.closeByTrade(order.getSiteId(), order.getOrderType(), order.getOrderId());
BigDecimal goodsMoney = new BigDecimal(0);
BigDecimal zero = new BigDecimal(0);
List<ShopOrderGoods> orderGoods = shopOrderGoodsMapper.selectList(new QueryWrapper<ShopOrderGoods>().eq("order_id", order.getOrderId()).select("order_goods_id,order_goods_money,goods_money,price,discount_money,num"));
for (ShopOrderGoods item: orderGoods) {
if (ObjectUtil.isNotEmpty(param.getOrderGoodsData().get(item.getOrderGoodsId()))) {
BigDecimal money = param.getOrderGoodsData().get(item.getOrderGoodsId()).getMoney();
if (money.compareTo(zero) != 0) {
if (money.compareTo(BigDecimal.ZERO) != 0) {
ShopOrderGoods orderGoodsUpdate = new ShopOrderGoods();
orderGoodsUpdate.setOrderGoodsId(item.getOrderGoodsId());
orderGoodsUpdate.setOrderGoodsMoney(item.getOrderGoodsMoney().add(money));
if (orderGoodsUpdate.getOrderGoodsMoney().compareTo(zero) == -1) {
if (orderGoodsUpdate.getOrderGoodsMoney().compareTo(BigDecimal.ZERO) == -1) {
throw new CommonException("订单项小计总额不能小于0");
}
orderGoodsUpdate.setGoodsMoney(orderGoodsUpdate.getOrderGoodsMoney().add(item.getDiscountMoney()));
@ -292,7 +291,7 @@ public class ShopOrderServiceImpl implements IShopOrderService {
ShopOrder orderUpdate = new ShopOrder();
orderUpdate.setOrderId(order.getOrderId());
orderUpdate.setOrderMoney(goodsMoney.add(param.getDeliveryMoney()).subtract(order.getDiscountMoney()));
if (orderUpdate.getOrderMoney().compareTo(zero) == -1) orderUpdate.setOrderMoney(zero);
if (orderUpdate.getOrderMoney().compareTo(BigDecimal.ZERO) == -1) orderUpdate.setOrderMoney(BigDecimal.ZERO);
orderUpdate.setDeliveryMoney(param.getDeliveryMoney());
orderUpdate.setGoodsMoney(goodsMoney);
this.shopOrderMapper.updateById(orderUpdate);
@ -307,7 +306,7 @@ public class ShopOrderServiceImpl implements IShopOrderService {
coreOrderLogService.add(logParam);
// 如果调价后的订单金额为0
if (orderUpdate.getOrderMoney().compareTo(zero) == 0) {
if (orderUpdate.getOrderMoney().compareTo(BigDecimal.ZERO) == 0) {
OrderPayParam payParam = new OrderPayParam();
payParam.setTradeId(order.getOrderId());
payParam.setMainType(OrderLogMainTypeEnum.SYSTEM.getType());

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