parent
92dde0b48b
commit
7a4a6a3046
|
@ -1,39 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
// TODO 芋艿:看看怎么删除
|
|
||||||
@ApiModel("管理后台 - 商品属性详情展示 Request VO")
|
|
||||||
@Data
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class ProductPropertyViewRespVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "属性项 id", example = "1")
|
|
||||||
public Long propertyId;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "属性项的名字", example = "内存")
|
|
||||||
public String name;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "属性值数组")
|
|
||||||
public List<Tuple2> propertyValues;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@ApiModel(value = "属性值元组")
|
|
||||||
public static class Tuple2 {
|
|
||||||
private final long id;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public Tuple2(Long id, String name) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ApiModel("管理后台 - 商品属性值的明细 Response VO")
|
||||||
|
@Data
|
||||||
|
public class ProductPropertyValueDetailRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性的编号", required = true, example = "1")
|
||||||
|
private Long propertyId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性的名称", required = true, example = "颜色")
|
||||||
|
private String propertyName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性值的编号", required = true, example = "1024")
|
||||||
|
private Long valueId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "属性值的名称", required = true, example = "红色")
|
||||||
|
private String valueName;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
### 获得商品 SPU 明细
|
||||||
|
GET {{baseUrl}}/product/spu/get-detail?id=4
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
@ -1,56 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.product.service.sku;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
|
||||||
import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
|
||||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
||||||
|
|
||||||
// TODO 芋艿:整合到 {@link ProductSkuServiceTest} 中
|
|
||||||
/**
|
|
||||||
* {@link ProductSkuServiceImpl} 的单元测试类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Import(ProductSkuServiceImpl.class)
|
|
||||||
@Disabled // TODO 芋艿:临时去掉
|
|
||||||
public class SkuServiceImplTest extends BaseDbUnitTest {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ProductSkuServiceImpl ProductSkuService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ProductSkuMapper ProductSkuMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteSku_success() {
|
|
||||||
// mock 数据
|
|
||||||
ProductSkuDO dbSku = randomPojo(ProductSkuDO.class);
|
|
||||||
ProductSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据
|
|
||||||
// 准备参数
|
|
||||||
Long id = dbSku.getId();
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
ProductSkuService.deleteSku(id);
|
|
||||||
// 校验数据不存在了
|
|
||||||
assertNull(ProductSkuMapper.selectById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeleteSku_notExists() {
|
|
||||||
// 准备参数
|
|
||||||
Long id = 1L;
|
|
||||||
|
|
||||||
// 调用, 并断言异常
|
|
||||||
assertServiceException(() -> ProductSkuService.deleteSku(id), SKU_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
### 获得地区树
|
||||||
|
GET {{baseUrl}}/system/area/tree
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.ip;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.ip.core.Area;
|
||||||
|
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
|
||||||
|
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
|
||||||
|
import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Api(tags = "管理后台 - 地区")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/area")
|
||||||
|
@Validated
|
||||||
|
public class AreaController {
|
||||||
|
|
||||||
|
@GetMapping("/tree")
|
||||||
|
@ApiOperation("获得地区树")
|
||||||
|
public CommonResult<List<AreaNodeRespVO>> getAreaTree() {
|
||||||
|
Area area = AreaUtils.getArea(Area.ID_CHINA);
|
||||||
|
Assert.notNull(area, "获取不到中国");
|
||||||
|
return success(AreaConvert.INSTANCE.convertList(area.getChildren()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-by-ip")
|
||||||
|
@ApiOperation("获得 IP 对应的地区名")
|
||||||
|
@ApiImplicitParam(name = "ip", value = "IP", required = true, dataTypeClass = String.class)
|
||||||
|
public CommonResult<String> getAreaByIp(@RequestParam("ip") String ip) {
|
||||||
|
// 获得城市
|
||||||
|
Area area = IPUtils.getArea(ip);
|
||||||
|
if (area == null) {
|
||||||
|
return success("未知");
|
||||||
|
}
|
||||||
|
// 格式化返回
|
||||||
|
return success(AreaUtils.format(area.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.controller.admin.ip.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ApiModel("管理后台 - 地区节点 Response VO")
|
||||||
|
@Data
|
||||||
|
public class AreaNodeRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "编号", required = true, example = "110000")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "名字", required = true, example = "北京")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子节点
|
||||||
|
*/
|
||||||
|
private List<AreaNodeRespVO> children;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.convert.ip;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.ip.core.Area;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AreaConvert {
|
||||||
|
|
||||||
|
AreaConvert INSTANCE = Mappers.getMapper(AreaConvert.class);
|
||||||
|
|
||||||
|
List<AreaNodeRespVO> convertList(List<Area> list);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 获得地区树
|
||||||
|
export function getAreaTree() {
|
||||||
|
return request({
|
||||||
|
url: '/system/area/tree',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得 IP 对应的地区名
|
||||||
|
export function getAreaByIp(ip) {
|
||||||
|
return request({
|
||||||
|
url: '/system/area/get-by-ip?ip=' + ip,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
|
||||||
|
<!-- 操作工具栏 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">IP 查询
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<el-table v-if="refreshTable" v-loading="loading" :data="list" row-key="id"
|
||||||
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
|
||||||
|
<el-table-column label="编号" prop="id"/>
|
||||||
|
<el-table-column label="名字" prop="name"/>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog title="IP 查询" :visible.sync="open" width="500px" append-to-body>
|
||||||
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
|
<el-form-item label="IP" prop="ip">
|
||||||
|
<el-input v-model="form.ip" placeholder="请输入 IP 地址"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="地址" prop="result">
|
||||||
|
<el-input v-model="form.result" readonly placeholder="展示查询 IP 结果" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm">查 询</el-button>
|
||||||
|
<el-button @click="cancel">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {getAreaByIp, getAreaTree} from "@/api/system/area";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Area",
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 地区列表
|
||||||
|
list: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
|
// 表单参数
|
||||||
|
form: {
|
||||||
|
ip: undefined,
|
||||||
|
result: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
rules: {
|
||||||
|
ip: [{required: true, message: "IP 地址不能为控", trigger: "blur"}],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
getAreaTree().then(response => {
|
||||||
|
this.list = response.data;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 取消按钮 */
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.form = {
|
||||||
|
ip: undefined,
|
||||||
|
result: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("form");
|
||||||
|
},
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
this.reset();
|
||||||
|
this.open = true;
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
submitForm() {
|
||||||
|
this.$refs["form"].validate(valid => {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getAreaByIp(this.form.ip).then(response => {
|
||||||
|
this.$modal.msgSuccess("查询成功");
|
||||||
|
this.form.result = response.data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue