Commit a34a95f8 authored by youc's avatar youc
Browse files

Merge branch 'master' of https://gitee.com/youc-project/litemall

parents f9f41412 a697e696
...@@ -97,8 +97,8 @@ public class AdminGoodsController { ...@@ -97,8 +97,8 @@ public class AdminGoodsController {
try { try {
//将生成的分享图片地址写入数据库 //将生成的分享图片地址写入数据库
qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName()); String url = qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName());
goods.setShareUrl(qCodeService.getShareImageUrl(goods.getId().toString())); goods.setShareUrl(url);
// 商品基本信息表litemall_goods // 商品基本信息表litemall_goods
goodsService.updateById(goods); goodsService.updateById(goods);
...@@ -194,8 +194,8 @@ public class AdminGoodsController { ...@@ -194,8 +194,8 @@ public class AdminGoodsController {
goodsService.add(goods); goodsService.add(goods);
//将生成的分享图片地址写入数据库 //将生成的分享图片地址写入数据库
qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName()); String url = qCodeService.createGoodShareImage(goods.getId().toString(), goods.getPicUrl(), goods.getName());
goods.setShareUrl(qCodeService.getShareImageUrl(goods.getId().toString())); goods.setShareUrl(url);
goodsService.updateById(goods); goodsService.updateById(goods);
// 商品规格表litemall_goods_specification // 商品规格表litemall_goods_specification
......
package org.linlinjava.litemall.admin.web;
import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallGoods;
import org.linlinjava.litemall.db.domain.LitemallGroupon;
import org.linlinjava.litemall.db.domain.LitemallGrouponRules;
import org.linlinjava.litemall.db.service.LitemallGoodsService;
import org.linlinjava.litemall.db.service.LitemallGrouponRulesService;
import org.linlinjava.litemall.db.service.LitemallGrouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin/groupon")
@Validated
public class AdminGrouponController {
@Autowired
private LitemallGrouponRulesService rulesService;
@Autowired
private LitemallGoodsService goodsService;
@Autowired
private LitemallGrouponService grouponService;
@GetMapping("/listRecord")
public Object listRecord(@LoginAdmin Integer adminId,
String grouponId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
List<LitemallGroupon> grouponList = grouponService.querySelective(grouponId, page, limit, sort, order);
int total = grouponService.countSelective(grouponId, page, limit, sort, order);
List<Map<String, Object>> records = new ArrayList<>();
for (LitemallGroupon groupon : grouponList) {
Map<String, Object> RecordData = new HashMap<>();
List<LitemallGroupon> subGrouponList = grouponService.queryJoiners(groupon.getId());
LitemallGrouponRules rules = rulesService.queryById(groupon.getRulesId());
LitemallGoods goods = goodsService.findById(rules.getGoodsId());
RecordData.put("groupon", groupon);
RecordData.put("subGroupons", subGrouponList);
RecordData.put("rules", rules);
RecordData.put("goods", goods);
records.add(RecordData);
}
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", records);
return ResponseUtil.ok(data);
}
@GetMapping("/list")
public Object list(@LoginAdmin Integer adminId,
String goodsId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
List<LitemallGrouponRules> rulesList = rulesService.querySelective(goodsId, page, limit, sort, order);
int total = rulesService.countSelective(goodsId, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", rulesList);
return ResponseUtil.ok(data);
}
@PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody String grouponRulesBody) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
Integer id = JacksonUtil.parseInteger(grouponRulesBody, "id");
Integer goodsId = JacksonUtil.parseInteger(grouponRulesBody, "goodsId");
String discount = JacksonUtil.parseString(grouponRulesBody, "discount");
Integer discountMember = JacksonUtil.parseInteger(grouponRulesBody, "discountMember");
String expireTimeString = JacksonUtil.parseString(grouponRulesBody, "expireTime");
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime expireTime = LocalDateTime.parse(expireTimeString, df);
LitemallGoods goods = goodsService.findById(goodsId);
if (goods == null) {
return ResponseUtil.badArgumentValue();
}
LitemallGrouponRules grouponRules = rulesService.queryById(id);
if (grouponRules == null) {
return ResponseUtil.badArgumentValue();
}
grouponRules.setGoodsId(goodsId);
grouponRules.setDiscount(new BigDecimal(discount));
grouponRules.setDiscountMember(discountMember);
grouponRules.setGoodsName(goods.getName());
grouponRules.setExpireTime(expireTime);
grouponRules.setPicUrl(goods.getPicUrl());
rulesService.update(grouponRules);
return ResponseUtil.ok();
}
@PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestBody String grouponRulesBody) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
Integer goodsId = JacksonUtil.parseInteger(grouponRulesBody, "goodsId");
String discount = JacksonUtil.parseString(grouponRulesBody, "discount");
Integer discountMember = JacksonUtil.parseInteger(grouponRulesBody, "discountMember");
String expireTimeString = JacksonUtil.parseString(grouponRulesBody, "expireTime");
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime expireTime = LocalDateTime.parse(expireTimeString, df);
LitemallGoods goods = goodsService.findById(goodsId);
if (goods == null) {
return ResponseUtil.badArgumentValue();
}
LitemallGrouponRules grouponRules = new LitemallGrouponRules();
grouponRules.setGoodsId(goodsId);
grouponRules.setDiscount(new BigDecimal(discount));
grouponRules.setDiscountMember(discountMember);
grouponRules.setAddTime(LocalDateTime.now());
grouponRules.setGoodsName(goods.getName());
grouponRules.setExpireTime(expireTime);
grouponRules.setPicUrl(goods.getPicUrl());
rulesService.createRules(grouponRules);
return ResponseUtil.ok();
}
@PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody String body) {
if (adminId == null) {
return ResponseUtil.unlogin();
}
Integer id = JacksonUtil.parseInteger(body, "id");
rulesService.delete(id);
return ResponseUtil.ok();
}
}
...@@ -2,25 +2,18 @@ package org.linlinjava.litemall.admin.web; ...@@ -2,25 +2,18 @@ package org.linlinjava.litemall.admin.web;
import org.linlinjava.litemall.admin.annotation.LoginAdmin; import org.linlinjava.litemall.admin.annotation.LoginAdmin;
import org.linlinjava.litemall.core.storage.StorageService; import org.linlinjava.litemall.core.storage.StorageService;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.ResponseUtil; import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.validator.Order; import org.linlinjava.litemall.core.validator.Order;
import org.linlinjava.litemall.core.validator.Sort; import org.linlinjava.litemall.core.validator.Sort;
import org.linlinjava.litemall.db.domain.LitemallStorage; import org.linlinjava.litemall.db.domain.LitemallStorage;
import org.linlinjava.litemall.db.service.LitemallStorageService; import org.linlinjava.litemall.db.service.LitemallStorageService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -35,29 +28,13 @@ public class AdminStorageController { ...@@ -35,29 +28,13 @@ public class AdminStorageController {
@Autowired @Autowired
private LitemallStorageService litemallStorageService; private LitemallStorageService litemallStorageService;
private String generateKey(String originalFilename){
int index = originalFilename.lastIndexOf('.');
String suffix = originalFilename.substring(index);
String key = null;
LitemallStorage storageInfo = null;
do{
key = CharUtil.getRandomString(20) + suffix;
storageInfo = litemallStorageService.findByKey(key);
}
while(storageInfo != null);
return key;
}
@GetMapping("/list") @GetMapping("/list")
public Object list(@LoginAdmin Integer adminId, public Object list(@LoginAdmin Integer adminId,
String key, String name, String key, String name,
@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit, @RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort, @Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order){ @Order @RequestParam(defaultValue = "desc") String order) {
List<LitemallStorage> storageList = litemallStorageService.querySelective(key, name, page, limit, sort, order); List<LitemallStorage> storageList = litemallStorageService.querySelective(key, name, page, limit, sort, order);
int total = litemallStorageService.countSelective(key, name, page, limit, sort, order); int total = litemallStorageService.countSelective(key, name, page, limit, sort, order);
Map<String, Object> data = new HashMap<>(); Map<String, Object> data = new HashMap<>();
...@@ -69,40 +46,21 @@ public class AdminStorageController { ...@@ -69,40 +46,21 @@ public class AdminStorageController {
@PostMapping("/create") @PostMapping("/create")
public Object create(@LoginAdmin Integer adminId, @RequestParam("file") MultipartFile file) throws IOException { public Object create(@LoginAdmin Integer adminId, @RequestParam("file") MultipartFile file) throws IOException {
if(adminId == null){ if (adminId == null) {
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
InputStream inputStream = null; storageService.store(file.getInputStream(), file.getSize(), file.getContentType(), originalFilename);
try { return ResponseUtil.ok();
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
return ResponseUtil.badArgumentValue();
}
String key = generateKey(originalFilename);
storageService.store(file.getInputStream(), file.getSize(), file.getContentType(), key);
String url = storageService.generateUrl(key);
LitemallStorage storageInfo = new LitemallStorage();
storageInfo.setName(originalFilename);
storageInfo.setSize((int)file.getSize());
storageInfo.setType(file.getContentType());
storageInfo.setAddTime(LocalDateTime.now());
storageInfo.setModified(LocalDateTime.now());
storageInfo.setKey(key);
storageInfo.setUrl(url);
litemallStorageService.add(storageInfo);
return ResponseUtil.ok(storageInfo);
} }
@PostMapping("/read") @PostMapping("/read")
public Object read(@LoginAdmin Integer adminId, @NotNull Integer id) { public Object read(@LoginAdmin Integer adminId, @NotNull Integer id) {
if(adminId == null){ if (adminId == null) {
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
LitemallStorage storageInfo = litemallStorageService.findById(id); LitemallStorage storageInfo = litemallStorageService.findById(id);
if(storageInfo == null){ if (storageInfo == null) {
return ResponseUtil.badArgumentValue(); return ResponseUtil.badArgumentValue();
} }
return ResponseUtil.ok(storageInfo); return ResponseUtil.ok(storageInfo);
...@@ -110,7 +68,7 @@ public class AdminStorageController { ...@@ -110,7 +68,7 @@ public class AdminStorageController {
@PostMapping("/update") @PostMapping("/update")
public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallStorage litemallStorage) { public Object update(@LoginAdmin Integer adminId, @RequestBody LitemallStorage litemallStorage) {
if(adminId == null){ if (adminId == null) {
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
litemallStorageService.update(litemallStorage); litemallStorageService.update(litemallStorage);
...@@ -119,7 +77,7 @@ public class AdminStorageController { ...@@ -119,7 +77,7 @@ public class AdminStorageController {
@PostMapping("/delete") @PostMapping("/delete")
public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallStorage litemallStorage) { public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallStorage litemallStorage) {
if(adminId == null){ if (adminId == null) {
return ResponseUtil.unlogin(); return ResponseUtil.unlogin();
} }
litemallStorageService.deleteByKey(litemallStorage.getKey()); litemallStorageService.deleteByKey(litemallStorage.getKey());
......
module.exports = { module.exports = {
NODE_ENV: '"production"', NODE_ENV: '"production"',
ENV_CONFIG: '"dep"', ENV_CONFIG: '"dep"',
BASE_API: '"http://localhost:8080/admin"' BASE_API: '"https://www.menethil.com.cn/admin"'
} }
import request from '@/utils/request'
export function listRecord(query) {
return request({
url: '/groupon/listRecord',
method: 'get',
params: query
})
}
export function listGroupon(query) {
return request({
url: '/groupon/list',
method: 'get',
params: query
})
}
export function deleteGroupon(data) {
return request({
url: '/groupon/delete',
method: 'post',
data
})
}
export function publishGroupon(data) {
return request({
url: '/groupon/create',
method: 'post',
data
})
}
export function editGroupon(data) {
return request({
url: '/groupon/update',
method: 'post',
data
})
}
...@@ -105,6 +105,21 @@ export const asyncRouterMap = [ ...@@ -105,6 +105,21 @@ export const asyncRouterMap = [
] ]
}, },
{
path: '/groupon',
component: Layout,
redirect: 'noredirect',
name: 'grouponManage',
meta: {
title: '团购管理',
icon: 'chart'
},
children: [
{ path: 'list', component: _import('groupon/list'), name: 'list', meta: { title: '团购规则', noCache: true }},
{ path: 'record', component: _import('groupon/record'), name: 'record', meta: { title: '团购活动', noCache: true }}
]
},
{ {
path: '/promotion', path: '/promotion',
component: Layout, component: Layout,
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</el-form-item> </el-form-item>
<el-form-item label="商品介绍"> <el-form-item label="商品介绍">
<span>{{ props.row.brief }}</span> <span>{{ props.row.brief }}</span>
</el-form-item> </el-form-item>
<el-form-item label="商品单位"> <el-form-item label="商品单位">
<span>{{ props.row.unit }}</span> <span>{{ props.row.unit }}</span>
</el-form-item> </el-form-item>
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
</el-form-item> </el-form-item>
<el-form-item label="类目ID"> <el-form-item label="类目ID">
<span>{{ props.row.categoryId }}</span> <span>{{ props.row.categoryId }}</span>
</el-form-item> </el-form-item>
<el-form-item label="品牌商ID"> <el-form-item label="品牌商ID">
<span>{{ props.row.brandId }}</span> <span>{{ props.row.brandId }}</span>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="商品编号" prop="goodsSn"> <el-table-column align="center" label="商品编号" prop="goodsSn">
</el-table-column> </el-table-column>
...@@ -52,6 +52,12 @@ ...@@ -52,6 +52,12 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" property="iconUrl" label="分享图">
<template slot-scope="scope">
<img :src="scope.row.shareUrl" width="40"/>
</template>
</el-table-column>
<el-table-column align="center" label="详情" prop="detail"> <el-table-column align="center" label="详情" prop="detail">
<template slot-scope="scope"> <template slot-scope="scope">
<el-dialog title="商品详情" :visible.sync="detailDialogVisible"> <el-dialog title="商品详情" :visible.sync="detailDialogVisible">
...@@ -71,19 +77,19 @@ ...@@ -71,19 +77,19 @@
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.isNew ? 'success' : 'error' ">{{scope.row.isNew ? '新品' : '非新品'}}</el-tag> <el-tag :type="scope.row.isNew ? 'success' : 'error' ">{{scope.row.isNew ? '新品' : '非新品'}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="是否热品" prop="isHot"> <el-table-column align="center" label="是否热品" prop="isHot">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.isHot ? 'success' : 'error' ">{{scope.row.isHot ? '热品' : '非热品'}}</el-tag> <el-tag :type="scope.row.isHot ? 'success' : 'error' ">{{scope.row.isHot ? '热品' : '非热品'}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="是否在售" prop="isOnSale"> <el-table-column align="center" label="是否在售" prop="isOnSale">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag :type="scope.row.isOnSale ? 'success' : 'error' ">{{scope.row.isOnSale ? '在售' : '未售'}}</el-tag> <el-tag :type="scope.row.isOnSale ? 'success' : 'error' ">{{scope.row.isOnSale ? '在售' : '未售'}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width"> <el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
...@@ -211,4 +217,4 @@ export default { ...@@ -211,4 +217,4 @@ export default {
} }
} }
} }
</script> </script>
\ No newline at end of file
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsId">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
<el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download"
@click="handleDownload">导出
</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
highlight-current-row>
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" class="table-expand">
<el-form-item label="宣传画廊">
<img class="gallery" v-for="pic in props.row.gallery" :key="pic" :src="pic"/>
</el-form-item>
<el-form-item label="商品介绍">
<span>{{ props.row.brief }}</span>
</el-form-item>
<el-form-item label="商品单位">
<span>{{ props.row.unit }}</span>
</el-form-item>
<el-form-item label="关键字">
<span>{{ props.row.keyword }}</span>
</el-form-item>
<el-form-item label="类目ID">
<span>{{ props.row.categoryId }}</span>
</el-form-item>
<el-form-item label="品牌商ID">
<span>{{ props.row.brandId }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" label="商品ID" prop="goodsId">
</el-table-column>
<el-table-column align="center" min-width="100" label="名称" prop="goodsName">
</el-table-column>
<el-table-column align="center" property="iconUrl" label="图片">
<template slot-scope="scope">
<img :src="scope.row.picUrl" width="40"/>
</template>
</el-table-column>
<el-table-column align="center" label="团购优惠" prop="discount">
</el-table-column>
<el-table-column align="center" label="团购要求" prop="discountMember">
</el-table-column>
<el-table-column align="center" label="开始时间" prop="addTime">
</el-table-column>
<el-table-column align="center" label="结束时间" prop="expireTime">
</el-table-column>
<el-table-column align="center" label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改对话框 -->
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
<el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px"
style='width: 400px; margin-left:50px;'>
<el-form-item label="商品ID" prop="goodsId">
<el-input v-model="dataForm.goodsId"></el-input>
</el-form-item>
<el-form-item label="团购折扣" prop="discount">
<el-input v-model="dataForm.discount"></el-input>
</el-form-item>
<el-form-item label="团购人数要求" prop="discountMember">
<el-input v-model="dataForm.discountMember"></el-input>
</el-form-item>
<el-form-item label="过期时间" prop="expireTime">
<el-date-picker v-model="dataForm.expireTime" type="datetime" placeholder="选择日期"
value-format="yyyy-MM-dd HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button v-if="dialogStatus=='create'" type="primary" @click="createData">确定</el-button>
<el-button v-else type="primary" @click="updateData">确定</el-button>
</div>
</el-dialog>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<el-tooltip placement="top" content="返回顶部">
<back-to-top :visibilityHeight="100"></back-to-top>
</el-tooltip>
</div>
</template>
<style>
.table-expand {
font-size: 0;
}
.table-expand label {
width: 100px;
color: #99a9bf;
}
.table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
.gallery {
width: 80px;
margin-right: 10px;
}
</style>
<script>
import {listGroupon, publishGroupon, deleteGroupon, editGroupon} from '@/api/groupon'
import BackToTop from '@/components/BackToTop'
export default {
name: 'GoodsList',
components: {BackToTop},
data() {
return {
list: [],
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
goodsId: undefined,
sort: 'add_time',
order: 'desc'
},
goodsDetail: '',
detailDialogVisible: false,
downloadLoading: false,
dataForm: {
id: undefined,
goodsId: '',
discount: '',
discountMember: '',
expireTime: undefined,
},
dialogFormVisible: false,
dialogStatus: '',
textMap: {
update: '编辑',
create: '创建'
},
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listGroupon(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
resetForm() {
this.dataForm = {
id: undefined,
goodsId: '',
discount: '',
discountMember: '',
expireTime: undefined,
}
},
handleCreate() {
this.resetForm()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
createData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
publishGroupon(this.dataForm).then(response => {
this.list.unshift(response.data.data)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleUpdate(row) {
this.dataForm = Object.assign({}, row)
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
updateData() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
editGroupon(this.dataForm).then(() => {
for (const v of this.list) {
if (v.id === this.dataForm.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.dataForm)
break
}
}
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
})
}
})
},
handleDelete(row) {
deleteGroupon(row).then(response => {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
})
const index = this.list.indexOf(row)
this.list.splice(index, 1)
})
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['商品ID', '名称', '首页主图', '折扣', '人数要求', '活动开始时间', '活动结束时间']
const filterVal = ['id', 'name', 'pic_url', 'discount', 'discountMember', 'addTime', 'expireTime']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
this.downloadLoading = false
})
}
}
}
</script>
<template>
<div class="app-container calendar-list-container">
<!-- 查询和其他操作 -->
<div class="filter-container">
<el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入商品编号" v-model="listQuery.goodsId">
</el-input>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<!--<el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>-->
<el-button class="filter-item" type="primary" :loading="downloadLoading" icon="el-icon-download"
@click="handleDownload">导出
</el-button>
</div>
<!-- 查询结果 -->
<el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
highlight-current-row>
<el-table-column type="expand">
<template slot-scope="scope">
<el-table :data="scope.row.subGroupons" border style="width: 100%">
<el-table-column align="center" label="订单ID" prop="orderId">
</el-table-column>
<el-table-column align="center" label="用户ID" prop="userId">
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column align="center" label="订单ID" prop="groupon.orderId">
</el-table-column>
<el-table-column align="center" label="用户ID" prop="groupon.userId">
</el-table-column>
<el-table-column align="center" label="参与人数" prop="subGroupons.length">
</el-table-column>
<el-table-column align="center" label="团购折扣" prop="rules.discount">
</el-table-column>
<el-table-column align="center" label="团购要求" prop="rules.discountMember">
</el-table-column>
<el-table-column align="center" property="iconUrl" label="分享图片">
<template slot-scope="scope">
<img :src="scope.row.groupon.shareUrl" width="40"/>
</template>
</el-table-column>
<el-table-column align="center" label="开始时间" prop="rules.addTime">
</el-table-column>
<el-table-column align="center" label="结束时间" prop="rules.expireTime">
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="listQuery.page"
:page-sizes="[10,20,30,50]" :page-size="listQuery.limit"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
<el-tooltip placement="top" content="返回顶部">
<back-to-top :visibilityHeight="100"></back-to-top>
</el-tooltip>
</div>
</template>
<style>
.table-expand {
font-size: 0;
}
.table-expand label {
width: 100px;
color: #99a9bf;
}
.table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
}
.gallery {
width: 80px;
margin-right: 10px;
}
</style>
<script>
import {listRecord} from '@/api/groupon'
import BackToTop from '@/components/BackToTop'
export default {
name: 'GoodsList',
components: {BackToTop},
data() {
return {
list: [],
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
goodsId: undefined,
sort: 'add_time',
order: 'desc'
},
goodsDetail: '',
detailDialogVisible: false,
downloadLoading: false,
}
},
created() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listRecord(this.listQuery).then(response => {
this.list = response.data.data.items
this.total = response.data.data.total
this.listLoading = false
}).catch(() => {
this.list = []
this.total = 0
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1
this.getList()
},
handleSizeChange(val) {
this.listQuery.limit = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.page = val
this.getList()
},
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['商品ID', '名称', '首页主图', '折扣', '人数要求', '活动开始时间', '活动结束时间']
const filterVal = ['id', 'name', 'pic_url', 'discount', 'discountMember', 'addTime', 'expireTime']
excel.export_json_to_excel2(tHeader, this.list, filterVal, '商品信息')
this.downloadLoading = false
})
}
}
}
</script>
...@@ -5,7 +5,7 @@ spring: ...@@ -5,7 +5,7 @@ spring:
encoding: UTF-8 encoding: UTF-8
server: server:
port: 8080 port: 8082
logging: logging:
level: level:
......
...@@ -18,31 +18,37 @@ import java.util.Set; ...@@ -18,31 +18,37 @@ import java.util.Set;
@ControllerAdvice @ControllerAdvice
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public Object badArgumentHandler(IllegalArgumentException e){
e.printStackTrace();
return ResponseUtil.badArgumentValue();
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class) @ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseBody @ResponseBody
public Object argumentHandler(MethodArgumentTypeMismatchException e){ public Object badArgumentHandler(MethodArgumentTypeMismatchException e){
e.printStackTrace(); e.printStackTrace();
return ResponseUtil.badArgumentValue(); return ResponseUtil.badArgumentValue();
} }
@ExceptionHandler(MissingServletRequestParameterException.class) @ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody @ResponseBody
public Object argumentHandler(MissingServletRequestParameterException e){ public Object badArgumentHandler(MissingServletRequestParameterException e){
e.printStackTrace(); e.printStackTrace();
return ResponseUtil.badArgumentValue(); return ResponseUtil.badArgumentValue();
} }
@ExceptionHandler(HttpMessageNotReadableException.class) @ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody @ResponseBody
public Object httpMessageNotReadableHandler(HttpMessageNotReadableException e){ public Object badArgumentHandler(HttpMessageNotReadableException e){
e.printStackTrace(); e.printStackTrace();
return ResponseUtil.badArgumentValue(); return ResponseUtil.badArgumentValue();
} }
@ExceptionHandler(ValidationException.class) @ExceptionHandler(ValidationException.class)
@ResponseBody @ResponseBody
public Object handle(ValidationException e) { public Object badArgumentHandler(ValidationException e) {
e.printStackTrace(); e.printStackTrace();
if(e instanceof ConstraintViolationException){ if(e instanceof ConstraintViolationException){
ConstraintViolationException exs = (ConstraintViolationException) e; ConstraintViolationException exs = (ConstraintViolationException) e;
...@@ -57,7 +63,7 @@ public class GlobalExceptionHandler { ...@@ -57,7 +63,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
@ResponseBody @ResponseBody
public Object exceptionHandler(Exception e){ public Object seriousHandler(Exception e){
e.printStackTrace(); e.printStackTrace();
return ResponseUtil.serious(); return ResponseUtil.serious();
} }
......
package org.linlinjava.litemall.core.qcode;
import cn.binarywang.wx.miniapp.api.WxMaService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.linlinjava.litemall.core.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public abstract class QCodeBase {
@Autowired
protected WxMaService wxMaService;
@Autowired
protected StorageService storageService;
protected abstract String getKeyName(String id);
/**
* 获取图片地址
*
* @param id
* @return
*/
public String getShareImageUrl(String id) {
return storageService.generateUrl(getKeyName(id));
}
protected BufferedImage getQCode(String scene, String page) {
//创建该商品的二维码
File file = null;
try {
file = wxMaService.getQrcodeService().createWxaCodeUnlimit(scene, page);
FileInputStream inputStream = new FileInputStream(file);
BufferedImage qrCodeImage = ImageIO.read(inputStream);
return qrCodeImage;
} catch (WxErrorException | IOException e) {
e.printStackTrace();
}
return null;
}
protected void saveImage(String id, byte[] imageData) {
// MultipartFile multipartFile = new MockMultipartFile(getKeyName(id), getKeyName(id), "image/jpeg", imageData);
// //存储分享图
// storageService.store(multipartFile, getKeyName(id));
}
/**
* 居中写文字
*
* @param baseImage
* @param textToWrite
* @param font
* @param color
* @param y
*/
protected void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, Font font, Color color, int y) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(color);
g2D.setFont(font);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 计算文字长度,计算居中的x点坐标
FontMetrics fm = g2D.getFontMetrics(font);
int textWidth = fm.stringWidth(textToWrite);
int widthX = (baseImage.getWidth() - textWidth) / 2;
// 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。
g2D.drawString(textToWrite, widthX, y);
// 释放对象
g2D.dispose();
}
/**
* 写上文字
*
* @param baseImage
* @param textToWrite
* @param font
* @param color
* @param x
* @param y
*/
protected void drawTextInImg(BufferedImage baseImage, String textToWrite, Font font, Color color, int x, int y) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(color);
g2D.setFont(font);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2D.drawString(textToWrite, x, y);
g2D.dispose();
}
/**
* 画中画
*
* @param baseImage
* @param imageToWrite
* @param x
* @param y
* @param width
* @param height
*/
protected void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite, int x, int y, int width, int height) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.drawImage(imageToWrite, x, y, width, height, null);
g2D.dispose();
}
}
package org.linlinjava.litemall.core.qcode;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class QCodeGoodShare extends QCodeBase {
@Override
protected String getKeyName(String id) {
return "GOOD_QCODE_" + id + ".jpg";
}
/**
* 创建商品分享图
*
* @param goodId
* @param goodPicUrl
* @param goodName
*/
public void createGoodShareImage(String goodId, String goodPicUrl, String goodName) {
if (!SystemConfig.isAutoCreateShareImage())
return;
BufferedImage qrCodeImage = getQCode("goods," + goodId, "pages/index/index");
//将商品图片,商品名字,商城名字画到模版图中
byte[] imageData = new byte[0];
try {
imageData = drawPicture(qrCodeImage, goodPicUrl, goodName, SystemConfig.getMallName());
} catch (IOException e) {
e.printStackTrace();
}
saveImage(goodId, imageData);
}
/**
* 将商品图片,商品名字画到模版图中
*
* @param qrCodeImage 二维码图片
* @param goodPicUrl 商品图片地址
* @param goodName 商品名称
* @return
* @throws IOException
*/
private byte[] drawPicture(BufferedImage qrCodeImage, String goodPicUrl, String goodName, String shopName) throws IOException {
//底图
ClassPathResource redResource = new ClassPathResource("back.jpg");
BufferedImage red = ImageIO.read(redResource.getInputStream());
//商品图片
URL goodPic = new URL(goodPicUrl);
BufferedImage goodImage = ImageIO.read(goodPic);
// --- 画图 ---
//底层空白 bufferedImage
BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
//画上图片
drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());
//画上商品图片
drawImgInImg(baseImage, goodImage, 56, 135, 720, 720);
//画上小程序二维码
drawImgInImg(baseImage, qrCodeImage, 442, 1006, 340, 340);
Font font = new Font("Microsoft YaHei", Font.PLAIN, 42);
Color color = new Color(167, 136, 69);
//写上商品名称
drawTextInImg(baseImage, goodName, font, color, 112, 955);
//写上商城名称
drawTextInImgCenter(baseImage, shopName, font, color, 98);
//转jpg
BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage
.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(baseImage, 0, 0, null);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageIO.write(result, "jpg", bs);
//最终byte数组
return bs.toByteArray();
}
}
package org.linlinjava.litemall.core.qcode;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.db.domain.LitemallGroupon;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
public class QCodeGroupon extends QCodeBase {
@Override
protected String getKeyName(String id) {
return null;
}
public void createGrouponShareImage(String goodName, String goodPicUrl, LitemallGroupon groupon) {
try {
BufferedImage qrCodeImage = getQCode("groupon," + groupon.getId(), "pages/index/index");
//将商品图片,商品名字,商城名字画到模版图中
byte[] imageData = drawPicture(qrCodeImage, goodPicUrl, goodName, SystemConfig.getMallName());
saveImage(groupon.getId().toString(), imageData);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将商品图片,商品名字画到模版图中
*
* @param qrCodeImage 二维码图片
* @param goodPicUrl 商品图片地址
* @param goodName 商品名称
* @return
* @throws IOException
*/
private byte[] drawPicture(BufferedImage qrCodeImage, String goodPicUrl, String goodName, String shopName) throws IOException {
//底图
ClassPathResource redResource = new ClassPathResource("back.jpg");
BufferedImage red = ImageIO.read(redResource.getInputStream());
//商品图片
URL goodPic = new URL(goodPicUrl);
BufferedImage goodImage = ImageIO.read(goodPic);
// --- 画图 ---
//底层空白 bufferedImage
BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
//画上图片
drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());
//画上商品图片
drawImgInImg(baseImage, goodImage, 56, 135, 720, 720);
//画上小程序二维码
drawImgInImg(baseImage, qrCodeImage, 442, 1006, 340, 340);
Font font = new Font("Microsoft YaHei", Font.PLAIN, 42);
Color color = new Color(167, 136, 69);
//写上商品名称
drawTextInImg(baseImage, goodName, font, color, 112, 955);
//写上商城名称
drawTextInImgCenter(baseImage, shopName, font, color, 98);
//转jpg
BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage
.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
result.getGraphics().drawImage(baseImage, 0, 0, null);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageIO.write(result, "jpg", bs);
//最终byte数组
return bs.toByteArray();
}
}
...@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; ...@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.error.WxErrorException;
import org.linlinjava.litemall.core.storage.StorageService; import org.linlinjava.litemall.core.storage.StorageService;
import org.linlinjava.litemall.core.system.SystemConfig; import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.db.domain.LitemallGroupon;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -22,6 +23,31 @@ public class QCodeService { ...@@ -22,6 +23,31 @@ public class QCodeService {
@Autowired @Autowired
private StorageService storageService; private StorageService storageService;
public String createGrouponShareImage(String goodName, String goodPicUrl, LitemallGroupon groupon) {
try {
//创建该商品的二维码
File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("groupon," + groupon.getId(), "pages/index/index");
FileInputStream inputStream = new FileInputStream(file);
//将商品图片,商品名字,商城名字画到模版图中
byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName);
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
//存储分享图
String url = storageService.store(inputStream2, imageData.length, "image/jpeg", getKeyName(groupon.getId().toString()));
return url;
} catch (WxErrorException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/** /**
* 创建商品分享图 * 创建商品分享图
* *
...@@ -29,32 +55,30 @@ public class QCodeService { ...@@ -29,32 +55,30 @@ public class QCodeService {
* @param goodPicUrl * @param goodPicUrl
* @param goodName * @param goodName
*/ */
public void createGoodShareImage(String goodId, String goodPicUrl, String goodName) { public String createGoodShareImage(String goodId, String goodPicUrl, String goodName) {
if (!SystemConfig.isAutoCreateShareImage()) if (!SystemConfig.isAutoCreateShareImage())
return; return "";
try { try {
//创建该商品的二维码 //创建该商品的二维码
File file = wxMaService.getQrcodeService().createWxaCodeUnlimit(goodId, "pages/index/index"); File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("goods," + goodId, "pages/index/index");
FileInputStream inputStream = new FileInputStream(file); FileInputStream inputStream = new FileInputStream(file);
//将商品图片,商品名字,商城名字画到模版图中 //将商品图片,商品名字,商城名字画到模版图中
byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName, SystemConfig.getMallName()); byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName);
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData); ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
//存储分享图 //存储分享图
storageService.store(inputStream2, imageData.length, "image/jpeg", getKeyName(goodId)); String url = storageService.store(inputStream2, imageData.length, "image/jpeg", getKeyName(goodId));
return url;
} catch (WxErrorException e) { } catch (WxErrorException e) {
e.printStackTrace(); e.printStackTrace();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (FontFormatException e) {
e.printStackTrace();
} }
}
public String getShareImageUrl(String goodId) { return "";
return storageService.generateUrl(getKeyName(goodId));
} }
private String getKeyName(String goodId) { private String getKeyName(String goodId) {
...@@ -70,9 +94,9 @@ public class QCodeService { ...@@ -70,9 +94,9 @@ public class QCodeService {
* @return * @return
* @throws IOException * @throws IOException
*/ */
private byte[] drawPicture(InputStream qrCodeImg, String goodPicUrl, String goodName, String shopName) throws IOException, FontFormatException { private byte[] drawPicture(InputStream qrCodeImg, String goodPicUrl, String goodName) throws IOException {
//底图 //底图
ClassPathResource redResource = new ClassPathResource("back.jpg"); ClassPathResource redResource = new ClassPathResource("back.png");
BufferedImage red = ImageIO.read(redResource.getInputStream()); BufferedImage red = ImageIO.read(redResource.getInputStream());
...@@ -92,16 +116,16 @@ public class QCodeService { ...@@ -92,16 +116,16 @@ public class QCodeService {
drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight()); drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());
//画上商品图片 //画上商品图片
drawImgInImg(baseImage, goodImage, 56, 135, 720, 720); drawImgInImg(baseImage, goodImage, 71, 69, 660, 660);
//画上小程序二维码 //画上小程序二维码
drawImgInImg(baseImage, qrCodeImage, 442, 1006, 340, 340); drawImgInImg(baseImage, qrCodeImage, 448, 767, 300, 300);
//写上商品名称 //写上商品名称
drawTextInImg(baseImage, goodName, 112, 955); drawTextInImg(baseImage, goodName, 65, 867);
//写上商城名称 //写上商城名称
drawTextInImgCenter(baseImage, shopName, 112, 98); // drawTextInImgCenter(baseImage, shopName, 98);
//转jpg //转jpg
...@@ -115,13 +139,13 @@ public class QCodeService { ...@@ -115,13 +139,13 @@ public class QCodeService {
return bs.toByteArray(); return bs.toByteArray();
} }
private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int x, int y) { private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int y) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics(); Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(new Color(167, 136, 69)); g2D.setColor(new Color(167, 136, 69));
String fontName = "Microsoft YaHei"; String fontName = "Microsoft YaHei";
Font f = new Font(fontName, Font.PLAIN, 42); Font f = new Font(fontName, Font.PLAIN, 28);
g2D.setFont(f); g2D.setFont(f);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
...@@ -131,17 +155,17 @@ public class QCodeService { ...@@ -131,17 +155,17 @@ public class QCodeService {
int widthX = (baseImage.getWidth() - textWidth) / 2; int widthX = (baseImage.getWidth() - textWidth) / 2;
// 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。 // 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。
g2D.drawString(textToWrite, widthX, 100); g2D.drawString(textToWrite, widthX, y);
// 释放对象 // 释放对象
g2D.dispose(); g2D.dispose();
} }
private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) throws IOException, FontFormatException { private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) {
Graphics2D g2D = (Graphics2D) baseImage.getGraphics(); Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
g2D.setColor(new Color(167, 136, 69)); g2D.setColor(new Color(167, 136, 69));
//TODO 注意,这里的字体必须安装在服务器上 //TODO 注意,这里的字体必须安装在服务器上
g2D.setFont(new Font("Microsoft YaHei", Font.PLAIN, 42)); g2D.setFont(new Font("Microsoft YaHei", Font.PLAIN, 28));
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2D.drawString(textToWrite, x, y); g2D.drawString(textToWrite, x, y);
......
...@@ -58,7 +58,7 @@ public class QiniuStorage implements Storage { ...@@ -58,7 +58,7 @@ public class QiniuStorage implements Storage {
} }
/** /**
* 阿里云OSS对象存储简单上传实现 * 七牛云OSS对象存储简单上传实现
*/ */
@Override @Override
public void store(InputStream inputStream, long contentLength, String contentType, String keyName) { public void store(InputStream inputStream, long contentLength, String contentType, String keyName) {
......
...@@ -16,7 +16,7 @@ public interface Storage { ...@@ -16,7 +16,7 @@ public interface Storage {
* @param inputStream 文件输入流 * @param inputStream 文件输入流
* @param contentLength 文件长度 * @param contentLength 文件长度
* @param contentType 文件类型 * @param contentType 文件类型
* @param keyName 文件索引 * @param keyName 文件名
*/ */
void store(InputStream inputStream, long contentLength, String contentType, String keyName); void store(InputStream inputStream, long contentLength, String contentType, String keyName);
......
package org.linlinjava.litemall.core.storage; package org.linlinjava.litemall.core.storage;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.db.domain.LitemallStorage;
import org.linlinjava.litemall.db.service.LitemallStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
...@@ -13,6 +18,8 @@ import java.util.stream.Stream; ...@@ -13,6 +18,8 @@ import java.util.stream.Stream;
public class StorageService { public class StorageService {
private String active; private String active;
private Storage storage; private Storage storage;
@Autowired
private LitemallStorageService litemallStorageService;
public String getActive() { public String getActive() {
return active; return active;
...@@ -32,13 +39,44 @@ public class StorageService { ...@@ -32,13 +39,44 @@ public class StorageService {
/** /**
* 存储一个文件对象 * 存储一个文件对象
* @param inputStream 文件输入流 *
* @param inputStream 文件输入流
* @param contentLength 文件长度 * @param contentLength 文件长度
* @param contentType 文件类型 * @param contentType 文件类型
* @param keyName 文件索引名 * @param fileName 文件索引名
*/ */
public void store(InputStream inputStream, long contentLength, String contentType, String keyName) { public String store(InputStream inputStream, long contentLength, String contentType, String fileName) {
storage.store(inputStream, contentLength, contentType, keyName); String key = generateKey(fileName);
storage.store(inputStream, contentLength, contentType, key);
String url = generateUrl(key);
LitemallStorage storageInfo = new LitemallStorage();
storageInfo.setName(fileName);
storageInfo.setSize((int) contentLength);
storageInfo.setType(contentType);
storageInfo.setAddTime(LocalDateTime.now());
storageInfo.setModified(LocalDateTime.now());
storageInfo.setKey(key);
storageInfo.setUrl(url);
litemallStorageService.add(storageInfo);
return url;
}
private String generateKey(String originalFilename) {
int index = originalFilename.lastIndexOf('.');
String suffix = originalFilename.substring(index);
String key = null;
LitemallStorage storageInfo = null;
do {
key = CharUtil.getRandomString(20) + suffix;
storageInfo = litemallStorageService.findByKey(key);
}
while (storageInfo != null);
return key;
} }
public Stream<Path> loadAll() { public Stream<Path> loadAll() {
......
...@@ -21,7 +21,6 @@ public class StorageAutoConfiguration { ...@@ -21,7 +21,6 @@ public class StorageAutoConfiguration {
@Bean @Bean
public StorageService storageService() { public StorageService storageService() {
StorageService storageService = new StorageService(); StorageService storageService = new StorageService();
Map<String, Storage> supportedStorage = new HashMap<String, Storage>(3);
String active = this.properties.getActive(); String active = this.properties.getActive();
storageService.setActive(active); storageService.setActive(active);
if(active.equals("local")){ if(active.equals("local")){
...@@ -34,7 +33,7 @@ public class StorageAutoConfiguration { ...@@ -34,7 +33,7 @@ public class StorageAutoConfiguration {
storageService.setStorage(tencentStorage()); storageService.setStorage(tencentStorage());
} }
else if(active.equals("qiniu")){ else if(active.equals("qiniu")){
storageService.setStorage(tencentStorage()); storageService.setStorage(qiniuStorage());
} }
else{ else{
throw new RuntimeException("当前存储模式 " + active + " 不支持"); throw new RuntimeException("当前存储模式 " + active + " 不支持");
......
...@@ -22,7 +22,11 @@ class SystemInistService { ...@@ -22,7 +22,11 @@ class SystemInistService {
private void inist() { private void inist() {
systemInistService = this; systemInistService = this;
SystemInfoPrinter.printInfo("Litemall 初始化信息", getSystemInfo()); try {
SystemInfoPrinter.printInfo("Litemall 初始化信息", getSystemInfo());
} catch (Exception e) {
e.printStackTrace();
}
} }
private Map<String, String> getSystemInfo() { private Map<String, String> getSystemInfo() {
...@@ -48,6 +52,7 @@ class SystemInistService { ...@@ -48,6 +52,7 @@ class SystemInistService {
infos.put("本地对象访问地址", environment.getProperty("litemall.storage.local.address")); infos.put("本地对象访问地址", environment.getProperty("litemall.storage.local.address"));
infos.put("本地对象访问端口", environment.getProperty("litemall.storage.local.port")); infos.put("本地对象访问端口", environment.getProperty("litemall.storage.local.port"));
// 微信相关信息
infos.put(SystemInfoPrinter.CREATE_PART_COPPER + 2, "微信相关"); infos.put(SystemInfoPrinter.CREATE_PART_COPPER + 2, "微信相关");
infos.put("微信APP KEY", environment.getProperty("litemall.wx.app-id")); infos.put("微信APP KEY", environment.getProperty("litemall.wx.app-id"));
infos.put("微信APP-SECRET", environment.getProperty("litemall.wx.app-secret")); infos.put("微信APP-SECRET", environment.getProperty("litemall.wx.app-secret"));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment