Skip to content

Commit cc9d906

Browse files
committed
编辑商品分类前端页面已完成
1 parent 2cfa502 commit cc9d906

File tree

11 files changed

+287
-65
lines changed

11 files changed

+287
-65
lines changed

go/controller/category/category.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func Save(ctx *iris.Context) {
119119
return
120120
}
121121

122-
var categoryJSON model.Category = category
122+
var categoryJSON = category
123123
if createOrUpdate == "update" {
124124
categoryJSON = updatedCategory
125125
}

go/controller/ueditor/config.json go/controller/ueditor/config.go

+16-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
/* 前后端通信相关的配置,注释只允许使用多行方式 */
2-
{
1+
package ueditor
2+
3+
// UEditor 前后端通信相关的配置,注释只允许使用多行方式
4+
var UEditor = map[string]interface{}{
35
/* 上传图片配置项 */
46
"imageActionName": "uploadImage", /* 执行上传图片的action名称 */
57
"imageFieldName": "upFile", /* 提交的图片表单名称 */
68
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
7-
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
9+
"imageAllowFiles": []string{".png", ".jpg", ".jpeg", ".gif", ".bmp"}, /* 上传图片格式显示 */
810
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
911
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
1012
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
@@ -38,57 +40,56 @@
3840
"snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
3941

4042
/* 抓取远程图片配置 */
41-
"catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
43+
"catcherLocalDomain": []string{"127.0.0.1", "localhost", "img.baidu.com"},
4244
"catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
4345
"catcherFieldName": "source", /* 提交的图片列表表单名称 */
4446
"catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
4547
"catcherUrlPrefix": "", /* 图片访问路径前缀 */
4648
"catcherMaxSize": 2048000, /* 上传大小限制,单位B */
47-
"catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
49+
"catcherAllowFiles": []string{".png", ".jpg", ".jpeg", ".gif", ".bmp"}, /* 抓取图片格式显示 */
4850

4951
/* 上传视频配置 */
5052
"videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
5153
"videoFieldName": "upfile", /* 提交的视频表单名称 */
5254
"videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
5355
"videoUrlPrefix": "", /* 视频访问路径前缀 */
5456
"videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
55-
"videoAllowFiles": [
57+
"videoAllowFiles": []string{
5658
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
57-
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
59+
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"}, /* 上传视频格式显示 */
5860

5961
/* 上传文件配置 */
6062
"fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
6163
"fileFieldName": "upfile", /* 提交的文件表单名称 */
6264
"filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
6365
"fileUrlPrefix": "", /* 文件访问路径前缀 */
6466
"fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
65-
"fileAllowFiles": [
67+
"fileAllowFiles": []string{
6668
".png", ".jpg", ".jpeg", ".gif", ".bmp",
6769
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
6870
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
6971
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
70-
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
71-
], /* 上传文件格式显示 */
72+
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml",
73+
}, /* 上传文件格式显示 */
7274

7375
/* 列出指定目录下的图片 */
7476
"imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
7577
"imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
7678
"imageManagerListSize": 20, /* 每次列出文件数量 */
7779
"imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
7880
"imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
79-
"imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
81+
"imageManagerAllowFiles": []string{".png", ".jpg", ".jpeg", ".gif", ".bmp"}, /* 列出的文件类型 */
8082

8183
/* 列出指定目录下的文件 */
8284
"fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
8385
"fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
8486
"fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
8587
"fileManagerListSize": 20, /* 每次列出文件数量 */
86-
"fileManagerAllowFiles": [
88+
"fileManagerAllowFiles": []string{
8789
".png", ".jpg", ".jpeg", ".gif", ".bmp",
8890
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
8991
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
9092
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
91-
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
92-
] /* 列出的文件类型 */
93-
93+
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml",
94+
}, /* 列出的文件类型 */
9495
}

go/controller/ueditor/ueditor.go

+1-32
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,18 @@
11
package ueditor
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"io"
7-
"io/ioutil"
86
"mime"
97
"os"
108
"time"
119
"strconv"
1210
"strings"
13-
"regexp"
1411
"gopkg.in/kataras/iris.v6"
1512
"github.com/satori/go.uuid"
1613
"wemall/go/config"
1714
"wemall/go/utils"
1815
)
19-
20-
func readConfig(filename string) (map[string]interface{}, error) {
21-
bytes, err := ioutil.ReadFile(filename)
22-
if err != nil {
23-
fmt.Println("ReadFile: ", err.Error())
24-
return nil, err
25-
}
26-
27-
configStr := string(bytes[:])
28-
reg := regexp.MustCompile(`/\*.*\*/`)
29-
30-
configStr = reg.ReplaceAllString(configStr, "")
31-
bytes = []byte(configStr)
32-
33-
var result map[string]interface{}
34-
35-
if err := json.Unmarshal(bytes, &result); err != nil {
36-
fmt.Println("Unmarshal: ", err.Error())
37-
return nil, err
38-
}
39-
return result, nil
40-
}
4116

4217
func upload(ctx *iris.Context) {
4318
errResData := iris.Map{
@@ -141,13 +116,7 @@ func Handler(ctx *iris.Context) {
141116
action := ctx.FormValue("action")
142117
switch action {
143118
case "config": {
144-
var result map[string]interface{}
145-
var err error
146-
if result, err = readConfig("./go/controller/ueditor/config.json"); err != nil {
147-
ctx.JSON(iris.StatusOK, iris.Map{})
148-
return
149-
}
150-
ctx.JSON(iris.StatusOK, result)
119+
ctx.JSON(iris.StatusOK, UEditor)
151120
break
152121
}
153122
case "uploadImage": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
REQUEST_SAVE_CATEGORY,
3+
REQUEST_SAVE_CATEGORY_SUCCESS,
4+
} from '../../constants';
5+
6+
function receive(data) {
7+
return {
8+
type : REQUEST_SAVE_CATEGORY_SUCCESS,
9+
category : data.category
10+
};
11+
}
12+
13+
export default function(category) {
14+
return dispatch => {
15+
var url = pageConfig.apiPath + '/admin/category/update';
16+
return fetch(url, {
17+
method: 'POST',
18+
headers: {
19+
'Accept': 'application/json',
20+
'Content-Type': 'application/json'
21+
},
22+
body: JSON.stringify(category)
23+
})
24+
.then(response => response.json())
25+
.then(json => dispatch(receive(json.data)));
26+
};
27+
};
28+

nodejs/static/javascripts/admin/actions/product/requestSaveProduct.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ export default function(product) {
1515
var url = pageConfig.apiPath + '/admin/product/update';
1616
var categories = [];
1717
for (var i = 0; i < product.categories.length; i++) {
18+
var idArr = product.categories[i].split('-');
1819
categories.push({
19-
id: parseInt(product.categories[i].split('-')[1])
20+
id: parseInt(idArr[idArr.length - 1])
2021
});
2122
}
2223
var reqData ={
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import React, { Component } from 'react';
2+
import { connect } from 'react-redux';
3+
4+
import {
5+
Button,
6+
Row,
7+
Col,
8+
Form,
9+
Input,
10+
InputNumber,
11+
TreeSelect
12+
} from 'antd';
13+
14+
import requestCategory from '../../actions/category/requestCategory';
15+
import requestSaveCategory from '../../actions/category/requestSaveCategory';
16+
import requestCategoryList from '../../actions/category/requestCategoryList';
17+
import Software from '../Software';
18+
import utils from '../../utils';
19+
import analyze from '../../../sdk/analyze';
20+
import '../../../../styles/admin/category/editCategory.css';
21+
22+
/*
23+
* 管理后台,新建或编辑商品分类
24+
*/
25+
class EitCategory extends Component {
26+
constructor(props) {
27+
super(props);
28+
this.onNameBlur = this.onNameBlur.bind(this);
29+
this.onCategoryChange = this.onCategoryChange.bind(this);
30+
this.onRemarkBlur = this.onRemarkBlur.bind(this);
31+
this.onSubmit = this.onSubmit.bind(this);
32+
33+
this.state = {
34+
categoryId : this.props.routeParams.id,
35+
parentId : '',
36+
parentKey : [], //父分类, 初始为数组是为了让树形控件显示placeholder
37+
name : '',
38+
remark : '',
39+
treeData : []
40+
};
41+
}
42+
componentDidMount() {
43+
analyze.pv();
44+
const { dispatch } = this.props;
45+
if (this.state.categoryId) {
46+
dispatch(requestCategory(this.state.categoryId));
47+
}
48+
dispatch(requestCategoryList());
49+
}
50+
componentWillReceiveProps(nextProps) {
51+
var category = nextProps.data.category;
52+
var categories = nextProps.data.categories;
53+
if (category && categories && categories.length > 0) {
54+
this.setState({
55+
categoryId : category.id,
56+
parentId : category.parentId,
57+
parentKey : utils.parseTreeNodeKey(categories, category.parentId),
58+
name : category.name,
59+
remark : category.remark,
60+
treeData : utils.parseTree(categories, {
61+
withRoot: true
62+
})
63+
});
64+
}
65+
}
66+
onNameBlur(event) {
67+
this.setState({ name: event.target.value });
68+
}
69+
onCategoryChange(value) {
70+
var arr = value.split('-');
71+
this.setState({
72+
parentId : arr[arr.length - 1],
73+
parentKey : value
74+
});
75+
}
76+
onRemarkBlur(event) {
77+
this.setState({ remark: event.target.value });
78+
}
79+
onSubmit() {
80+
const { dispatch } = this.props;
81+
dispatch(requestSaveCategory({
82+
id : this.state.categoryId,
83+
name : this.state.name,
84+
parentId : this.state.parentId,
85+
remark : this.state.remark
86+
}));
87+
}
88+
render() {
89+
let { data } = this.props;
90+
let editLabel = this.state.categoryId ? '编辑' : '添加';
91+
let isLoading = this.state.categoryId
92+
&& (!data.category || !data.categories || data.categories.length <= 0)
93+
? true : false;
94+
95+
let name = this.state.name;
96+
let remark = this.state.remark;
97+
let treeData = this.state.treeData;
98+
99+
const FormItem = Form.Item;
100+
const formItemLayout = {
101+
labelCol: {
102+
xs: { span: 24 },
103+
sm: { span: 3 },
104+
},
105+
wrapperCol: {
106+
xs: { span: 24 },
107+
sm: { span: 12 },
108+
}
109+
};
110+
111+
return (
112+
<div>
113+
<Row gutter={24}>
114+
<Col span={24}>
115+
<div className="category-box">
116+
<div className="category-title">{editLabel}商品分类</div>
117+
{
118+
isLoading ? null :
119+
<Form>
120+
<FormItem {...formItemLayout} label="名称">
121+
<Input defaultValue={name} onBlur={this.onNameBlur}/>
122+
</FormItem>
123+
<FormItem {...formItemLayout} label="父分类">
124+
<TreeSelect
125+
style={{ width: '100%' }}
126+
value={this.state.parentKey}
127+
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
128+
treeData={treeData}
129+
placeholder="请选择父分类"
130+
treeDefaultExpandAll
131+
onChange={this.onCategoryChange} />
132+
</FormItem>
133+
<FormItem {...formItemLayout} label="备注">
134+
<Input type="textarea" defaultValue={remark} rows={4} onBlur={this.onRemarkBlur}/>
135+
</FormItem>
136+
</Form>
137+
}
138+
</div>
139+
</Col>
140+
<Col span={24}>
141+
<Col span={15} className="submit-box">
142+
<Button onClick={this.onSubmit} type="primary" size="large">保存</Button>
143+
<Button className="submit-cancel-btn" size="large">取消</Button>
144+
</Col>
145+
</Col>
146+
</Row>
147+
<Software />
148+
</div>
149+
);
150+
}
151+
}
152+
153+
const mapStateToProps = (state) => {
154+
return {
155+
data: state.category
156+
};
157+
}
158+
159+
export default connect(mapStateToProps)(EitCategory);
160+

nodejs/static/javascripts/admin/containers/product/EditProduct.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ class EditProduct extends Component {
9292
});
9393
}
9494
componentWillReceiveProps(nextProps) {
95-
var product = nextProps.data.product;
96-
if (product) {
95+
var product = nextProps.data.product;
96+
var allCategories = nextProps.data.categories;
97+
if (product && allCategories && allCategories.length > 0) {
9798
var categories = [];
9899
for (var i = 0; i < product.categories.length; i++) {
99100
var parentId = product.categories[i].parentId;
100101
var id = product.categories[i].id;
101-
categories.push(parentId + '-' + id);
102+
categories.push(utils.parseTreeNodeKey(allCategories, id));
102103
}
103104
this.setState({
104105
productId : product.id,
@@ -186,7 +187,7 @@ class EditProduct extends Component {
186187
}
187188
};
188189

189-
let treeData = utils.parseCategoryTree(data.categories);
190+
let treeData = utils.parseTree(data.categories);
190191

191192
const treeProps = {
192193
treeData,

nodejs/static/javascripts/admin/reducers/category.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
} from '../constants';
88

99
let initState = {
10-
category : null,
11-
categories : []
10+
category : null,
11+
categories : []
1212
};
1313

1414
export default (state = initState, action) => {

0 commit comments

Comments
 (0)