Compare commits

..

No commits in common. "294aa013e4382c9a0c2a33941dc5f72bccff4bc4" and "4da07ddfaa858c204a02d26a508308ad06e3b16e" have entirely different histories.

4 changed files with 171 additions and 350 deletions

View File

@ -179,8 +179,8 @@
<template #default="{ row }">
<el-button v-if="true || stateCode.ORDER_STATE_WAIT_PAY==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/edit'] }" size="mini" type="text" @click="handleEdit(row)">{{ t('详情') }}</el-button>
<el-button v-if="stateCode.ORDER_STATE_WAIT_PAY==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/remove'] }" size="small" type="text" @click.stop="handleCancel(row.order_id)">{{ t('取消') }}</el-button>
<!--店铺付款这款有问题不符合 暂时停用-->
<!-- <el-button v-if="stateCode.ORDER_STATE_WAIT_PAY==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/finance'] }" size="mini" type="text" @click="handlePaid(row)">{{ t('付款') }}</el-button> -->
<el-button v-if="stateCode.ORDER_STATE_WAIT_PAY==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/finance'] }" size="mini" type="text" @click="handlePaid(row)">{{ t('付款') }}</el-button>
<el-button v-if="ifReview && stateCode.ORDER_STATE_WAIT_REVIEW==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/review'] }" size="mini" type="text" @click="handleReview(row.order_id)">{{ t('订单审核') }}</el-button>
<el-button v-if="ifFinanceReview && stateCode.ORDER_STATE_WAIT_FINANCE_REVIEW==row.order_state_id" v-permissions="{ permission: ['/manage/trade/orderBase/finance'] }" size="mini" type="text" @click="handleFinanceReview(row.order_id)">{{ t('财务审核') }}</el-button>

View File

