+
-
- 商品
-
-
- 成交单价/购买数量
-
-
- 实付金额
-
-
- 支付方式
-
-
- 订单状态
-
-
- 操作
-
+ 商品
+ 成交单价/购买数量
+ 实付金额
+ 支付方式
+ 订单状态
+ 操作
-
+
+
+
+
订单编号:{{ order.orderNumber }}
下单时间:{{ order.createTime }}
+
+
+
-
+
-
![]()
+
{{ orderItem.prodName }}
@@ -123,10 +84,9 @@
-
+
+
+
¥{{ order.actualTotal }}
@@ -135,10 +95,9 @@
-
+
+
+
微信支付
@@ -147,47 +106,24 @@
-
+
+
+
- 待付款
- 待发货
- 待收货
- 待评价
- 成功
- 失败
+ 待付款
+ 待发货
+ 待收货
+ 待评价
+ 成功
+ 失败
-
+
+
+
-
+
查看
@@ -195,6 +131,8 @@
+
+
-
-
+
+
+
暂无数据
+
+
-
-
-
+
+
+
+
+
+
diff --git a/front-end/mall4v/src/views/modules/prod/prodComm/add-or-update.vue b/front-end/mall4v/src/views/modules/prod/prodComm/add-or-update.vue
index e84dd22..1fd56f1 100644
--- a/front-end/mall4v/src/views/modules/prod/prodComm/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodComm/add-or-update.vue
@@ -1,156 +1,130 @@
+
-
-
-
-
-
-
-
-
- 无
-
-
-
![]()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ 无
+
+
![]()
-
-
- 是
-
-
- 不是
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+ 是
+ 不是
+
+
+
-
+
+
+
+
+
+
+
+ 审核通过
+ 不通过
+ 等待审核
+
+
+
+
+
+
+
+
diff --git a/front-end/mall4v/src/views/modules/prod/prodComm/index.vue b/front-end/mall4v/src/views/modules/prod/prodComm/index.vue
index b2154a1..5f1ce3e 100644
--- a/front-end/mall4v/src/views/modules/prod/prodComm/index.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodComm/index.vue
@@ -1,41 +1,49 @@
+
+
+ :data="dataList"
+ :table-loading="dataListLoading"
+ :option="tableOption"
+ @search-change="onSearch"
+ @on-load="getDataList"
+ @refresh-change="refreshChange"
+ @row-del="rowDel"
>
-
- {{ scope.row.user.nickName }}
-
-
- {{ scope.row.replyTime ? scope.row.replyTime : '-' }}
-
+
+
+ {{ scope.row.user.nickName }}
+
-
-
- 编辑
-
+
+
+ {{ scope.row.replyTime ? scope.row.replyTime : '-' }}
+
-
- 查看
-
-
+
+
+
+ 编辑
+
+
+
+ 查看
+
+
+
+
import { ElMessage, ElMessageBox } from 'element-plus'
-import { tableOption } from '@/crud/prod/prodComm.js'
+import { tableOption } from '@/crud/prod/prodComm.js' // 导入表格配置项
import AddOrUpdate from './add-or-update.vue'
+// 表格数据引用
const dataList = ref([])
+
+// 分页对象
const page = reactive({
- total: 0, // 总页数
- currentPage: 1, // 当前页数
- pageSize: 20 // 每页显示多少条
+ total: 0, // 总记录数
+ currentPage: 1, // 当前页码
+ pageSize: 20 // 每页显示条数
})
+
+// 数据加载状态引用
const dataListLoading = ref(false)
+/**
+ * 获取数据列表方法
+ * @param pageParam - 分页参数
+ * @param params - 搜索参数
+ * @param done - 完成回调函数
+ */
const getDataList = (pageParam, params, done) => {
- dataListLoading.value = true
+ dataListLoading.value = true // 设置加载状态为true
+
http({
url: http.adornUrl('/prod/prodComm/page'),
method: 'get',
@@ -68,24 +88,33 @@ const getDataList = (pageParam, params, done) => {
}, params))
})
.then(({ data }) => {
- dataList.value = data.records
- page.total = data.total
- dataListLoading.value = false
- if (done) done()
+ dataList.value = data.records // 将获取的数据赋值给dataList
+ page.total = data.total // 更新总记录数
+ dataListLoading.value = false // 设置加载状态为false
+ if (done) done() // 如果有完成回调,则调用
})
}
+// 控制弹窗显示与隐藏
const addOrUpdateVisible = ref(false)
const addOrUpdateRef = ref(null)
+
/**
- * 新增 / 修改
+ * 新增或修改操作
+ * @param id - 商品评论ID(新增时为null)
+ * @param isEdit - 是否是编辑模式
*/
const onAddOrUpdate = (id, isEdit) => {
- addOrUpdateVisible.value = true
+ addOrUpdateVisible.value = true // 显示弹窗
nextTick(() => {
- addOrUpdateRef.value?.init(id, isEdit)
+ addOrUpdateRef.value?.init(id, isEdit) // 初始化弹窗内容
})
}
+
+/**
+ * 删除行
+ * @param row - 要删除的行数据
+ */
const rowDel = (row) => {
ElMessageBox.confirm('确定进行删除操作?', '提示', {
confirmButtonText: '确定',
@@ -94,7 +123,7 @@ const rowDel = (row) => {
})
.then(() => {
http({
- url: http.adornUrl('/prod/prodComm/' + row.prodCommId),
+ url: http.adornUrl(`/prod/prodComm/${row.prodCommId}`),
method: 'delete',
data: http.adornData({})
})
@@ -104,19 +133,26 @@ const rowDel = (row) => {
type: 'success',
duration: 1500,
onClose: () => {
- getDataList()
+ getDataList() // 刷新数据列表
}
})
})
- }).catch(() => { })
+ }).catch(() => { /* 用户取消操作 */ })
}
+
/**
- * 刷新回调
+ * 刷新回调,重新加载数据列表
*/
const refreshChange = () => {
- getDataList(page)
+ getDataList(page) // 重新加载数据
}
+
+/**
+ * 搜索条件改变时重新加载数据列表
+ * @param params - 搜索参数
+ * @param done - 完成回调函数
+ */
const onSearch = (params, done) => {
- getDataList(page, params, done)
+ getDataList(page, params, done) // 根据搜索参数加载数据
}
diff --git a/front-end/mall4v/src/views/modules/prod/prodInfo/components/prod-transport.vue b/front-end/mall4v/src/views/modules/prod/prodInfo/components/prod-transport.vue
index e21a643..d798070 100644
--- a/front-end/mall4v/src/views/modules/prod/prodInfo/components/prod-transport.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodInfo/components/prod-transport.vue
@@ -1,9 +1,12 @@
+
+
+
+
+
+
所有地区
+
+
+
+
diff --git a/front-end/mall4v/src/views/modules/prod/prodInfo/components/sku-table.vue b/front-end/mall4v/src/views/modules/prod/prodInfo/components/sku-table.vue
index ceeff69..80bbc07 100644
--- a/front-end/mall4v/src/views/modules/prod/prodInfo/components/sku-table.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodInfo/components/sku-table.vue
@@ -1,149 +1,170 @@
+
+
+ border
+ style="width: 100%; margin-top: 20px"
>
-
-
- {{ scope.row.properties.split(';')[index].split(':')[1] }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 禁用
-
-
- 启用
-
-
-
+
+
+ :key="index"
+ :label="leftTitle"
+ >
+
+ {{ scope.row.properties.split(';')[index].split(':')[1] }}
+
+
+
+
+
+ prop="pic"
+ label="sku图片"
+ width="180"
+ >
+
+
+
+
+
+
+
+ prop="prodName"
+ label="商品名称"
+ width="250"
+ >
+
+
+ type="textarea"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ controls-position="right"
+ :precision="2"
+ :max="1000000000"
+ :min="0.01"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ controls-position="right"
+ :precision="2"
+ :max="1000000000"
+ :min="0.01"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ :min="0"
+ controls-position="right"
+ type="number"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ :precision="2"
+ :min="0"
+ controls-position="right"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ :precision="2"
+ :min="0"
+ controls-position="right"
+ :disabled="!scope.row.status"
+ />
+
+
+
+
+
+
+
+ type="text"
+ @click="changeSkuStatus(`${scope.$index}`)"
+ >
+ 禁用
+
+
+ type="text"
+ @click="changeSkuStatus(`${scope.$index}`)"
+ >
+ 启用
+
+
+
diff --git a/front-end/mall4v/src/views/modules/prod/prodInfo/index.vue b/front-end/mall4v/src/views/modules/prod/prodInfo/index.vue
index f60a30b..0f80984 100644
--- a/front-end/mall4v/src/views/modules/prod/prodInfo/index.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodInfo/index.vue
@@ -1,28 +1,22 @@
-
+
+
+
+
+
-
- 上架
-
-
- 下架
-
+ 上架
+ 下架
-
+
+
+
-
+
+
+
-
-
+
+
-
+
+
+
-
+
-
+
+
+
-
+
+
+
-
- 商家配送
-
-
- 用户自提
-
+ 商家配送
+ 用户自提
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- 确定
-
+ 确定
@@ -138,18 +88,20 @@ import SkuTag from './components/sku-tag.vue'
import SkuTable from './components/sku-table.vue'
import { Debounce } from '@/utils/debounce'
+// 定义事件发射器
const emit = defineEmits(['refreshDataList'])
-// 分类树展示与回显
+// 分类树展示与回显数据
const category = reactive({
- list: [],
- selected: [],
+ list: [], // 分类列表
+ selected: [], // 当前选择的分类
props: {
value: 'categoryId',
label: 'categoryName'
}
})
-// 规格列表
+
+// 表单模型数据
const dataForm = ref({
prodName: '',
brief: '',
@@ -167,22 +119,28 @@ const dataForm = ref({
},
deliveryTemplateId: null
})
+
+// 分组标签数据
const tags = ref([])
+
+// 获取路由参数中的产品ID
onMounted(() => {
dataForm.value.prodId = useRoute().query.prodId
getDataList()
})
+// 引用子组件实例
const skuTableRef = ref(null)
const skuTagRef = ref(null)
+
/**
- * 获取分类数据
+ * 获取所有必要的数据列表
*/
const getDataList = () => {
getTagList()
getCategoryList().then(() => {
if (dataForm.value.prodId) {
- // 获取产品数据
+ // 如果存在产品ID,则获取具体产品信息并填充表单
http({
url: http.adornUrl(`/prod/prod/info/${dataForm.value.prodId}`),
method: 'get',
@@ -198,6 +156,7 @@ const getDataList = () => {
})
} else {
nextTick(() => {
+ // 初始化表单,清除所有字段
dataFormRef.value?.resetFields()
skuTagRef.value?.init()
dataForm.value.pic = ''
@@ -206,49 +165,48 @@ const getDataList = () => {
}
})
}
+
/**
- * 获取分类信息
+ * 获取分类信息并转换为树形结构
*/
const getCategoryList = () => {
return http({
url: http.adornUrl('/prod/category/listCategory'),
method: 'get',
params: http.adornParams()
+ }).then(({ data }) => {
+ category.list = treeDataTranslate(data, 'categoryId', 'parentId')
})
- .then(({ data }) => {
- category.list = treeDataTranslate(data, 'categoryId', 'parentId')
- })
}
+
/**
- * 选择分类改变事件
- * @param val
+ * 处理分类改变事件,更新分类ID
*/
const handleCategoryChange = (val) => {
dataForm.value.categoryId = val[val.length - 1]
}
+// 获取路由实例
const router = useRouter()
+
+// 表单引用
const dataFormRef = ref(null)
+
/**
- * 表单提交
+ * 提交表单,添加或更新产品信息
*/
const onSubmit = Debounce(() => {
dataFormRef.value?.validate((valid) => {
if (!valid) {
return
}
- if (!dataForm.value.imgs) {
- errorMsg('请选择图片上传')
- return
- }
- if (!dataForm.value.deliveryMode) {
- errorMsg('请选择配送方式')
- return
- }
- if (dataForm.value.deliveryMode.hasShopDelivery && !dataForm.value.deliveryTemplateId) {
- errorMsg('请选择运费模板')
+ // 校验表单完整性
+ if (!dataForm.value.imgs || !dataForm.value.deliveryMode ||
+ (dataForm.value.deliveryMode.hasShopDelivery && !dataForm.value.deliveryTemplateId)) {
+ errorMsg('请检查表单内容')
return
}
+
const param = Object.assign({}, dataForm.value)
// 设置价格和库存
paramSetPriceAndStocks(param)
@@ -257,69 +215,73 @@ const onSubmit = Debounce(() => {
param.deliveryModeVo = dataForm.value.deliveryMode
// 商品主图
param.pic = dataForm.value.imgs.split(',')[0]
+
+ // 发送HTTP请求保存或更新产品信息
http({
url: http.adornUrl('/prod/prod'),
method: param.prodId ? 'put' : 'post',
data: http.adornData(param)
- })
- .then(() => {
- ElMessage({
- message: '操作成功',
- type: 'success',
- duration: 1500,
- onClose: () => {
- router.push({
- path: '/prod/prodList'
- })
- emit('refreshDataList')
- }
- })
+ }).then(() => {
+ ElMessage({
+ message: '操作成功',
+ type: 'success',
+ duration: 1500,
+ onClose: () => {
+ // 成功后跳转到产品列表页,并刷新列表
+ router.push({ path: '/prod/prodList' })
+ emit('refreshDataList')
+ }
})
+ })
})
})
+/**
+ * 设置商品价格和库存总量
+ */
const paramSetPriceAndStocks = (param) => {
- // 商品库存
param.totalStocks = 0
- // 商品价格
param.price = 0
- // 商品原价
param.oriPrice = 0
- // 商品实际库存
+
for (let i = 0; i < param.skuList.length; i++) {
const element = param.skuList[i]
- if (element.status !== 1) {
- continue
- }
- if (param.price === 0) {
- param.price = element.price ? Number.parseFloat(element.price) : 0
- }
- // 商品价格为最低价的那件商品的价格
+ if (element.status !== 1) continue
+
+ if (param.price === 0) param.price = Number.parseFloat(element.price || 0)
+
param.price = Math.min(param.price, element.price)
- if (param.price === element.price) {
- param.oriPrice = element.oriPrice ? Number.parseFloat(element.oriPrice) : 0
- }
- param.totalStocks += element.stocks ? Number.parseInt(element.stocks) : 0
+ if (param.price === element.price) param.oriPrice = Number.parseFloat(element.oriPrice || 0)
+
+ param.totalStocks += Number.parseInt(element.stocks || 0)
}
- // 如果sku没有商品名称,则使用商品的商品名称
+
if (param.skuList.length === 1) {
param.skuList[0].prodName = dataForm.value.prodName
}
}
+
+/**
+ * 处理SKU变化事件,更新SKU名称
+ */
const skuTagChangeSkuHandler = (skuList) => {
const prodName = dataForm.value.prodName
skuList.forEach(sku => {
if (sku.properties) {
sku.skuName = ''
const properties = sku.properties.split(';')
- for (const propertiesKey in properties) {
- sku.skuName += properties[propertiesKey].split(':')[1] + ' '
+ for (const property of properties) {
+ sku.skuName += property.split(':')[1] + ' '
}
- sku.prodName = prodName + ' ' + sku.skuName
+ sku.prodName = prodName + ' ' + sku.skuName.trim()
}
})
dataForm.value.skuList = skuList
}
+
+/**
+ * 显示错误消息
+ */
const errorMsg = (message) => {
ElMessage({
message,
@@ -336,9 +298,8 @@ const getTagList = () => {
url: http.adornUrl('/prod/prodTag/listTagList'),
method: 'get',
params: http.adornParams()
+ }).then(({ data }) => {
+ tags.value = data
})
- .then(({ data }) => {
- tags.value = data
- })
}
diff --git a/front-end/mall4v/src/views/modules/prod/prodList/index.vue b/front-end/mall4v/src/views/modules/prod/prodList/index.vue
index 2175088..e27b83e 100644
--- a/front-end/mall4v/src/views/modules/prod/prodList/index.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodList/index.vue
@@ -1,5 +1,6 @@
+
+
+
上架
@@ -40,6 +43,7 @@
+
{
dataListLoading.value = true
http({
@@ -95,23 +109,20 @@ const getDataList = (pageParam, params, done) => {
)
})
.then(({ data }) => {
- dataList.value = data.records
- for (const key in dataList.value) {
- // eslint-disable-next-line no-prototype-builtins
- if (dataList.value.hasOwnProperty(key)) {
- const element = dataList.value[key]
- element.imgs = element.imgs.split(',')[0]
- }
- }
+ // 更新数据列表并处理图片字段
+ dataList.value = data.records.map(element => ({
+ ...element,
+ imgs: element.imgs.split(',')[0]
+ }))
page.total = data.total
dataListLoading.value = false
if (done) done()
})
}
-const router = useRouter()
+
/**
- * 新增 / 修改
- * @param id
+ * 新增或编辑商品信息
+ * @param id - 商品ID,如果存在则为编辑,否则为新增
*/
const onAddOrUpdate = (id) => {
router.push({
@@ -119,19 +130,21 @@ const onAddOrUpdate = (id) => {
query: { prodId: id }
})
}
+
/**
- * 删除和批量删除
- * @param id
+ * 删除或批量删除商品信息
+ * @param id - 单个商品ID,若不存在则执行批量删除
*/
const onDelete = (id) => {
const prodIds = getSeleProdIds()
if (id) {
prodIds.push(id)
}
+
ElMessageBox.confirm(`确定进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
- type: 'warning'
+ type: '警告'
})
.then(() => {
http({
@@ -150,32 +163,33 @@ const onDelete = (id) => {
})
})
})
- .catch(() => { })
+ .catch(() => {})
}
+
/**
- * 条件查询
- * @param params
- * @param done
+ * 条件查询触发的数据获取
+ * @param params - 查询参数
+ * @param done - 完成回调
*/
const onSearch = (params, done) => {
getDataList(page, params, done)
}
+// 多选变化后的选择项
const dataListSelections = ref([])
+
/**
- * 多选变化
- * @param val
+ * 多选变化事件处理器
+ * @param val - 选中的行数据
*/
const selectionChange = (val) => {
dataListSelections.value = val
}
+
/**
- * 获取选中的商品Id列表
+ * 获取选中的商品ID列表
*/
const getSeleProdIds = () => {
- return dataListSelections.value?.map(item => {
- return item.prodId
- })
+ return dataListSelections.value?.map(item => item.prodId) || []
}
-
diff --git a/front-end/mall4v/src/views/modules/prod/prodTag/add-or-update.vue b/front-end/mall4v/src/views/modules/prod/prodTag/add-or-update.vue
index e150923..f39ca68 100644
--- a/front-end/mall4v/src/views/modules/prod/prodTag/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodTag/add-or-update.vue
@@ -4,6 +4,7 @@
:title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false"
>
+
+
-
+
+
+
-
- 正常
-
-
- 禁用
-
+ 正常
+ 禁用
-
+
+
+
-
- 一列一个
-
-
- 一列两个
-
-
- 一列三个
-
+ 一列一个
+ 一列两个
+ 一列三个
-
+
+
+
+
@@ -82,55 +65,76 @@
diff --git a/front-end/mall4v/src/views/modules/prod/prodTag/index.vue b/front-end/mall4v/src/views/modules/prod/prodTag/index.vue
index f8a92f2..00a779f 100644
--- a/front-end/mall4v/src/views/modules/prod/prodTag/index.vue
+++ b/front-end/mall4v/src/views/modules/prod/prodTag/index.vue
@@ -1,5 +1,6 @@
+
+
+
+
{{ scope.row.title || '-' }}
+
+
-
+
禁用
@@ -35,6 +38,7 @@
+
自定义类型
@@ -44,6 +48,7 @@
+
+
+
{
dataListLoading.value = true
http({
@@ -103,11 +119,13 @@ const getDataList = (pageParam, params, done) => {
})
}
+// 控制添加或更新对话框显示/隐藏
const addOrUpdateVisible = ref(false)
const addOrUpdateRef = ref(null)
+
/**
- * 新增 / 修改
- * @param id
+ * 新增或编辑产品标签
+ * @param id - 标签ID,如果存在则为编辑模式
*/
const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true
@@ -116,6 +134,10 @@ const onAddOrUpdate = (id) => {
})
}
+/**
+ * 删除产品标签
+ * @param id - 标签ID
+ */
const onDelete = (id) => {
ElMessageBox.confirm('确定进行删除操作?', '提示', {
confirmButtonText: '确定',
@@ -138,19 +160,22 @@ const onDelete = (id) => {
}
})
})
- }).catch(() => { })
+ }).catch(() => {})
}
+
/**
- * 刷新回调
+ * 刷新回调,用于重新加载数据列表
*/
const refreshChange = () => {
getDataList(page)
}
+
+/**
+ * 条件查询触发的数据获取
+ * @param params - 查询参数
+ * @param done - 完成回调
+ */
const onSearch = (params, done) => {
getDataList(page, params, done)
}
-
-
-
diff --git a/front-end/mall4v/src/views/modules/prod/spec/add-or-update.vue b/front-end/mall4v/src/views/modules/prod/spec/add-or-update.vue
index 42ef658..dbe7f10 100644
--- a/front-end/mall4v/src/views/modules/prod/spec/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/prod/spec/add-or-update.vue
@@ -4,11 +4,13 @@
:title="!dataList[0].propId ? '新增' : '修改'"
:close-on-click-modal="false"
>
+
+
+
+
+
+
+
+
+
diff --git a/front-end/mall4v/src/views/modules/prod/spec/index.vue b/front-end/mall4v/src/views/modules/prod/spec/index.vue
index 7982190..5530018 100644
--- a/front-end/mall4v/src/views/modules/prod/spec/index.vue
+++ b/front-end/mall4v/src/views/modules/prod/spec/index.vue
@@ -1,5 +1,6 @@
+
+
-
+
{{ item.propValue }}
+
+
新增
+
+
编辑
@@ -43,14 +44,14 @@
v-if="isAuth('prod:spec:delete')"
type="danger"
icon="el-icon-delete"
-
@click.stop="onDelete(scope.row.propId)"
>
删除
-
+
+
{
dataListLoading.value = true
@@ -101,11 +114,13 @@ const getDataList = (pageParam, params, done) => {
})
}
+// 控制添加或更新对话框显示/隐藏
const addOrUpdateVisible = ref(false)
const addOrUpdateRef = ref(null)
+
/**
- * 新增 / 修改
- * @param val
+ * 新增或编辑产品规格
+ * @param val - 如果存在则为编辑模式,否则为新增模式
*/
const onAddOrUpdate = (val) => {
addOrUpdateVisible.value = true
@@ -115,13 +130,11 @@ const onAddOrUpdate = (val) => {
}
/**
- * 删除
- * @param id
+ * 删除产品规格
+ * @param id - 规格ID,如果不存在则表示批量删除
*/
const onDelete = (id) => {
- const ids = id ? [id] : dataListSelections.value?.map(item => {
- return item.propId
- })
+ const ids = id ? [id] : dataListSelections.value?.map(item => item.propId)
ElMessageBox.confirm(`确定进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -144,13 +157,17 @@ const onDelete = (id) => {
})
})
})
- .catch(() => { })
+ .catch(() => {})
}
+/**
+ * 条件查询触发的数据获取
+ * @param params - 查询参数
+ * @param done - 完成回调
+ */
const onSearch = (params, done) => {
getDataList(page, params, done)
}
-
diff --git a/front-end/mall4v/src/views/modules/shop/pickAddr/add-or-update.vue b/front-end/mall4v/src/views/modules/shop/pickAddr/add-or-update.vue
index 48e28b2..75e0148 100644
--- a/front-end/mall4v/src/views/modules/shop/pickAddr/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/shop/pickAddr/add-or-update.vue
@@ -4,6 +4,7 @@
:title="!dataForm.addrId ? '新增' : '修改'"
:close-on-click-modal="false"
>
+
-
-
+
+
+
+
+
@@ -55,10 +53,7 @@
-
+
-
-
+
+
+
+
-
-
+
+
+
+
+
+
-
@@ -107,9 +90,15 @@
import { ElMessage } from 'element-plus'
import { isMobile } from '@/utils/validate'
import { Debounce } from '@/utils/debounce'
+import { ref, reactive, nextTick, defineEmits, defineExpose } from 'vue'
+
+// 定义事件发射器,用于向父组件发送事件
const emit = defineEmits(['refreshDataList'])
+
+// 控制对话框显示/隐藏的布尔值
const visible = ref(false)
-// eslint-disable-next-line no-unused-vars
+
+// 验证手机号格式
const validateMobile = (rule, value, callback) => {
if (!isMobile(value)) {
callback(new Error('手机号格式错误'))
@@ -117,6 +106,8 @@ const validateMobile = (rule, value, callback) => {
callback()
}
}
+
+// 表单验证规则
const dataRule = {
addrName: [
{ required: true, message: '自提点名称不能为空', trigger: 'blur' },
@@ -136,10 +127,20 @@ const dataRule = {
{ validator: validateMobile, trigger: 'blur' }
]
}
+
+// 省列表
const provinceList = ref([])
+
+// 表单引用
const dataFormRef = ref(null)
+
+// 城市列表
const cityList = ref([])
+
+// 区/县列表
const areaList = ref([])
+
+// 表单数据对象,初始化默认值
const dataForm = reactive({
addrId: 0,
addr: '',
@@ -152,11 +153,18 @@ const dataForm = reactive({
cityId: null,
provinceId: null
})
+
+// 分页信息
const page = reactive({
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 10 // 每页显示多少条
})
+
+/**
+ * 初始化方法,接受可选的ID作为参数
+ * @param id - 自提点地址条目ID,如果存在则为编辑模式
+ */
const init = (id) => {
dataForm.addrId = id || 0
visible.value = true
@@ -173,9 +181,7 @@ const init = (id) => {
})
if (dataForm.addrId) {
http({
- url: http.adornUrl(
- `/shop/pickAddr/info/${dataForm.addrId}`
- ),
+ url: http.adornUrl(`/shop/pickAddr/info/${dataForm.addrId}`),
method: 'get',
params: http.adornParams()
})
@@ -197,6 +203,10 @@ const init = (id) => {
}
defineExpose({ init })
+/**
+ * 根据父级ID获取地区列表
+ * @param pid - 父级地区ID,默认为0表示获取省级列表
+ */
const listAreaByParentId = (pid) => {
if (!pid) pid = 0
return http({
@@ -207,26 +217,26 @@ const listAreaByParentId = (pid) => {
}
/**
- * 选择省
- * @param val
+ * 选择省时触发
+ * @param val - 省ID
*/
const selectProvince = (val) => {
dataForm.cityId = null
dataForm.city = ''
- // 获取城市的select
+ dataForm.areaId = null
+ dataForm.area = ''
listAreaByParentId(val).then(({ data }) => {
cityList.value = data
})
}
/**
- * 选择市
- * @param val
+ * 选择市时触发
+ * @param val - 市ID
*/
const selectCity = (val) => {
dataForm.areaId = null
dataForm.area = ''
- // 获取区的select
listAreaByParentId(val).then(({ data }) => {
areaList.value = data
})
@@ -236,24 +246,23 @@ const selectCity = (val) => {
* 表单提交
*/
const onSubmit = Debounce(() => {
+ // 设置省市区的名字
for (let i = 0; i < provinceList.value.length; i++) {
if (provinceList.value[i].areaId === dataForm.provinceId) {
- // 将省名字保存起来
dataForm.province = provinceList.value[i].areaName
}
}
for (let i = 0; i < cityList.value.length; i++) {
if (cityList.value[i].areaId === dataForm.cityId) {
- // 将市名字保存起来
dataForm.city = cityList.value[i].areaName
}
}
for (let i = 0; i < areaList.value.length; i++) {
if (areaList.value[i].areaId === dataForm.areaId) {
- // 将市名字保存起来
dataForm.area = areaList.value[i].areaName
}
}
+
dataFormRef.value?.validate(valid => {
if (valid) {
http({
diff --git a/front-end/mall4v/src/views/modules/shop/pickAddr/index.vue b/front-end/mall4v/src/views/modules/shop/pickAddr/index.vue
index 6024340..4dad1f1 100644
--- a/front-end/mall4v/src/views/modules/shop/pickAddr/index.vue
+++ b/front-end/mall4v/src/views/modules/shop/pickAddr/index.vue
@@ -1,5 +1,6 @@
+
+
+
{
http({
@@ -99,11 +112,13 @@ const getDataList = (pageParam, params, done) => {
})
}
+// 控制添加或更新对话框显示/隐藏
const addOrUpdateVisible = ref(false)
const addOrUpdateRef = ref(null)
+
/**
* 新增 / 修改
- * @param id
+ * @param id - 如果存在则为编辑模式,否则为新增模式
*/
const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true
@@ -113,13 +128,11 @@ const onAddOrUpdate = (id) => {
}
/**
- * 删除
- * @param id
+ * 删除单个或多个自提点地址
+ * @param id - 单个自提点地址ID,若未提供则执行批量删除
*/
const onDelete = (id) => {
- const ids = id ? [id] : dataListSelections.value?.map(item => {
- return item.addrId
- })
+ const ids = id ? [id] : dataListSelections.value?.map(item => item.addrId)
ElMessageBox.confirm(
'确定进行删除操作?', '提示',
{
@@ -145,20 +158,21 @@ const onDelete = (id) => {
})
})
})
- .catch(() => { })
+ .catch(() => {})
}
/**
- * 条件查询
- * @param params
- * @param done
+ * 条件查询触发的数据获取
+ * @param params - 查询参数
+ * @param done - 完成回调
*/
const onSearch = (params, done) => {
getDataList(page, params, done)
}
+
/**
- * 多选变化
- * @param val
+ * 多选变化时触发
+ * @param val - 当前选择的数据项数组
*/
const selectionChange = (val) => {
dataListSelections.value = val
diff --git a/front-end/mall4v/src/views/modules/shop/transport/add-or-update.vue b/front-end/mall4v/src/views/modules/shop/transport/add-or-update.vue
index e077e2c..0826721 100644
--- a/front-end/mall4v/src/views/modules/shop/transport/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/shop/transport/add-or-update.vue
@@ -1,326 +1,142 @@
+
-
-
+
+
-
-
-
-
-
- 买家承担运费
-
-
- 卖家包邮
-
-
-
-
-
-
- 按件数
-
-
- 按重量
-
-
- 按体积
-
-
-
-
-
-
- 所有地区
- 请选择可配送区域
-
- {{ city.areaName }}
+ { pattern: /\s\S+|S+\s|\S/, message: '请输入正确的模板名称', trigger: 'blur' }]"
+ >
+
+
+
+
+
+
+ 买家承担运费
+ 卖家包邮
+
+
+
+
+
+
+ 按件数
+ 按重量
+ 按体积
+
+
+
+
+
+
+
+
+ 所有地区
+ 请选择可配送区域
+
+ {{ city.areaName }}
-
- 编辑
-
-
- 删除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 点击添加可配送的区域和运费
-
-
-
- 指定条件包邮
-
-
-
-
- 请选择指定包邮城市
-
- {{ city.areaName }}
-
-
- 编辑
-
-
- 删除
-
-
-
-
-
-
-
- 满件/重量/体积包邮
-
-
- 满金额包邮
-
-
- 满件/重量/体积且满金额包邮
-
-
-
-
-
-
-
- 满 元包邮
-
-
- 满 件/重量/体积包邮
-
-
-
-
-
-
- 点击添加指定包邮条件
-
-
-
-
-
+ 编辑
+ 删除
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 点击添加可配送的区域和运费
+
+
+
+ 指定条件包邮
+
+
+
+
+
+
+ 请选择指定包邮城市
+ {{ city.areaName }}
+ 编辑
+ 删除
+
+
+
+
+
+
+
+ 满件/重量/体积包邮
+ 满金额包邮
+ 满件/重量/体积且满金额包邮
+
+
+
+
+
+
+
+
+ 满 元包邮
+
+
+ 满 件/重量/体积包邮
+
+
+
+
+
+
+
+ 点击添加指定包邮条件
+
+
+
+
+
+
+
+
+
+
@@ -329,10 +145,18 @@ import { isAuth } from '@/utils'
import { ElMessage } from 'element-plus'
import { Debounce } from '@/utils/debounce'
import AddOrUpdate from './add-or-update.vue'
+import { ref, reactive, computed, watch, nextTick } from 'vue'
+
+// 定义一个事件发射器,允许子组件向父组件发送消息
const emit = defineEmits(['refreshDataList'])
+// 是否有免费条件的标志
const hasFreeCondition = ref(0)
+
+// 控制对话框的可见性
const visible = ref(false)
+
+// 表单数据对象,包含运输模板的各项信息
const dataForm = ref({
hasFreeCondition: false,
transName: '',
@@ -343,20 +167,28 @@ const dataForm = ref({
transfees: [{ cityList: [], status: 1 }],
transfeeFrees: [{ freeCityList: [], freeType: 0 }]
})
+
+// 分页配置
const page = reactive({
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 10 // 每页显示多少条
})
+
+// 根据chargeType计算表格标题
const tableTitle = computed(() => {
- const titles = [['首件(个)', '运费(元)', '续件(个)', '续费(元)'], ['首重(kg)', '运费(元)', '续重(kg)', '续费(元)'], ['首体积(m³)', '运费(元)', '续体积(m³)', '续费(元)']]
+ const titles = [
+ ['首件(个)', '运费(元)', '续件(个)', '续费(元)'],
+ ['首重(kg)', '运费(元)', '续重(kg)', '续费(元)'],
+ ['首体积(m³)', '运费(元)', '续体积(m³)', '续费(元)']
+ ]
if (dataForm.value.chargeType) {
return titles[dataForm.value.chargeType]
}
return titles[0]
})
-// 如果当前对话框不可见,则关闭选择城市的对话框
+// 监听visible值的变化,如果对话框不可见则关闭选择城市的对话框
watch(
() => visible.value,
(val) => {
@@ -366,11 +198,19 @@ watch(
}
)
+// 控制添加或更新对话框的可见性
const addOrUpdateVisible = ref(false)
const dataFormRef = ref(null)
+
+/**
+ * 初始化方法,根据ID加载或创建新的运输模板
+ * @param id - 运输模板ID,若不存在则为创建模式
+ */
const init = (id) => {
visible.value = true
dataForm.value.transportId = id || 0
+
+ // 确保在DOM更新后重置表单字段
nextTick(() => {
dataFormRef.value?.resetFields()
dataForm.value = {
@@ -384,9 +224,10 @@ const init = (id) => {
transfeeFrees: [{ freeCityList: [], freeType: 0 }]
}
})
+
+ // 如果存在ID,则加载现有运输模板的数据
if (dataForm.value.transportId) {
http({
- // 获取运费模板数据
url: http.adornUrl(`/shop/transport/info/${dataForm.value.transportId}`),
method: 'get'
})
@@ -401,8 +242,16 @@ const init = (id) => {
})
}
}
+
+// 将init方法暴露给父组件调用
defineExpose({ init })
+/**
+ * 获取城市列表并填充到对应的运费项或包邮条件中
+ * @param row - 当前行索引
+ * @param cityList - 城市列表
+ * @param type - 类型标识符,0为普通运费项,1为包邮条件
+ */
const getDataList = (row, cityList, type) => {
if (type === 0) {
dataForm.value.transfees[row].cityList = cityList
@@ -413,22 +262,25 @@ const getDataList = (row, cityList, type) => {
}
/**
- * 添加运费项
+ * 添加一个新的运费项
*/
const addTransfee = () => {
dataForm.value.transfees.push({ cityList: [], status: 1 })
}
/**
- * 删除运费项
+ * 删除指定的运费项
+ * @param rowIndex - 要删除的行索引
*/
const onDelete = (rowIndex) => {
dataForm.value.transfees.splice(rowIndex, 1)
}
+// 引用添加或更新子组件实例
const addOrUpdateRef = ref(null)
+
/**
- * 可配送区域和运费编辑
+ * 可配送区域和运费编辑(当前功能未实现)
*/
const onAddOrUpdate = () => {
ElMessage({
@@ -448,14 +300,16 @@ const addTransfeeFree = () => {
}
/**
- * 删除指定包邮条件
+ * 删除指定的包邮条件
+ * @param rowIndex - 要删除的行索引
*/
const deleteTransfeeFree = (rowIndex) => {
dataForm.value.transfeeFrees?.splice(rowIndex, 1)
}
/**
- * 指定包邮条件编辑
+ * 编辑指定的包邮条件
+ * @param rowIndex - 要编辑的行索引
*/
const addOrUpdateTransfeeFree = (rowIndex) => {
addOrUpdateVisible.value = true
@@ -470,8 +324,8 @@ const addOrUpdateTransfeeFree = (rowIndex) => {
}
/**
- * 改变模板类型, 0 买家承担运费 1 卖家包邮
- * @param val
+ * 改变模板类型,0表示买家承担运费,1表示卖家包邮
+ * @param val - 新的选择值
*/
const changeFreeFee = (val) => {
dataForm.value.hasFreeCondition = false
@@ -484,7 +338,9 @@ const changeFreeFee = (val) => {
}
/**
- * 校验输入的数字
+ * 校验输入的数字,确保其为正整数且不小于零
+ * @param row - 当前行对象
+ * @param type - 需要校验的字段类型
*/
const checkNumber = (row, type) => {
if (type === 1) {
@@ -497,7 +353,9 @@ const checkNumber = (row, type) => {
}
/**
- * 保留整数并小于零的数设为0
+ * 保留整数并处理小于零的情况
+ * @param num - 输入的数字
+ * @returns 处理后的数字
*/
const getNumber = (num) => {
num = Math.round(num)
@@ -505,11 +363,12 @@ const getNumber = (num) => {
}
/**
- * 表单提交
+ * 提交表单,保存运输模板信息
*/
const onSubmit = Debounce(() => {
dataFormRef.value?.validate((valid) => {
if (valid) {
+ // 检查每个运费项是否选择了可配送区域
for (let i = 1; i < dataForm.value.transfees.length; i++) {
const transfee = dataForm.value.transfees[i]
if (transfee.cityList.length === 0) {
@@ -521,12 +380,18 @@ const onSubmit = Debounce(() => {
return
}
}
+
+ // 设置是否有免费条件
if (dataForm.value.hasFreeCondition) {
hasFreeCondition.value = 1
} else {
hasFreeCondition.value = 0
}
+
+ // 清空默认运费项的城市列表,因为它是全局性的
dataForm.value.transfees[0].cityList = []
+
+ // 发起HTTP请求保存运输模板信息
http({
url: http.adornUrl('/shop/transport'),
method: dataForm.value.transportId ? 'put' : 'post',
diff --git a/front-end/mall4v/src/views/modules/shop/transport/index.vue b/front-end/mall4v/src/views/modules/shop/transport/index.vue
index 3132cb9..8ae6cd1 100644
--- a/front-end/mall4v/src/views/modules/shop/transport/index.vue
+++ b/front-end/mall4v/src/views/modules/shop/transport/index.vue
@@ -1,91 +1,99 @@
+
-
-
- {{ item.propValue }}
-
-
-
-
- 新增
-
+
+
+ {{ item.propValue }}
+
-
- 批量删除
-
-
+
+
+
+ 新增
+
-
-
- 修改
-
+
+ 批量删除
+
+
-
- 删除
-
-
+
+
+
+ 修改
+
+
+
+ 删除
+
+
+
diff --git a/front-end/mall4v/src/views/modules/sys/area/add-or-update.vue b/front-end/mall4v/src/views/modules/sys/area/add-or-update.vue
index 5bbc53f..f489c42 100644
--- a/front-end/mall4v/src/views/modules/sys/area/add-or-update.vue
+++ b/front-end/mall4v/src/views/modules/sys/area/add-or-update.vue
@@ -1,9 +1,11 @@
+
+
+
+
+