diff --git a/.env.development b/.env.development index 6f56968..84a632c 100644 --- a/.env.development +++ b/.env.development @@ -5,5 +5,5 @@ VITE_APP_TITLE = 运营云后台管理系统 VITE_APP_ENV = 'development' # 开发环境 -VITE_APP_BASE_API = 'http://192.168.18.99:8080/' +VITE_APP_BASE_API = 'http://192.168.18.151:8080' VITE_APP_PLATFORM = 'http://localhost:9000/platform' \ No newline at end of file diff --git a/.env.production b/.env.production index 281197b..5b5b061 100644 --- a/.env.production +++ b/.env.production @@ -5,7 +5,7 @@ VITE_APP_TITLE = 运营云后台管理系统 VITE_APP_ENV = 'production' # 生产环境 -VITE_APP_BASE_API = 'http://47.109.205.240:8080/' +VITE_APP_BASE_API = 'http://47.109.205.240:8080' VITE_APP_PLATFORM = 'http://47.109.205.240/platform' # 是否在打包时开启压缩,支持 gzip 和 brotli diff --git a/package.json b/package.json index e5623d3..1aeedc3 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "vue": "3.4.31", "vue-cropper": "1.1.1", "vue-router": "4.4.0", - "vuedraggable": "4.1.0" + "vuedraggable": "^4.1.0" }, "devDependencies": { "@vitejs/plugin-vue": "5.0.5", diff --git a/src/api/goods/info.js b/src/api/goods/info.js index 46c79d7..861fc76 100644 --- a/src/api/goods/info.js +++ b/src/api/goods/info.js @@ -2,14 +2,23 @@ import request from '@/utils/request' // 获取商品管理列表 export function getGoodManageInfo(query) { + console.log(query) return request({ - url: '/goodInfoManage/getGoodManage', + url: '/goods/goodInfoManage/getGoodManage', method: 'get', params: query }) } - +// 获取商品分类列表 +export function getGoodType(query) { + console.log(query) + return request({ + url: '/goods/goodInfoManage/goodType', + method: 'get', + params: query + }) +} diff --git a/src/assets/styles/custom.scss b/src/assets/styles/custom.scss index 14e520d..f466efa 100644 --- a/src/assets/styles/custom.scss +++ b/src/assets/styles/custom.scss @@ -174,24 +174,30 @@ cursor: pointer; transition: all 0.3s; } - // 表格中文本的颜色 - .color-gray { - color: #5a5a5a; - } - .color-orange { - color: orange; - } - .color-green { - color: green; - } - .color-red { - color: red; - } - } - .el-button { - font-size: 12px !important; - font-weight: 400; } + // 表格中文本的颜色 + .color-blue { + color: #3685fe; + } + .color-black { + color: #000000; + } + .color-gray { + color: #5a5a5a; + } + .color-orange { + color: #ffb345; + } + .color-green { + color: #25bf82; + } + .color-red { + color: #ff4348; + } +} +.el-button { + font-size: 12px !important; + font-weight: 400; } // 页面添加的自定义容器,上下撑满 .customer-control { @@ -217,12 +223,53 @@ width: 60px; height: 60px; overflow: hidden; /* 隐藏超出部分 */ - display: flex; /* 使用 Flex 布局居中 */ + display: flex; /* 使用 Flex 布局居中 */ justify-content: center; align-items: center; .table-cell-img { - min-width: 100%; /* 至少撑满宽度 */ + min-width: 100%; /* 至少撑满宽度 */ min-height: 100%; /* 至少撑满高度 */ object-fit: cover; /* 保持比例并覆盖容器 */ } } + +// 新增商品页面-开始 +.customer-box { + height: 100%; + border-radius: 16px; + padding: 20px 16px; + overflow-y: auto; + background-color: #fff; + .my-el-select { + width: 200px; + } + .el-input-number .el-input__inner { + text-align: left; + } + // 商品属性 + .attr-item { + display: inline-block; + margin-right: 10px; + .el-icon { + vertical-align: middle; + margin: 5px; + } + } + .attr-row { + display: flex; + flex-direction: row; + justify-content: flex-start; + flex-wrap: nowrap; + gap: 10px; + margin-bottom: 10px; + } + .attr-input { + width: 120px; + } + .attr-box { + padding: 16px 16px 6px 16px; + border-radius: 6px; + border: 1px solid #999; + } +} +// 新增商品页面-结束 diff --git a/src/components/myUploadImage.vue b/src/components/myUploadImage.vue new file mode 100644 index 0000000..435908c --- /dev/null +++ b/src/components/myUploadImage.vue @@ -0,0 +1,387 @@ + + + 图片比例1:1,建议尺寸为800 * 800px,支持png、jpg、gif等格式,大小2MB以内 + + + + + 上传图片 + + + + + + + + + + 主图 + + + + + + + + + 删除 + + + + + 至多可上传{{ limit }}张图片 + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/myUploadVideo.vue b/src/components/myUploadVideo.vue new file mode 100644 index 0000000..3ccac7d --- /dev/null +++ b/src/components/myUploadVideo.vue @@ -0,0 +1,286 @@ + + + + 建议比例1:1,不超过60s,视频200MB以内 + + + + + + 上传视频 + + + + + + + + {{ getFileName(file.name) }} + + + 删除 + + + + + + + + diff --git a/src/components/tableComponent.vue b/src/components/tableComponent.vue index 7c065f4..6c640b8 100644 --- a/src/components/tableComponent.vue +++ b/src/components/tableComponent.vue @@ -39,6 +39,11 @@ width="55" align="center" /> + + + {{ (currentPage - 1) * pageSize + $index + 1 }} + + - + - + - + - + - + - + - + - + - + - + - + - - - + + + - - + - 查询 - 重置 + 查询 + 重置 - + - 正常 - 异常 + 正常 + 异常 - + - + - + - + - + + + @@ -330,12 +240,22 @@ const generateMockData = () => { }).list; }; // 加载数据 -const loadData = () => { +const loadData = async () => { // 模拟API请求延迟 setTimeout(() => { tableData.value = generateMockData(); tableTotal.value = tableData.value.length; }, 500); + // try { + // let response = await getGoodManageInfo(formInline); + // console.log(response); + // if (response.code == 200) { + // tableData.value = response.data.records; + // tableTotal.value = response.data.total; + // } + // } catch (error) { + // console.log(error); + // } }; // 自定义表头类名,也可以在columns指定列中添加headerClassName: 'custom-header' const getHeaderClass = ({ column }) => { diff --git a/src/views/goods/addGoods.vue b/src/views/goods/addGoods.vue index 3c0f3cd..9170802 100644 --- a/src/views/goods/addGoods.vue +++ b/src/views/goods/addGoods.vue @@ -1,145 +1,539 @@ - + + + - - - - + + + + - - - + - - - + - + + + + + + + + + + + + + + + + + + + 单规格 + 多规格 + + + + + + + 元 + + + + + + + + + + + + + + + + + + + +多规格 + + + + + + + + + + + + 添加属性 + + + + + + 属性名称 + 属性内容 + + + {{ item.name }} + + + + + + + + + + + + + + + + + + + + + {{ item.text }} + + + + + + + + {{ + item.text }} + + + + + {{ + item.text }} + + + + + + + + + + + + + + + + + 确认新增 - +// 选中的省市区编码数组(如:['云南省', '昆明市', '呈贡区']) +const selectedAddress = ref([]); +const detailAddress = ref(''); +// 级联选择器配置 +const cascaderProps = ref({ + value: 'name', // 选项值字段名 + label: 'name', // 选项标签字段名 + children: 'children' // 子选项字段名 +}); +// 省市区数据(示例) +const addressOptions = ref([ + { + name: '云南省', + children: [ + { + name: '昆明市', + children: [ + { name: '五华区' }, + { name: '盘龙区' }, + { name: '呈贡区' } + ] + }, + { + name: '曲靖市', + children: [ + { name: '麒麟区' }, + { name: '沾益区' } + ] + } + ] + }, + { + name: '广东省', + children: [ + { + name: '广州市', + children: [ + { name: '天河区' }, + { name: '越秀区' } + ] + } + ] + } + // 其他省份数据... +]); + +// 保障服务 +const isSafeguardSelected = computed({ + get: () => formInline.safeguard.isSelected === 1, + set: (val) => { + formInline.safeguard.isSelected = val ? 1 : 0 + } +}) +// 优惠设置 +const isDiscountSettings = computed({ + get: () => formInline.discountSettings.isSelected === 1, + set: (val) => { + formInline.discountSettings.isSelected = val ? 1 : 0 + } +}) +// 优惠折扣 +const isDiscountRebate = computed({ + get: () => formInline.discountRebate.isSelected === 1, + set: (val) => { + formInline.discountRebate.isSelected = val ? 1 : 0 + } +}) + +// 文件上传前的校验 +// const beforeUpload = (file) => { +// const isImage = ['image/jpeg', 'image/png', 'image/gif'].includes(file.type) +// const isLt2M = file.size / 1024 / 1024 < 2 + +// if (!isImage) { +// ElMessage.error('只能上传JPG/PNG/GIF格式的图片!') +// return false +// } +// if (!isLt2M) { +// ElMessage.error('图片大小不能超过2MB!') +// return false +// } +// return true +// } +// 文件变化时触发验证 +// const handleChange = () => { +// console.log('文件变化时触发验证') +// nextTick(() => { +// console.log(formInline.images) +// formRef.value.validateField('images') +// }) +// } +// 移除文件时触发验证 +// const handleRemove = (file) => { +// console.log('移除文件时触发验证') +// console.log(file) +// console.log(formInline.images) +// formInline.images = formInline.images.filter(item => item.uid !== file.uid) +// formRef.value.validateField('images') +// } +// 超出限制提示 +// const handleExceed = () => { +// ElMessage.warning('最多只能上传5张图片!') +// } + +const categoryList1 = ref([]); +const categoryList2 = ref([]); +const categoryList3 = ref([]); + +const getGoodTypeList = async () => { + try { + let response = await getGoodType(); + console.log(response); + if (response.code == 200) { + categoryList1.value = response.data; + } + } catch (error) { + console.log(error); + } +}; +const changeCategory1 = (id) => { + console.log(id); + formInline.categoryId1 = id; + formInline.categoryId2 = ""; + categoryList2.value = categoryList1.value.filter((item) => item.id == id)[0].children; + formInline.categoryId3 = ""; + formInline.categoryId = ""; + categoryList3.value = []; + if (id == 70) { + // 选择产出品 + formInline.goodCategorySelectType = 1; + } else { + // 选择投入品 + formInline.goodCategorySelectType = 2; + } +}; +const changeCategory2 = (id) => { + console.log(id); + formInline.categoryId2 = id; + categoryList3.value = categoryList2.value.filter((item) => item.id == id)[0].children; + formInline.categoryId3 = ""; + formInline.categoryId = ""; +}; +const changeCategory3 = (id) => { + console.log(id); + formInline.categoryId3 = id; + formInline.categoryId = id; +}; + +const onSave = async () => { + console.log(formInline); + // formRef.validate(valid => { + // if (!valid) return + // console.log('验证通过!', formRef.value) + // }) + try { + await formRef.value.validate() + console.log('验证通过!', formRef.value) + // 整理提交的参数 + + // 调用接口提交 + + } catch (error) { + console.log('验证失败', error) + } +}; + +const getGoodTypeList2 = async () => { + const res = await getGoodType({ + pageNum: 1, + pageSize: 100, + }); + if (res.code === 200) { + goodTypeList.value = res.data.list; + } +}; + +onMounted(() => { + getGoodTypeList(); +}); + + diff --git a/src/views/goods/goodsCategory.vue b/src/views/goods/goodsCategory.vue index b690015..5e4976d 100644 --- a/src/views/goods/goodsCategory.vue +++ b/src/views/goods/goodsCategory.vue @@ -106,6 +106,7 @@ :total="tableTotal" :current-page="formInline.current" :page-size="formInline.size" + :showSort="true" > diff --git a/src/views/goods/goodsManage.vue b/src/views/goods/goodsManage.vue index d3e3303..5b5cf0b 100644 --- a/src/views/goods/goodsManage.vue +++ b/src/views/goods/goodsManage.vue @@ -7,118 +7,63 @@ - + - - - + + + - - - + + + - - - + + + - 查询 - 重置 + 查询 + 重置 - 批量删除 + 批量删除 - 新增商品 + 新增商品 - + - + - + + + + ¥{{ slotProps.row.goodPrice }} + - - 上架 - 下架 + + 待上架 + 已上架 + 上架 + 下架 + 审核中 @@ -126,34 +71,19 @@ - + - + - + - + - + @@ -175,14 +105,14 @@ import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue"; import tableComponent from "@/components/tableComponent.vue"; import Mock from "mockjs"; -import { getGoodManageInfo } from "@/api/goods/info"; +import { getGoodManageInfo, getGoodType } from "@/api/goods/info"; import { ca } from "element-plus/es/locales.mjs"; const formInline = reactive({ - goodsName: "", - goodsCategoryId: "", - goodsBrandId: "", - serachType: "1", + goodName: "", + goodCategoryId: "", + storeId: "", + type: "1", current: 1, size: 10, }); @@ -218,13 +148,13 @@ const tabChange = (Event) => { console.log(Event.index); if (Event.index == "0") { // 请求全部 - formInline.serachType = "1"; + formInline.type = "1"; } else if (Event.index == "1") { // 请求已上架 - formInline.serachType = "2"; - } else { + formInline.type = "2"; + } else if (Event.index == "2"){ // 请求已下架 - formInline.serachType = "3"; + formInline.type = "3"; } loadData(); }; @@ -241,16 +171,15 @@ let nowClickRow = ref({}); // 列配置 const columns = ref([]); const columns1 = ref([ - { prop: "sort", label: "排序" }, - { prop: "id", label: "ID" }, - { prop: "goodsUrl", label: "商品图片", slotName: "goodsUrl" }, - { prop: "goodsName", label: "商品名称", width: "120" }, + { prop: "goodId", label: "ID", width: "150" }, + { prop: "goodUrl", label: "商品图片", slotName: "goodUrl" }, + { prop: "goodName", label: "商品名称", width: "120" }, { prop: "categoryName", label: "分类名称" }, - { prop: "goodsPrice", label: "商品售价" }, + { prop: "goodPrice", label: "商品售价" }, { prop: "salesVolume", label: "销量" }, { prop: "pageView", label: "浏览量" }, - { prop: "inventory", label: "库存" }, - { prop: "goodsStatus", label: "状态", slotName: "goodsStatus" }, + { prop: "stock", label: "库存" }, + { prop: "isListed", label: "状态", slotName: "isListed" }, { prop: "action", label: "操作", slotName: "action" }, ]); @@ -282,16 +211,16 @@ const generateMockData = () => { return Mock.mock({ "list|10": [ { - "id|+1": 10000, + "goodId|+1": 10000, "sort|+1": 1, - goodsUrl: " @image", //商品图片 - goodsName: () => generateFoodNickname(), //商品名称 + goodUrl: " @image", //商品图片 + goodName: () => generateFoodNickname(), //商品名称 categoryName: '@pick(["蔬菜", "肥料", "农药"])', //分类名称 - goodsPrice: "@float(10, 200, 2, 2)", //商品售价 + goodPrice: "@float(10, 200, 2, 2)", //商品售价 salesVolume: "@integer(1000, 20000)", //销量 pageView: Mock.mock("@id").toString().slice(0, 6), //浏览量 - inventory: "@integer(5000, 90000)", //库存 - goodsStatus: '@pick(["上架", "下架"])', //状态 + stock: "@integer(5000, 90000)", //库存 + isListed: '@pick(["上架", "下架"])', //状态 ordersNums: "@integer(10, 200)", }, ], @@ -300,18 +229,18 @@ const generateMockData = () => { // 加载数据 const loadData = async () => { tableLoading.value = true; - tableData.value = generateMockData(); - tableTotal.value = tableData.value.length; - // try { - // let response = await getGoodManageInfo(formInline); - // console.log(response); - // if (response.code == 200) { - // tableData.value = response.data.records; - // tableTotal.value = response.data.total; - // } - // } catch (error) { - // console.log(error); - // } + // tableData.value = generateMockData(); + // tableTotal.value = tableData.value.length; + try { + let response = await getGoodManageInfo(formInline); + console.log(response); + if (response.code == 200) { + tableData.value = response.data.records; + tableTotal.value = response.data.total; + } + } catch (error) { + console.log(error); + } tableLoading.value = false; }; @@ -339,10 +268,10 @@ const seeDetails = (row) => { console.log("要查看详情的行:", row); }; const toUpload = () => { - console.log("向上移动:"); + console.log("上架:"); }; const toDownload = () => { - console.log("向下移动:"); + console.log("下架:"); }; // 编辑操作 const handleEdit = (row) => { diff --git a/vite.config.js b/vite.config.js index 7701c1f..f86c245 100644 --- a/vite.config.js +++ b/vite.config.js @@ -46,10 +46,10 @@ export default defineConfig(({ mode, command }) => { open: true, proxy: { // https://cn.vitejs.dev/config/#server-proxy - '/api': { + '/apis': { target: VITE_APP_BASE_API, changeOrigin: true, - rewrite: (p) => p.replace(/^\/api/, '') + rewrite: (p) => p.replace(/^\/apis/, '') }, // springdoc proxy '^/v3/api-docs/(.*)': {