@ -6,79 +6,81 @@
:close-on-click-modal="false"
@close="handleClose"
>
<div class="edit-tip">
正在编辑商品: <strong>{{ formData.name }}</strong>
(条码: {{ formData.barcode || '无条码' }})
</div>
<div class="edit-tip">
正在编辑商品: <strong>{{ formData.name }}</strong>
(条码: {{ formData.barcode || '无条码' }})
</div>
<el-form ref="editForm" :model="formData" label-width="100px" label-position="right">
<!-- 主图编辑 -->
<!-- <el-form-item label="当前主图">
<el-image
v-if="formData.thumb"
:src="formData.thumb"
style="width: 100px; height: 100px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
/>
<span v-else class="text-gray-500">暂无主图</span>
</el-form-item> -->
<el-form-item
label="商品主图"
label="上传新主图"
prop="newThumb"
:rules="[
{ required: true, message: '请上传商品主图', trigger: 'change' }
{ required: true, message: '请上传新的商品主图', trigger: 'change' }
]"
>
<upload
height="100px"
:image="formData.newThumb"
width="100px"
@upImage="handleMainImageUpload"
height="100px"
:image="formData.newThumb"
width="100px"
@upImage="handleMainImageUpload"
/>
<div class="el-form-item__error" style="padding-top: 10px;">
<span>支持 JPG, PNG 格式建议尺寸 800x800px</span>
</div>
</el-form-item>
<el-form-item label="商品副图">
<!-- 副图编辑 -->
<!-- <el-form-item label="商品副图">
<div class="sub-images-container">
<!-- 副图列表 -->
<div v-for="(item, index) in formData.product_image_list" :key="item.id || `sub_${index}`" class="sub-image-item">
<el-image
:src="item.imageUrl"
style="width: 80px; height: 80px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
:preview-index="index + 1"
/>
<div class="sub-img-actions">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleEditSubImage(index)"
title="更换图片"
/>
</div>
<!-- 现有副图的隐藏上传组件 -->
<upload
ref="subImageUploadRefs"
class="sub-image-uploader"
height="80px"
width="80px"
:image="item.imageUrl"
@upImage="(url) => handleSubImageUpload(url, index)"
/>
</div>
<div v-for="(item, index) in formData.product_image_list" :key="item.id || index" class="sub-image-item">
<upload
v-if="item.uploadNew"
height="80px"
:image="item.newImageUrl || item.imageUrl"
width="80px"
@upImage="(url) => handleSubImageUpload(url, index)"
/>
<el-image
v-else
:src="item.imageUrl"
style="width: 80px; height: 80px; object-fit: cover; border: 1px solid #eee;"
:preview-src-list="[formData.thumb, ...getSubImages(formData.product_image_list)]"
:preview-index="index + 1"
/>
<div class="sub-img-actions">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="toggleEditSubImage(index)"
/>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="deleteSubImage(index)"
/>
</div>
</div>
<!-- 新增副图按钮-->
<div class="add-sub-image" @click="handleAddSubImage">
<div class="add-sub-image" @click="addSubImage">
<i class="el-icon-plus" />
<span>添加副图</span>
</div>
<!-- 新增副图专用的隐藏上传组件 -->
<upload
ref="newSubImageUpload"
class="sub-image-uploader"
height="80px"
width="80px"
:image="''"
@upImage="handleNewSubImageUpload"
v-show="false"
/>
</div>
</el-form-item>
</el-form-item> -->
</el-form>
<template #footer>
@ -104,14 +106,13 @@ export default {
formData: {
id: '',
name: '',
barcode: '',
barcode: '', //
thumb: '',
newThumb: '',
product_image_list: [],
original_product_image_list: [],
original_thumb: ''
original_product_image_list: [], //
original_thumb: '' //
},
currentEditingSubImageIndex: -1 //
}
},
methods: {
@ -119,41 +120,41 @@ export default {
getSubImages(imageList) {
return (imageList || []).map(item => item.imageUrl).filter(url => url);
},
// open
open(row) {
if (!row || !row.id) {
this.$message.error('无效的商品数据');
return;
}
//
const originalProductImages = JSON.parse(JSON.stringify(row.product_image_list || []));
const originalThumb = row.thumb || '';
// barcode
this.formData = {
id: row.id,
name: row.name || '未知名称',
barcode: row.barcode || '', //
thumb: originalThumb,
newThumb: originalThumb,
original_thumb: originalThumb,
product_image_list: originalProductImages.map(item => ({
...item,
uploadNew: false,
newImageUrl: ''
})),
original_product_image_list: originalProductImages
};
this.visible = true;
this.$nextTick(() => {
this.$refs.editForm?.clearValidate();
});
},
//
open(row) {
if (!row || !row.id) {
this.$message.error('无效的商品数据');
return;
}
const originalProductImages = JSON.parse(JSON.stringify(row.product_image_list || []));
const originalThumb = row.thumb || '';
this.formData = {
id: row.id,
name: row.name || '未知名称',
barcode: row.barcode || '',
thumb: originalThumb,
newThumb: originalThumb,
original_thumb: originalThumb,
product_image_list: originalProductImages.map(item => {
const { id, productId, imageUrl, seq, status, createdAt, updatedAt } = item;
return { id, productId, imageUrl, seq, status, createdAt, updatedAt };
}),
original_product_image_list: originalProductImages
};
this.visible = true;
this.$nextTick(() => {
this.$refs.editForm?.clearValidate();
});
},
//
handleClose() {
this.visible = false;
this.currentEditingSubImageIndex = -1;
this.formData = {
id: '',
name: '',
@ -171,97 +172,80 @@ export default {
this.formData.newThumb = imageUrl;
},
// -
handleEditSubImage(index) {
this.currentEditingSubImageIndex = index;
this.$nextTick(() => {
const uploadRefs = this.$refs.subImageUploadRefs;
const uploadComp = Array.isArray(uploadRefs) ? uploadRefs[index] : uploadRefs;
this.triggerUploadComp(uploadComp);
});
},
// "" -
handleAddSubImage() {
this.$nextTick(() => {
const uploadComp = this.$refs.newSubImageUpload;
this.triggerUploadComp(uploadComp);
});
},
// upload
triggerUploadComp(uploadComp) {
if (!uploadComp) return;
// open
if (typeof uploadComp.open === 'function') {
uploadComp.open();
}
// input
else if (uploadComp.$el) {
const fileInput = uploadComp.$el.querySelector('input[type="file"]');
if (fileInput) {
fileInput.click();
} else {
this.$message.warning('上传组件初始化中,请稍候');
}
}
},
// - URLID
//
handleSubImageUpload(imageUrl, index) {
if (this.formData.product_image_list[index]) {
this.formData.product_image_list[index].imageUrl = imageUrl;
this.$message.success('副图更新成功');
this.currentEditingSubImageIndex = -1;
const item = this.formData.product_image_list[index];
item.newImageUrl = imageUrl;
item.imageUrl = imageUrl; // URL
item.uploadNew = false; // 退
item.tmpUrl = ''; // URL
}
},
// -
handleNewSubImageUpload(imageUrl) {
if (!imageUrl) {
this.$message.warning('请选择有效的图片');
return;
//
toggleEditSubImage(idx) {
const item = this.formData.product_image_list[idx];
if (item.uploadNew) {
// URL
if (item.tmpUrl) {
item.imageUrl = item.tmpUrl;
item.tmpUrl = ''; // URL
}
item.newImageUrl = '';
} else {
// URL
item.tmpUrl = item.imageUrl;
}
//
const maxSeq = this.formData.product_image_list.reduce((p, c) => Math.max(p, c.seq || 0), 0);
// IDnull
item.uploadNew = !item.uploadNew;
},
//
deleteSubImage(index) {
this.formData.product_image_list.splice(index, 1);
},
addSubImage() {
const max = this.formData.product_image_list.reduce((p, c) => Math.max(p, c.seq || 0), 0);
this.formData.product_image_list.push({
id: null,
productId: this.formData.id,
imageUrl: imageUrl, // URL
seq: maxSeq + 1,
status: 1,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
imageUrl: '',
newImageUrl: '',
uploadNew: true, //
tmpUrl: '', // URL
isMain: false,
seq: max + 1,
status: 1
});
this.$message.success('新增副图成功');
},
//
async handleSubmit() {
try {
await this.$refs.editForm.validate();
// - 使
const submitData = [
{
id: this.formData.id,
name: this.formData.name,
barcode: this.formData.barcode,
// 使
thumb: this.formData.newThumb || this.formData.original_thumb,
product_image_list: this.formData.product_image_list
.filter(item => item.imageUrl)
.map((item, index) => ({
...item,
seq: index + 1 //
}))
// 使使
product_image_list: this.hasSubImagesChanged()
? this.formData.product_image_list.filter(item => item.imageUrl).map((item, index) => ({
id: item.id,
productId: this.formData.id,
imageUrl: item.imageUrl,
isMain: false,
seq: index + 1,
status: 1
}))
: this.formData.original_product_image_list
}
];
console.log('提交数据:', submitData);
console.log('提交更新商品图片请求:', submitData);
const response = await saveBatchBarcode(submitData);
if (response.status === 200) {
@ -272,25 +256,30 @@ export default {
this.$message.error('修改失败: ' + (response.msg || '未知错误'));
}
} catch (error) {
console.error('提交失败:', error);
console.error('提交修改失败:', error);
if (error.name !== 'ValidateError') {
this.$message.error('修改失败,请稍后重试');
}
}
},
//
//
hasSubImagesChanged() {
//
if (this.formData.product_image_list.length !== this.formData.original_product_image_list.length) {
return true;
}
//
for (let i = 0; i < this.formData.product_image_list.length; i++) {
const newItem = this.formData.product_image_list[i];
const originalItem = this.formData.original_product_image_list[i];
if (!originalItem || newItem.imageUrl !== originalItem.imageUrl) {
return true;
}
}
return false;
}
}
@ -322,16 +311,19 @@ export default {
.sub-img-actions {
display: flex;
gap: 5px;
.el-button {
color: #666;
padding: 0;
&:hover { color: #409eff; }
&:hover {
color: #409eff;
}
}
.el-button:nth-child(2):hover {
color: #f56c6c;
}
}
//
.sub-image-uploader {
display: none !important;
}
}

View File

@ -1735,7 +1735,7 @@ export default {
// this.creatCircle(obj)
},
async delectRadiusItem(index, item) {
let res = await delectArea({ transport_id: item.transport_id,store_id:this.store_id })
let res = await delectArea({ transport_id: item.transport_id })
if (res && res.status == 200) {
this.$baseMessage('删除成功', 'success')
}

View File

@ -7,7 +7,7 @@
width="50%"
@close="close"
>
<el-form ref="form" label-width="150px" :model="form" :rules="rules">
<el-form ref="form" label-width="120px" :model="form" :rules="rules">
<el-form-item :label="__('活动名称')" prop="activity_title">
<el-input
v-model="form.activity_title"
@ -45,7 +45,7 @@
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="__('砍价商品')" prop="product_item_name">
<el-form-item :label="__('砍价商品')" prop="product_item_name">
<el-input
v-model="form.product_item_name"
clearable
@ -80,9 +80,9 @@
/>
</el-form-item>
<el-form-item :label="__('砍价方式')" prop="cut_down_type">
<!-- <el-radio v-model="form.cut_down_type" :label="1">
<el-radio v-model="form.cut_down_type" :label="1">
{{ __('固定价格') }}
</el-radio> -->
</el-radio>
<el-radio v-model="form.cut_down_type" :label="2">
{{ __('价格范围') }}
</el-radio>
@ -109,106 +109,10 @@
v-model="form.cut_down_user_num"
:label="__('砍价人数')"
:max="10000000"
:min="2"
:min="0"
/>
<el-tooltip
content="砍价成功的人数例如设置为3人一共要3个人砍价才能达到底价下单默认最少为2"
placement="top"
effect="dark"
style="margin-left: 8px;"
>
<i class="el-icon-question" style="cursor: pointer; color: #909399; font-size: 14px;"></i>
</el-tooltip>
</el-form-item>
<el-form-item
v-if="form.cut_down_type === 2"
:label="__('助力好友砍价次数')"
prop="user_cutprice_num"
>
<div style="display: flex; align-items: center;">
<el-input-number
v-model="form.user_cutprice_num"
:label="__('助力好友砍价次数')"
:max="10000000"
:min="5"
style="width: 200px;"
/>
<el-tooltip
content="在活动期间每个人一共可以助力好友的人数默认最少为5"
placement="top"
effect="dark"
style="margin-left: 8px;"
>
<i class="el-icon-question" style="cursor: pointer; color: #909399; font-size: 14px;"></i>
</el-tooltip>
</div>
</el-form-item>
<el-form-item :label="__('砍价第一刀')" prop="cut_first_type">
<el-radio-group v-model="form.cut_first_type">
<el-radio :label="1" >
<span>{{ __('首刀比例') }}</span>
<el-tooltip
content="例如首刀比例为30%100块钱的商品第一刀砍30块"
placement="top"
effect="dark"
>
<i class="el-icon-question" style="margin-left: 5px; cursor: pointer;"></i>
</el-tooltip>
</el-radio>
<el-radio :label="2" style="margin-left: 20px;">
<span>{{ __('首刀金额') }}</span>
<el-tooltip
content="例如首刀金额为2050块钱的商品第一刀砍20块"
placement="top"
effect="dark"
>
<i class="el-icon-question" style="margin-left: 5px; cursor: pointer;"></i>
</el-tooltip>
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="首刀比例(单位-%" size="normal" v-if='form.cut_first_type == 1'>
<el-input v-model="form.cut_first_percent" placeholder="请输入首刀比例" clearable />
</el-form-item>
<el-form-item label="首刀金额(单位/块)" size="normal" v-if='form.cut_first_type == 2'>
<el-input v-model="form.cut_first_price " placeholder="请输入首刀金额" clearable />
</el-form-item>
</el-form>
<el-form ref="touzi" label-width="250px" :model="touzi" :rules="touziRules">
<!-- 总标签 + 问号提示 -->
<el-form-item label="砍价后投骰子的点数(单位-%" class="total-label-item">
<el-tooltip
content="设置骰子不同点数对应的中奖比例6个点数比例总和不能超过100%"
placement="top"
effect="dark"
style="margin-left: 8px;"
>
<i class="el-icon-question" style="cursor: pointer; color: #909399; font-size: 14px;"></i>
</el-tooltip>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12" v-for="(item,index) in touzi.luckyList" :key="index">
<div class="grid-content bg-purple">
<el-form-item :label="`点数${item.doubleValue}`" prop="luckyList" :error="touziErrorMsg">
<el-input
v-model="item.probability"
placeholder="请输入比例"
type="number"
clearable
@blur="checkProbabilityTotal(null, null, ()=>{})"
/>
</el-form-item>
</div>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="close">{{ __('取消') }}</el-button>
<el-button type="primary" @click="save">{{ __('确定') }}</el-button>
@ -231,42 +135,20 @@
form: {
product_item_name: '',
item_id: '',
cut_down_type: 2,
cut_down_type: 1,
cut_down_user_num: 0,
cut_down_fixed_price: '',
activity_type_id: 1124,
activity_starttime: '',
activity_endtime: '',
cut_hour:'',
diceObj:'',
cut_first_type:1,
product_count:'',
user_cutprice_num:'',
cut_first_percent:'',
cut_first_price:'',
},
touzi:{
luckyList:[
{doubleValue:'1',probability:'45'},
{doubleValue:'2',probability:'45'},
{doubleValue:'3',probability:'2'},
{doubleValue:'4',probability:'3'},
{doubleValue:'5',probability:'2'},
{doubleValue:"6",probability:'3'},
],
lottery_num:1
},
touziErrorMsg: '', //
touziRules: {
probabilityList: [
{
validator: this.checkProbabilityTotal,
trigger: ['blur', 'submit']
}
]
product_count:''
},
title: '',
dialogFormVisible: false,
mounted() {
this.$forceUpdate()
},
rules: {
activity_title: [
{ required: true, trigger: 'blur', message: this.__('活动标题') },
@ -318,9 +200,6 @@
},
}
},
mounted() {
this.$forceUpdate()
},
computed: {
isReadOnly() {
return this.form.activity_id !== undefined
@ -360,41 +239,22 @@
cut_down_type: row.activity_rule.cut_down_type,
cut_down_user_num: row.activity_rule.cut_down_user_num,
cut_hour:row.cut_hour,
product_count:row.product_count,
user_cutprice_num:row.activity_rule.user_cutprice_num,
cut_first_type:row.activity_rule.cut_first_type,//
cut_first_percent:row.activity_rule.cut_first_percent,
cut_first_price:row.activity_rule.cut_first_price,
product_count:row.product_count
}
let lucky_turn=row.lucky_turn
this.tranformData(lucky_turn)
}
this.dialogFormVisible = true
},
tranformData(lucky_turn){
if(this.form.cut_first_percent){
this.form.cut_first_type=1
}else if(this.form.cut_first_price){
this.form.cut_first_type=2
}
this.touzi=JSON.parse(lucky_turn)
},
close() {
this.form = {
product_item_name: '',
item_id: '',
cut_down_type: 2,
cut_down_type: 1,
cut_down_fixed_price: '',
user_cutprice_num:5,
activity_type_id: 1124,
activity_starttime: '',
cut_down_user_num: '',
activity_endtime: '',
cut_first_type:1,
product_count:'',
cut_first_percent:'',
cut_first_price:'',
}
this.$refs['form'].resetFields()
this.dialogFormVisible = false
@ -402,38 +262,7 @@
showItemTable() {
this.$refs['productItemTable'].showTable()
},
diceObjToStr(){
this.form.diceObj = JSON.stringify(this.touzi);
},
checkProbabilityTotal(rule, value, callback) {
//
const total = this.touzi.luckyList.reduce((sum, item) => {
// /0
const num = Number(item.probability) || 0
return sum + num
}, 0)
//
if (total > 100) {
this.touziErrorMsg = '6个点数比例总和不能超过100%'
callback(new Error('6个点数比例总和不能超过100%'))
} else if (total === 0) {
this.touziErrorMsg = '请至少输入一个点数比例'
callback(new Error('请至少输入一个点数比例'))
} else {
this.touziErrorMsg = '' //
callback() //
}
},
async save() {
let touziValid = true
try {
await this.$refs['touzi'].validate()
} catch (err) {
touziValid = false
}
if (!touziValid) return
this.diceObjToStr()
save() {
this.$refs['form'].validate(async (valid) => {
if (valid) {
if (this.form.activity_id && this.form.activity_id != undefined) {