后台品牌属性页面

develop
ddyd 2 weeks ago
parent 65ab95e84a
commit eebdef758b

@ -5,8 +5,11 @@ import java.util.HashMap;
import java.util.Map;
import com.bookstore.common.valid.AddGroup;
import com.bookstore.common.valid.AddShowStatusGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@ -62,7 +65,7 @@ public class BrandController {
*/
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Valid @RequestBody BrandEntity brand /* ,BindingResult result*/){ // @Valid开启校验功能
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand /* ,BindingResult result*/){ // @Valid开启校验功能
// if (result.hasErrors()) {
// //获取校验结果,foreach遍历全部错误数据
// Map<String, String> map = new HashMap<>();
@ -92,6 +95,13 @@ public class BrandController {
return R.ok();
}
@RequestMapping("/update/status")
//@RequiresPermissions("product:brand:update")
public R updateStatus(@Validated(AddShowStatusGroup.class) @RequestBody BrandEntity brand){
brandService.updateById(brand);
return R.ok();
}
/**
*
*/

@ -3,10 +3,13 @@ package com.bookstore.bookmall.product.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.awt.*;
import java.io.Serializable;
import java.util.Date;
import com.bookstore.common.valid.AddGroup;
import com.bookstore.common.valid.AddShowStatusGroup;
import com.bookstore.common.valid.ListValue;
import com.bookstore.common.valid.UpdataGroup;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
@ -35,13 +38,13 @@ public class BrandEntity implements Serializable {
/**
*
*/
@NotBlank(message = "品牌不能为空", groups = {UpdataGroup.class})
@NotBlank(message = "品牌不能为空", groups = {UpdataGroup.class, AddGroup.class})
private String name;
/**
* logo
*/
@NotNull
@URL(message = "logo必须是一个合法的url地址")
@URL(message = "logo必须是一个合法的url地址", groups = {AddGroup.class, UpdataGroup.class})
private String logo;
/**
*
@ -50,16 +53,18 @@ public class BrandEntity implements Serializable {
/**
* [0-1-]
*/
@ListValue(vals={0, 1},groups = {AddShowStatusGroup.class, AddGroup.class}) //自己编写的校验注解
private Integer showStatus;
/**
*
*/
@Pattern(regexp = "/^[a-zA-Z]$/", message = "检索首字母必须是一个首字母")
@Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是一个首字母", groups = {AddGroup.class, UpdataGroup.class})
private String firstLetter;
/**
*
*/
@Min(value = 0, message="排序必须大于等于0")
@Min(value = 0, message="排序必须大于等于0", groups = {AddGroup.class, UpdataGroup.class})
private Integer sort;
}

@ -28,10 +28,19 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
* 2controller
* 3beanBindingResult.
* 4
* 1@NotNull(message = "修改时必须指定品牌id", groups = {UpdataGroup.class})
*
* 2controller使Validated
* 使Validated
*
* @controllerAdvice
* 1controllerAdvice
*
*
* 1
* 2
* 3
*
*
* */

@ -0,0 +1,4 @@
package com.bookstore.common.valid;
public interface AddShowStatusGroup {
}

@ -0,0 +1,21 @@
package com.bookstore.common.valid;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotNull;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ListValueConstraintValidator.class}) //这里填的是校验器,可以自己编写一个
@Documented
public @interface ListValue {
String message() default "{com.bookstore.common.valid.ListValue.message}"; //会在一个配置文件中取得错误消息我们用自己的所以添加一个ValidationMessages.properties
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] vals() default {};
}

@ -0,0 +1,38 @@
package com.bookstore.common.valid;
import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer>/*第一个泛型是校验注解,第二个泛型是校验类型*/ {
private Set<Integer> set = new HashSet<>();
//初始化方法,会将详细信息给我门
@Override
public void initialize(ListValue constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
int[] vals = constraintAnnotation.vals(); //获取数据
for (int i =0; i < vals.length; i++) {
set.add(vals[i]);
}
}
@Override
/*
@param value value
@param context
@return
* */
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
return value == null || set.contains(value);
}
}

@ -0,0 +1 @@
com.bookstore.common.valid.ListValue.message=必须提交的值

@ -0,0 +1,68 @@
<!-- -->
<template>
<!-- 每一个节点用catid区分 -->
<el-tree :data="menus" :props="defaultProps" node-key="catId" ref="menuTree" @node-click="nodeClick">
</el-tree>
</template>
<script>
//jsjsjson
//import from '';
export default {
//import使
components: {},
data() {
//
return {
name: 'Category',
menus: [],
expandedKey: [],
defaultProps: { //
children: 'children',
label: 'name'
},
};
},
// data
computed: {},
//data
watch: {},
//
methods: {
//
getDataList() {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get',
}).then(({ data }) => {
console.log("成功获取到菜单数据。。。", data.data);
this.menus = data.data;
})
},
nodeClick(data, node, component){
console.log("子组件的节点被点击:", data, node, component);
//
this.$emit("tree-node-click", data, node, component);
},
},
// - 访this
created() {
this.getDataList();
},
// - 访DOM
mounted() {
},
beforeCreate() { }, // -
beforeMount() { }, // -
beforeUpdate() { }, // -
updated() { }, // -
beforeDestroy() { }, // -
destroyed() { }, // -
activated() { }, //keep-alive
}
</script>

