增加商品功能完成。
This commit is contained in:
parent
364c4c069b
commit
a3a6fb1d05
@ -3,6 +3,7 @@
|
||||
<div class="product-list">
|
||||
<div class="table-header">
|
||||
<h1>商品列表</h1>
|
||||
<a-button type="primary" @click="showAddModal">添加商品</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 过滤区域 -->
|
||||
@ -67,20 +68,131 @@
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 添加商品模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="addModalVisible"
|
||||
title="添加商品"
|
||||
:confirmLoading="confirmLoading"
|
||||
width="600px"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button @click="handleCancel">取消</a-button>
|
||||
<a-button type="primary" :loading="confirmLoading" @click="handleAdd">
|
||||
保存
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formState"
|
||||
:rules="rules"
|
||||
:label-col="{ span: 6 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
>
|
||||
<a-form-item label="所属商家" name="merchant_id" required>
|
||||
<a-select
|
||||
v-model:value="formState.merchant_id"
|
||||
placeholder="请选择商家"
|
||||
:options="merchantOptions"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品名称" name="name" required>
|
||||
<a-input v-model:value="formState.name" placeholder="请输入商品名称" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品图片" name="image_url" required>
|
||||
<div class="upload-wrapper">
|
||||
<div v-if="formState.image_url" class="image-preview">
|
||||
<img :src="formState.image_url" alt="商品图片" />
|
||||
<div class="image-actions">
|
||||
<a-button type="link" danger @click="handleRemoveImage">删除</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-upload
|
||||
v-else
|
||||
name="files"
|
||||
:customRequest="handleUpload"
|
||||
:show-upload-list="false"
|
||||
accept="image/*"
|
||||
>
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
上传图片
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品原价" name="product_price" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.product_price"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 100%"
|
||||
placeholder="请输入商品原价"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="销售价格" name="sale_price" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.sale_price"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 100%"
|
||||
placeholder="请输入销售价格"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="结算价格" name="settlement_amount" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.settlement_amount"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
style="width: 100%"
|
||||
placeholder="请输入结算价格"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="标签" name="tags">
|
||||
<a-input v-model:value="formState.tags" placeholder="多个标签用逗号分隔" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="最高抵扣消费金" name="max_deduct_points" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.max_deduct_points"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
style="width: 100%"
|
||||
placeholder="请输入最高抵扣消费金"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { message, Upload, InputNumber, Tag } from 'ant-design-vue'
|
||||
import { UploadOutlined } from '@ant-design/icons-vue'
|
||||
import PageContainer from '@/components/PageContainer.vue'
|
||||
import { getMerchantProducts } from '@/api/merchant'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
PageContainer
|
||||
PageContainer,
|
||||
UploadOutlined,
|
||||
AUpload: Upload,
|
||||
AInputNumber: InputNumber,
|
||||
ATag: Tag
|
||||
},
|
||||
setup() {
|
||||
const loading = ref(false)
|
||||
@ -221,6 +333,106 @@ export default defineComponent({
|
||||
console.log('修改商品:', record)
|
||||
}
|
||||
|
||||
// 添加商品相关
|
||||
const addModalVisible = ref(false)
|
||||
const confirmLoading = ref(false)
|
||||
const formRef = ref(null)
|
||||
|
||||
const formState = ref({
|
||||
merchant_id: undefined,
|
||||
name: '',
|
||||
image_url: '',
|
||||
product_price: null,
|
||||
sale_price: null,
|
||||
settlement_amount: null,
|
||||
tags: '',
|
||||
max_deduct_points: null
|
||||
})
|
||||
|
||||
const rules = {
|
||||
merchant_id: [{ required: true, message: '请选择所属商家' }],
|
||||
name: [{ required: true, message: '请输入商品名称' }],
|
||||
image_url: [{ required: true, message: '请上传商品图片' }],
|
||||
product_price: [{ required: true, message: '请输入商品原价' }],
|
||||
sale_price: [{ required: true, message: '请输入销售价格' }],
|
||||
settlement_amount: [{ required: true, message: '请输入结算价格' }],
|
||||
max_deduct_points: [{ required: true, message: '请输入最高抵扣消费金' }]
|
||||
}
|
||||
|
||||
// 显示添加模态框
|
||||
const showAddModal = () => {
|
||||
addModalVisible.value = true
|
||||
}
|
||||
|
||||
// 处理图片上传
|
||||
const handleUpload = async ({ file, onSuccess, onError }) => {
|
||||
const formData = new FormData()
|
||||
formData.append('files', file)
|
||||
|
||||
try {
|
||||
const res = await request.post('/api/upload/images', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
|
||||
if (res.code === 200 && res.data && res.data.urls && res.data.urls.length > 0) {
|
||||
formState.value.image_url = res.data.urls[0]
|
||||
onSuccess()
|
||||
message.success('上传成功')
|
||||
} else {
|
||||
throw new Error('上传失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传图片失败:', error)
|
||||
message.error('上传失败')
|
||||
onError()
|
||||
}
|
||||
}
|
||||
|
||||
// 删除图片
|
||||
const handleRemoveImage = () => {
|
||||
formState.value.image_url = ''
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleAdd = () => {
|
||||
formRef.value.validate().then(async () => {
|
||||
try {
|
||||
confirmLoading.value = true
|
||||
const res = await request.post('/api/merchant/product', formState.value)
|
||||
if (res.code === 200) {
|
||||
message.success('添加成功')
|
||||
addModalVisible.value = false
|
||||
fetchData()
|
||||
} else {
|
||||
throw new Error(res.message || '添加失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加商品失败:', error)
|
||||
message.error(error.message || '添加失败')
|
||||
} finally {
|
||||
confirmLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 取消添加
|
||||
const handleCancel = () => {
|
||||
formRef.value?.resetFields()
|
||||
formState.value = {
|
||||
merchant_id: undefined,
|
||||
name: '',
|
||||
image_url: '',
|
||||
product_price: null,
|
||||
sale_price: null,
|
||||
settlement_amount: null,
|
||||
tags: '',
|
||||
max_deduct_points: null
|
||||
}
|
||||
addModalVisible.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchMerchantOptions()
|
||||
})
|
||||
@ -234,7 +446,17 @@ export default defineComponent({
|
||||
filterForm,
|
||||
handleTableChange,
|
||||
handleMerchantChange,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
addModalVisible,
|
||||
confirmLoading,
|
||||
formRef,
|
||||
formState,
|
||||
rules,
|
||||
showAddModal,
|
||||
handleUpload,
|
||||
handleRemoveImage,
|
||||
handleAdd,
|
||||
handleCancel
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -281,4 +503,37 @@ export default defineComponent({
|
||||
:deep(.ant-tag) {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.upload-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
width: 104px;
|
||||
height: 104px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-preview img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.image-actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
padding: 4px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-actions .ant-btn {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user