diff --git a/src/api/mall/product/category.ts b/src/api/mall/product/category.ts
new file mode 100644
index 00000000..7ae81285
--- /dev/null
+++ b/src/api/mall/product/category.ts
@@ -0,0 +1,60 @@
+import request from '@/config/axios'
+
+/**
+ * 产品分类
+ */
+export interface CategoryVO {
+ /**
+ * 分类编号
+ */
+ id?: number
+ /**
+ * 父分类编号
+ */
+ parentId?: number
+ /**
+ * 分类名称
+ */
+ name: string
+ /**
+ * 分类图片
+ */
+ picUrl: string
+ /**
+ * 分类排序
+ */
+ sort?: number
+ /**
+ * 分类描述
+ */
+ description?: string
+ /**
+ * 开启状态
+ */
+ status: number
+}
+
+// 创建商品分类
+export const createCategory = (data: CategoryVO) => {
+ return request.post({ url: '/product/category/create', data })
+}
+
+// 更新商品分类
+export const updateCategory = (data: CategoryVO) => {
+ return request.put({ url: '/product/category/update', data })
+}
+
+// 删除商品分类
+export const deleteCategory = (id: number) => {
+ return request.delete({ url: `/product/category/delete?id=${id}` })
+}
+
+// 获得商品分类
+export const getCategory = (id: number) => {
+ return request.get({ url: `/product/category/get?id=${id}` })
+}
+
+// 获得商品分类列表
+export const getCategoryList = (params: any) => {
+ return request.get({ url: '/product/category/list', params })
+}
diff --git a/src/views/mall/product/category/form.vue b/src/views/mall/product/category/form.vue
new file mode 100644
index 00000000..e2b6f62a
--- /dev/null
+++ b/src/views/mall/product/category/form.vue
@@ -0,0 +1,149 @@
+
+
+
+
diff --git a/src/views/mall/product/category/index.vue b/src/views/mall/product/category/index.vue
new file mode 100644
index 00000000..12f51cff
--- /dev/null
+++ b/src/views/mall/product/category/index.vue
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/mall/product/category/utils.ts b/src/views/mall/product/category/utils.ts
new file mode 100644
index 00000000..a3774f22
--- /dev/null
+++ b/src/views/mall/product/category/utils.ts
@@ -0,0 +1,44 @@
+export const parseTime = (time) => {
+ if (!time) {
+ return null
+ }
+ const format = '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
+ time = parseInt(time)
+ } else if (typeof time === 'string') {
+ time = time
+ .replace(new RegExp(/-/gm), '/')
+ .replace('T', ' ')
+ .replace(new RegExp(/\.[\d]{3}/gm), '')
+ }
+ if (typeof time === 'number' && time.toString().length === 10) {
+ time = time * 1000
+ }
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') {
+ return ['日', '一', '二', '三', '四', '五', '六'][value]
+ }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}