@ -0,0 +1,120 @@
<template>
<el-dialog
:title="!dataForm.attrGroupId ? '新增' : '修改'"
:close-on-click-modal="false"
:visible.sync="visible">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
<el-form-item label="组名" prop="attrGroupName">
<el-input v-model="dataForm.attrGroupName" placeholder="组名"></el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model="dataForm.sort" placeholder="排序"></el-input>
</el-form-item>
<el-form-item label="描述" prop="descript">
<el-input v-model="dataForm.descript" placeholder="描述"></el-input>
</el-form-item>
<el-form-item label="组图标" prop="icon">
<el-input v-model="dataForm.icon" placeholder="组图标"></el-input>
</el-form-item>
<el-form-item label="所属分类id" prop="catelogId">
<el-input v-model="dataForm.catelogId" placeholder="所属分类id"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()"></el-button>
</span>
</el-dialog>
</template>
<script>
export default {
data () {
return {
visible: false,
dataForm: {
attrGroupId: 0,
attrGroupName: '',
sort: '',
descript: '',
icon: '',
catelogId: ''
},
dataRule: {
attrGroupName: [
{ required: true, message: '组名不能为空', trigger: 'blur' }
],
sort: [
{ required: true, message: '排序不能为空', trigger: 'blur' }
],
descript: [
{ required: true, message: '描述不能为空', trigger: 'blur' }
],
icon: [
{ required: true, message: '组图标不能为空', trigger: 'blur' }
],
catelogId: [
{ required: true, message: '所属分类id不能为空', trigger: 'blur' }
]
}
}
},
methods: {
init (id) {
this.dataForm.attrGroupId = id || 0
this.visible = true
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
if (this.dataForm.attrGroupId) {
this.$http({
url: this.$http.adornUrl(`/product/attrgroup/info/${this.dataForm.attrGroupId}`),
method: 'get',
params: this.$http.adornParams()
}).then(({data}) => {
if (data && data.code === 0) {
this.dataForm.attrGroupName = data.attrGroup.attrGroupName
this.dataForm.sort = data.attrGroup.sort
this.dataForm.descript = data.attrGroup.descript
this.dataForm.icon = data.attrGroup.icon
this.dataForm.catelogId = data.attrGroup.catelogId
}
})
}
})
},
//
dataFormSubmit () {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
this.$http({
url: this.$http.adornUrl(`/product/attrgroup/${!this.dataForm.attrGroupId ? 'save' : 'update'}`),
method: 'post',
data: this.$http.adornData({
'attrGroupId': this.dataForm.attrGroupId || undefined,
'attrGroupName': this.dataForm.attrGroupName,
'sort': this.dataForm.sort,
'descript': this.dataForm.descript,
'icon': this.dataForm.icon,
'catelogId': this.dataForm.catelogId
})
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.visible = false
this.$emit('refreshDataList')
}
})
} else {
this.$message.error(data.msg)
}
})
}
})
}
}
}
</script>

@ -0,0 +1,179 @@
<!-- -->
<template>
<el-row :gutter="20">
<el-col :span="6">
<category @tree-node-click="treeNodeClick"></category>
</el-col>
<el-col :span="18">
<div class="mod-config">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()"></el-button>
<el-button v-if="isAuth('product:attrgroup:save')" type="primary"
@click="addOrUpdateHandle()">新增</el-button>
<el-button v-if="isAuth('product:attrgroup:delete')" type="danger" @click="deleteHandle()"
:disabled="dataListSelections.length <= 0">批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" border v-loading="dataListLoading" @selection-change="selectionChangeHandle"
style="width: 100%;">
<el-table-column type="selection" header-align="center" align="center" width="50">
</el-table-column>
<el-table-column prop="attrGroupId" header-align="center" align="center" label="分组id">
</el-table-column>
<el-table-column prop="attrGroupName" header-align="center" align="center" label="组名">
</el-table-column>
<el-table-column prop="sort" header-align="center" align="center" label="排序">
</el-table-column>
<el-table-column prop="descript" header-align="center" align="center" label="描述">
</el-table-column>
<el-table-column prop="icon" header-align="center" align="center" label="组图标">
</el-table-column>
<el-table-column prop="catelogId" header-align="center" align="center" label="所属分类id">
</el-table-column>
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
<template slot-scope="scope">
<el-button type="text" size="small"
@click="addOrUpdateHandle(scope.row.attrGroupId)">修改</el-button>
<el-button type="text" size="small"
@click="deleteHandle(scope.row.attrGroupId)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
:current-page="pageIndex" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" :total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate"
@refreshDataList="getDataList"></add-or-update>
</div>
</el-col>
</el-row>
</template>
<script>
/*
父子组件传递数据
1子组件给父组件传递数据事件机制
子组件给父子件发送一个事件携带上数据
*/
//jsjsjson
//import from '';
import Category from "../common/category.vue";
import AddOrUpdate from "./attrgroup-add-or-update.vue";
export default {
//import使
components: { Category, AddOrUpdate },
data() {
return {
dataForm: {
key: ''
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false
}
},
// data
//data
watch: {},
//
methods: {
//
treeNodeClick(data, node, component) {
console.log("attrgroup感知到节点被点击", data, node, component);
console.log("菜单id:", data.catId);
},
//
getDataList() {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/product/attrgroup/list'),
method: 'get',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'key': this.dataForm.key
})
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.page.list
this.totalPage = data.page.totalCount
} else {
this.dataList = []
this.totalPage = 0
}
this.dataListLoading = false
})
},
//
sizeChangeHandle(val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
//
currentChangeHandle(val) {
this.pageIndex = val
this.getDataList()
},
//
selectionChangeHandle(val) {
this.dataListSelections = val
},
// /
addOrUpdateHandle(id) {
this.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id)
})
},
//
deleteHandle(id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.attrGroupId
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/product/attrgroup/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}
},
}
</script>
Loading…
Cancel
Save