This commit is contained in:
qiaopengfei 2024-08-02 08:56:45 +08:00
parent 4c4c44ce88
commit cf81f2265e
17 changed files with 1925 additions and 2006 deletions

View File

@ -1,6 +1,6 @@
VITE_MODE = 'development'
VITE_APP_BASE_API = 'https://122.228.26.226:12025'
VITE_APP_BASE_API = 'http://192.168.2.5:9999'
# VITE_APP_BASE_API = 'https://pre-api.aiguoerp.com'
# VITE_APP_BASE_API = 'http://localhost:80'

View File

@ -0,0 +1,57 @@
import request from '@axioshooks';
// 获取商品管理列表
export function select_by_conditions(data) {
return request({
url: 'xy_openapi/commodity_info/select_by_conditions',
method: 'post',
data
})
}
// 编辑商品(查询)
export function get_commodity_id(data) {
return request({
url: `xy_openapi/commodity_info/get_commodity_id/${data}`,
method: 'get',
data
})
}
// 编辑商品
export function edit_product(data) {
return request({
url: `xy_openapi/commodity_info/edit_product`,
method: 'put',
data
})
}
// 复制商品
export function get_commodity(data) {
return request({
url: `xy_openapi/commodity_info/get_commodity`,
method: 'get',
data
})
}
// 上架
export function publish(data) {
return request({
url: `xy_openapi/commodity_info/publish/${data}`,
method: 'get',
data
})
}
// 下架
export function pull_off(data) {
return request({
url: `xy_openapi/commodity_info/pull_off/${data}`,
method: 'get',
data
})
}
// 删除
export function delete_one(data) {
return request({
url: `xy_openapi/commodity_info/delete_one/${data}`,
method: 'delete',
data
})
}

View File

@ -28,6 +28,9 @@ export function uploadImage(data) {
return request({
url: 'xy_openapi/publish/uploadImage',
method: 'file',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data
})
}
@ -38,4 +41,28 @@ export function region(data) {
method: 'get',
data
})
}
//获取成色
export function qualityList(data) {
return request({
url: 'xy_openapi/quality/list',
method: 'get',
data
})
}
//获取发布默认地址
export function address_default(data) {
return request({
url: `xy_openapi/sender/default/${data}`,
method: 'get',
data
})
}
//商品发布
export function publish_shelve(data) {
return request({
url: 'xy_openapi/publish/shelve',
method: 'post',
data
})
}

View File

@ -0,0 +1,57 @@
<template>
<div>
<div v-for="(item, index) in props.ButtonList" :key="index">
<el-link
v-if="item.show && item.AssemblyName === 'el-link'"
:type="item.type"
:icon="item.icon"
:href="item.href"
:target="item.target"
:disabled="item.disabled"
:underline="item.underline ? true : false"
@click="item.confirm(props.row, item)"
>{{ item.name }}</el-link
>
<el-popconfirm
v-if="item.show && item.AssemblyName === 'el-popconfirm'"
:title="item.title"
:confirm-button-text="item.confirmText"
:cancel-button-text="item.cancelText"
:confirm-button-type="item.confirmType"
:cancel-button-type="item.cancelType"
:icon="item.popconfirmIcon"
:icon-color="item.iconColor"
:hide-icon="item.hideIcon"
@confirm="item.confirm(props.row, item)"
@cancel="item.cancel(props.row, item)"
>
<template #reference>
<el-link
:type="item.type"
:icon="item.icon"
:underline="item.underline ? true : false"
>{{ item.name }}</el-link
>
</template>
</el-popconfirm>
</div>
</div>
</template>
<script setup>
import { defineProps } from "vue";
const props = defineProps({
ButtonList: {
type: Array,
default: [],
},
row: {
type: Object,
default: {},
},
});
</script>
<style scoped lang='scss'>
</style>

View File

@ -0,0 +1,54 @@
<template>
<div class="calculation">
<div>
<!-- <span style="font-weight: bold; padding: 0 10px">本页信息:</span>
<span style="padding: 0 10px">总定价:{{ total_cost }}</span> -->
</div>
<div class="block">
<el-pagination
v-bind="attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
</template>
<script setup>
import { defineEmits, computed, useAttrs } from "vue";
const $emit = defineEmits(["handleSizeChange", "handleCurrentChange"]);
const $attrs = useAttrs();
const attrs = computed(() => {
return {
"page-size": 20,
"page-sizes": [20, 50, 100, 200],
layout: "total, sizes, prev, pager, next, jumper",
...$attrs,
};
});
//
const handleSizeChange = () => {
$emit("handleSizeChange");
};
//
const handleCurrentChange = () => {
$emit("handleCurrentChange");
};
</script>
<style scoped lang='scss'>
.calculation {
height: 50px;
border: 1px solid #ebeef5;
padding: 10px;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
::v-deep .el-pagination .el-input__suffix {
right: -18px;
}
}
</style>

View File

@ -0,0 +1,175 @@
<template>
<div class="text-msg-pic-upload">
<el-upload
ref="upload"
list-type="picture-card"
:class="{ display: data.uploadDisabled }"
v-model:file-list="tempFileList"
:multiple="props.multiple"
:auto-upload="props.autoUpload"
:on-exceed="handleExceed"
:on-change="onChange"
:show-file-list="props.limit > 1 || !props.limit"
accept="image/jpeg,image/png,image/gif,image/jpg"
>
<el-icon v-if="props.limit > 1 || tempFileList.length == 0"
><Plus
/></el-icon>
<img
:src="tempFileList[0].url"
v-if="props.limit == 1 && tempFileList.length > 0"
class="showimg"
/>
<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="hImgPreview(file)"
>
<el-icon><zoom-in /></el-icon>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<el-icon><Delete /></el-icon>
</span>
</span>
</div>
</template>
</el-upload>
<el-dialog v-model="data.dialogVisible" append-to-body>
<img width="100%" :src="data.dialogImageUrl" alt="" />
</el-dialog>
<!-- <div class="Upload_pictures">
<ul class="el-upload__tip cBBBDBF" style="color: #bbbdbf">
<li>支持PNGJEPG格式 不超过2MB</li>
</ul>
</div> -->
</div>
</template>
<script setup>
import { ref, reactive, watch, computed } from "vue";
import { ElMessage } from "element-plus";
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
const $emit = defineEmits(["onSuccessFiles"]);
const props = defineProps({
limitType: {
type: Array,
default: ["jpeg", "jpg", "gif", "png"],
}, //
autoUpload: Boolean,
limit: Number, //
imgList: Array, //
multiple: Boolean, //
});
const data = reactive({
// el-upload使
uploadDisabled: false,
dialogImageUrl: "",
dialogVisible: false,
});
const tempFileList = ref([]);
watch(
props,
(newval) => {
if (Array.isArray(props.imgList)) {
tempFileList.value = props.imgList;
}
},
{ deep: true, immediate: true }
);
computed(() => {
return props.autoUpload ? "上传文件" : "选择文件";
});
//
const hImgPreview = (file) => {
data.dialogImageUrl = file.url;
data.dialogVisible = true;
};
//
const handleRemove = (file) => {
if (tempFileList.value) {
const list = tempFileList.value.filter((f) => f.url != file.url);
$emit("onSuccessFiles", list);
} else {
$emit("onSuccessFiles", []);
}
return true;
};
const onChange = (file) => {
if (!file || !file.raw) {
return;
}
let types = props.limitType;
const isImage = types.find((f) => file.raw.type.includes(f));
const isLt20M = file.raw.size / 1024 / 1024 < 2;
if (!isImage && props.limit > 1) {
ElMessage(
types.length == 0
? "上传图片只能是 PNG 格式!"
: "上传图片只能是 JPG、PNG 格式!"
);
return false;
}
if (!isLt20M) {
ElMessage("上传图片大小不能超过 2MB!");
return false;
}
if (props.limit == 1) {
tempFileList.value = [];
}
handleUpload({ file: file });
return false;
};
//
const handleUpload = (op, filelist) => {
if (props.limit == 1) {
tempFileList.value = [];
setTimeout(() => {
tempFileList.value = [op.file];
}, 100);
}
$emit("onSuccessFiles", op.file);
};
const handleExceed = (files, fileList) => {
ElMessage(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${
files.length
} 个文件共选择了 ${files.length + fileList.length} 个文件`
);
};
</script>
<style lang="scss">
.text-msg-pic-upload .el-upload--picture-card,
.text-msg-pic-upload .el-upload-list--picture-card .el-upload-list__item {
width: 62px;
height: 62px;
line-height: 72px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px 0 0;
}
.showimg {
width: 60px;
height: 60px;
}
.display .el-upload--picture-card {
display: none;
}
.el-upload-list__item-delete {
margin-left: 10px !important;
}
</style>

View File

@ -1,32 +1,25 @@
<template>
<div class="text-msg-pic-upload">
<div class="upload_box">
<el-upload
ref="upload"
action="#"
list-type="picture-card"
:class="{ display: data.uploadDisabled }"
v-model:file-list="tempFileList"
v-model:file-list="fileList"
:class="{ display: fileList.length >= props.limit }"
:http-request="handleUpload"
:multiple="props.multiple"
:auto-upload="props.autoUpload"
:on-exceed="handleExceed"
:on-change="onChange"
:show-file-list="props.limit > 1 || !props.limit"
accept="image/jpeg,image/png,image/gif,image/jpg"
:before-upload="beforeUpload"
:limit="props.limit"
:on-exceed="onExceed"
:accept="props.limitType"
>
<el-icon v-if="props.limit > 1 || tempFileList.length == 0"
><Plus
/></el-icon>
<img
:src="tempFileList[0].url"
v-if="props.limit == 1 && tempFileList.length > 0"
class="showimg"
/>
<el-icon><Plus /></el-icon>
<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="hImgPreview(file)"
@click="handlePreview(file)"
>
<el-icon><zoom-in /></el-icon>
</span>
@ -40,136 +33,174 @@
</div>
</template>
</el-upload>
<el-dialog v-model="data.dialogVisible" append-to-body>
<img width="100%" :src="data.dialogImageUrl" alt="" />
<el-dialog v-model="data.dialogVisible">
<img
w-full
style="width: 100%; height: 100%"
:src="data.dialogImageUrl"
alt="Preview Image"
/>
</el-dialog>
<!-- <div class="Upload_pictures">
<ul class="el-upload__tip cBBBDBF" style="color: #bbbdbf">
<li>支持PNGJEPG格式 不超过2MB</li>
</ul>
</div> -->
</div>
</template>
<script setup>
import { ref, reactive, watch, computed } from "vue";
import { ElMessage } from "element-plus";
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
const $emit = defineEmits(["onSuccessFiles"]);
<script setup>
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
import { ref, reactive } from "vue";
import { ElMessage } from "element-plus";
import { Form } from "vant";
const $emit = defineEmits([""]);
const upload = ref(null);
const props = defineProps({
multiple: {
//
type: Boolean,
default: false,
},
autoUpload: {
//
type: Boolean,
default: true,
},
limitType: {
//
type: Array,
default: ["jpeg", "jpg", "gif", "png"],
}, //
autoUpload: Boolean,
limit: Number, //
imgList: Array, //
multiple: Boolean, //
},
limit: {
//
type: Number,
default: 10,
},
imgList: {
//
type: Array,
default: [],
},
style: {
type: Object,
default: {},
},
});
const data = reactive({
// el-upload使
uploadDisabled: false,
dialogImageUrl: "",
dialogVisible: false,
uploadDisabled: false,
});
const tempFileList = ref([]);
watch(
props,
(newval) => {
if (Array.isArray(props.imgList)) {
tempFileList.value = props.imgList;
}
},
{ deep: true, immediate: true }
);
computed(() => {
return props.autoUpload ? "上传文件" : "选择文件";
});
//
const hImgPreview = (file) => {
data.dialogImageUrl = file.url;
data.dialogVisible = true;
};
//
const handleRemove = (file) => {
if (tempFileList.value) {
const list = tempFileList.value.filter((f) => f.url != file.url);
$emit("onSuccessFiles", list);
} else {
$emit("onSuccessFiles", []);
}
return true;
};
const onChange = (file) => {
if (!file || !file.raw) {
return;
}
let types = props.limitType;
const isImage = types.find((f) => file.raw.type.includes(f));
const isLt20M = file.raw.size / 1024 / 1024 < 2;
if (!isImage && props.limit > 1) {
ElMessage(
types.length == 0
? "上传图片只能是 PNG 格式!"
: "上传图片只能是 JPG、PNG 格式!"
const params = ref([]); //
const fileList = ref(props.imgList); //
const uploadingPromises = ref([]);
// fileList
const beforeUpload = (file) => {
const isAllowedType = props.limitType.includes(
file.type.split("/")[1].toLowerCase()
);
const isLt30M = file.size / 1024 / 1024 < 2;
if (!isAllowedType) {
ElMessage.warning(
`${file.name}图片格式不正确请上传jpeg/jpg/png格式的图片`
);
return false;
}
if (!isLt20M) {
ElMessage("上传图片大小不能超过 2MB!");
if (!isLt30M) {
ElMessage.warning(`${file.name}上传图片大小不能超过 3MB!`);
return false;
}
if (props.limit == 1) {
tempFileList.value = [];
}
handleUpload({ file: file });
return false;
//
return true; //
};
//
const handleUpload = (op, filelist) => {
if (props.limit == 1) {
tempFileList.value = [];
setTimeout(() => {
tempFileList.value = [op.file];
}, 100);
}
$emit("onSuccessFiles", op.file);
const handlePreview = (uploadFile) => {
data.dialogImageUrl = uploadFile.url;
data.dialogVisible = true;
};
const handleExceed = (files, fileList) => {
ElMessage(
const handleRemove = (file) => {
if (fileList.value && Array.isArray(fileList.value)) {
const deleteList = fileList.value.filter((f) => f.url === file.url);
const updatedList = fileList.value.filter((f) => f.url !== file.url);
fileList.value = updatedList;
$emit("handleRemove", deleteList);
} else {
$emit("handleRemove", []);
}
return true;
};
const onExceed = (files, fileList) => {
ElMessage.warning(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${
files.length
} 个文件共选择了 ${files.length + fileList.length} 个文件`
);
};
//
const handleUpload = (file) => {
//
const uploadPromise = new Promise((resolve, reject) => {
setTimeout(() => {
//
//
resolve(file);
//
// reject(new Error(''));
}, 500); // 1
});
// Promise便
uploadingPromises.value.push(uploadPromise);
//
uploadPromise
.then(() => {
// Promise
const index = uploadingPromises.value.indexOf(uploadPromise);
if (index !== -1) {
uploadingPromises.value.splice(index, 1);
}
//
if (uploadingPromises.value.length === 0) {
//
allFilesUploaded();
}
})
.catch((error) => {
console.error("上传失败:", error);
//
// Promise
});
};
//
const allFilesUploaded = () => {
params.value = [];
for (var i = 0; i < fileList.value.length; i++) {
params.value.push(fileList.value[i].raw);
}
$emit("onSuccessFiles", params.value);
};
</script>
<style lang="scss">
.text-msg-pic-upload .el-upload--picture-card,
.text-msg-pic-upload .el-upload-list--picture-card .el-upload-list__item {
width: 62px;
height: 62px;
line-height: 72px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px 0 0;
<style scoped lang='scss'>
::v-deep {
.el-upload--picture-card,
.el-upload-list--picture-card .el-upload-list__item {
width: 62px;
height: 62px;
line-height: 72px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px 0 0;
}
.showimg {
width: 60px;
height: 60px;
}
.display .el-upload--picture-card {
display: none;
}
.el-upload-list__item-delete {
margin-left: 10px !important;
}
}
.showimg {
width: 60px;
height: 60px;
}
.display .el-upload--picture-card {
display: none;
}
.el-upload-list__item-delete {
margin-left: 10px !important;
}
</style>
</style>

View File

@ -1,199 +1,245 @@
<template>
<div class="saletopbox">
<div class="inputbox" v-for="item,index in inputdatas" :key="String(index)">
<el-input
clearable
v-if="item.type=='el-input'"
v-model="item.value"
size="large"
class="topinput"
:placeholder="item.placeholder"
>
<template #suffix v-if="item.popover">
<el-popover
placement="bottom-start"
:visible="imeipopover[index]"
:width="200"
trigger="click">
<template #reference>
<i
class="iconfont icon-icon-piliangcaozuo imeiicondefault"
:class="imeipopover ? 'imeiiconActive' : 'imeiicon'"
style="font-size: 12px;"
@click.prevent="imeiiconClick(index)"
></i>
</template>
<el-input placeholder="一行一项,最多支持200行" type="textarea" :rows="12" style="border:none" v-model="item.value"/>
<div class="popoverfooter">
<el-button size="small" @click.stop="imeipopover[index]=false">关闭</el-button>
<el-button size="small" @click.stop="item.value=''">清空</el-button>
<el-button size="small" type="primary" @click.stop="onSearch">查询</el-button>
</div>
</el-popover >
</template>
</el-input>
</div>
<el-button type="primary" @click.stop="onSearch">查询</el-button>
<el-button @click.stop="onRest">重置</el-button>
<el-popover
v-if="extrainputs.length>0"
placement="bottom-start"
:visible="extrapopover"
:width="450"
trigger="click">
<template #reference>
<el-button @click="extrapopover = !extrapopover">更多选项</el-button>
</template>
<div class="extrabox">
<div v-for="item,index in extrainputs" :key="String(index)" class="extraitem">
<div class="extraitemtitle">{{item.title}}</div>
<template>
<div class="saletopbox">
<div
class="inputbox"
v-for="(item, index) in inputdatas"
:key="String(index)"
>
<el-input
clearable
v-if="item.type == 'el-input'"
v-model="item.value"
class="topinput"
:placeholder="item.placeholder"
>
<template #suffix v-if="item.popover">
<el-popover
placement="bottom-start"
:visible="imeipopover[index]"
:width="200"
trigger="click"
>
<template #reference>
<i
class="iconfont icon-icon-piliangcaozuo imeiicondefault"
:class="imeipopover ? 'imeiiconActive' : 'imeiicon'"
style="font-size: 12px"
@click.prevent="imeiiconClick(index)"
></i>
</template>
<el-input
placeholder="一行一项,最多支持200行"
type="textarea"
:rows="12"
style="border: none"
v-model="item.value"
/>
<div class="popoverfooter">
<el-button size="small" @click.stop="imeipopover[index] = false"
>关闭</el-button
>
<el-button size="small" @click.stop="item.value = ''"
>清空</el-button
>
<el-button size="small" type="primary" @click.stop="onSearch"
>查询</el-button
>
</div>
</el-popover>
</template>
</el-input>
<el-select
style="width: 155px"
v-if="item.type === 'el-select'"
v-model="item.value"
:clearable="true"
:placeholder="item.placeholder"
><el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option
></el-select>
</div>
<el-button type="primary" @click.stop="onSearch">查询</el-button>
<el-button @click.stop="onRest">重置</el-button>
<el-popover
v-if="extrainputs.length > 0"
placement="bottom-start"
:visible="extrapopover"
width=""
trigger="click"
>
<template #reference>
<el-button @click="extrapopover = !extrapopover">更多选项</el-button>
</template>
<div class="extrabox">
<div
v-for="(item, index) in extrainputs"
:key="String(index)"
class="extraitem"
>
<div class="extraitemtitle">{{ item.title }}</div>
<el-input
clearable
v-if="item.type=='el-input'"
v-if="item.type == 'el-input'"
v-model="item.value"
size="large"
class="topinput"
:placeholder="item.placeholder"
>
</el-input>
>
</el-input>
<el-select
v-if="item.type === 'el-select'"
v-model="item.value"
:clearable="true"
:placeholder="item.placeholder"
><el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option
></el-select>
<el-date-picker
v-if="item.type=='el-date-picker'"
v-if="item.type == 'el-date-picker'"
v-model="item.value"
:style="{ width: item.width }"
size="large"
type="datetimerange"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
range-separator="至"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss"
:default-time="[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59)
]"
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
/>
</div>
</div>
<div class="extrafooter">
<el-button size="small" @click.stop="onCancelExtra">取消</el-button>
<el-button type="primary" size="small" @click.stop="onSearch">查询</el-button>
</div>
</el-popover>
</div>
</div>
<div class="extrafooter">
<el-button @click.stop="onCancelExtra">取消</el-button>
<el-button type="primary" @click.stop="onSearch">查询</el-button>
</div>
</el-popover>
</div>
</template>
<script setup>
import {markRaw,ref,computed} from 'vue';
import {ElInput} from "element-plus";
import { markRaw, ref, computed } from "vue";
import { ElInput } from "element-plus";
const props=defineProps(['inputs']);
const $emit=defineEmits(['onSrarch','onRest']);
const extrapopover=ref(false);
const extrainputs=ref([]);
const inputdatas=computed(()=>{
if(props.inputs.length>2){
const filters=props.inputs.slice(2,props.inputs.length);
extrainputs.value=filters;
return props.inputs.slice(0,2);
}
return props.inputs;
});
const imeipopover=ref([false]);
const imeiiconClick=(index)=>{
imeipopover.value[index]=true;
}
const props = defineProps(["inputs"]);
const $emit = defineEmits(["onSrarch", "onRest"]);
const extrapopover = ref(false);
const extrainputs = ref([]);
const inputdatas = computed(() => {
if (props.inputs.length > 2) {
const filters = props.inputs.slice(2, props.inputs.length);
extrainputs.value = filters;
return props.inputs.slice(0, 2);
}
return props.inputs;
});
const imeipopover = ref([false]);
const defaultTime1 = new Date(2000, 1, 1, 12, 0, 0)
const imeiiconClick = (index) => {
imeipopover.value[index] = true;
};
const onSearch=()=>{
const result={};
console.log(inputdatas.value,extrainputs.value);
inputdatas.value.map((h)=>{
result[h.name]=h.value.replace('\n',',');
});
extrainputs.value.map((h)=>{
if(h.type == 'el-input'){
result[h.name]=h.value.replace('\n',',');
}else if (h.type == 'el-date-picker'){
result[h.name]=h.value;
const defaultTime1 = new Date(2000, 1, 1, 12, 0, 0);
const onSearch = () => {
const result = {};
inputdatas.value.map((h) => {
if (h.type == "el-input") {
result[h.name] = h.value.replace("\n", ",");
} else {
result[h.name] = h.value;
console.log(result[h.name], "result[h.name]", h.value);
}
});
console.log(result,'result');
$emit('onSearch',result);
extrapopover.value = !extrapopover;
}
const onRest=()=>{
const result={};
extrainputs.value.map((h)=>{
h.value="";
result[h.name]='';
extrainputs.value.map((h) => {
if (h.type == "el-input") {
result[h.name] = h.value.replace("\n", ",");
} else {
result[h.name] = h.value;
}
});
inputdatas.value.map((h)=>{
h.value="";
result[h.name]='';
});
$emit('onRest',result);
}
const onCancelExtra=()=>{
$emit("onSearch", result);
extrapopover.value = !extrapopover;
}
};
const onRest = () => {
const result = {};
extrainputs.value.map((h) => {
h.value = "";
result[h.name] = "";
});
inputdatas.value.map((h) => {
h.value = "";
result[h.name] = "";
});
$emit("onRest", result);
};
const onCancelExtra = () => {
extrapopover.value = !extrapopover;
};
</script>
<style lang="scss">
.saletopbox{
<style lang="scss">
.saletopbox {
background: #fff;
padding:20px;
padding: 5px 20px 20px;
box-sizing: border-box;
display:flex;
align-items:center;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 10px;
gap: 10px;
}
.inputbox{
display:flex;
align-items:center;
justify-content: flex-start;
.inputbox {
display: flex;
align-items: center;
justify-content: flex-start;
}
.imeiicondefault{
height:26px;
width:26px;
box-sizing: border-box;
border-radius: 4px;
background: #f0f2f5;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.extraitem{
.extraitemtitle{
font-size:13px;
margin-bottom:5px;
color:#101010;
}
}
.extrabox{
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.extrafooter{
display: flex;
justify-content: flex-end;
align-items: center;
margin-top:12px;
}
.popoverfooter{
margin-top:15px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap:5px;
.imeiicondefault {
height: 20px;
width: 20px;
box-sizing: border-box;
border-radius: 4px;
background: #f0f2f5;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.extraitem {
.extraitemtitle {
font-size: 13px;
margin-bottom: 5px;
color: #101010;
}
}
.extrabox {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.extrafooter {
display: flex;
justify-content: flex-end;
align-items: center;
margin-top: 12px;
}
.popoverfooter {
margin-top: 15px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 5px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import Saleorder from './views/saleorder/index.vue';
import CommodityManagement from './views/CommodityManagement/index.vue';
import NewlyBuiltGoods from './views/NewlyBuiltGoods/index.vue';
import Home from './views/Home.vue';
import QualityWork from './views/qualityWork/index.vue';
@ -40,11 +40,11 @@ export const routes = [
children: [
{
meta: {
label: "新建商品",
label: "商品管理",
icon: markRaw(Location)
},
path: '/saleorder',
component: Saleorder,
path: '/CommodityManagement',
component: CommodityManagement,
},
{
meta: {

View File

@ -2,6 +2,7 @@
import axios, * as defaultAxios from 'axios';
import { getStorage, deloneStorage, jsonurldata } from "./commont";
import { ElMessage } from 'element-plus';
import { deepClone } from '../services/commont'
@ -51,7 +52,7 @@ export default ({
// const {promise, resolve, reject} =Promise.withResolvers();
return new Promise((resolve, reject) => {
const params = new FormData();
let newdatas = typeof (data) == "string" ? data : deepClone(data);
let outerTrigger = trigger;
try {
outerTrigger = JSON.stringify(trigger);
@ -71,12 +72,12 @@ export default ({
var axiosfn = {
"delete": (url, paramdata, config) => {
let newurl = url
let str = data && Object.keys(data).length > 0 ? "/" + jsonurldata(data) : ""
let str = newdatas && Object.keys(newdatas).length > 0 ? "/" + jsonurldata(newdatas) : ""
newurl = url + str
return axios.delete(newurl, config)
}, "post": axios.post, "get": (url, paramdata, config) => {
let newurl = url
let str = data && Object.keys(data).length > 0 ? "/" + jsonurldata(data) : ""
let str = newdatas && Object.keys(newdatas).length > 0 ? "/" + jsonurldata(newdatas) : ""
newurl = url + str
return axios.get(newurl, config)
}, "put": axios.put
@ -130,7 +131,6 @@ export default ({
}
axioshooks = axiosfn[method] ? axiosfn[method] : axios.post
// console.log(config,"config")
if (!url || !dispatchEffect()) return;
// ONLY trigger by query
if (outerTrigger && !innerTrigger) {
@ -139,42 +139,49 @@ export default ({
let paramsdata = null;
if (data) {
if (newdatas) {
if (method && method == 'file') {
let filekey = "";
const fileindex = _Object.keys(newdatas).find((f) => f == "filekey");
if (fileindex) {
filekey = newdatas["filekey"];
}
console.log(newdatas,'newdatas',filekey);
_Object.values(data).map((d, index) => {
if ((d && d != '') || typeof d == 'number') {
if (Object.keys(data)[index] == 'file') {
d.map((h)=>{
params.append('file', h, h.name);
if (filekey != "" && Object.keys(data)[index] == filekey) {
if (d && Array.isArray(d)) {
console.log(d,'ddd');
d.map((h, index) => {
console.log(h,'file');
params.append(filekey,h, h.name);
})
} else if (Object.keys(data)[index] == 'filekey') {
params.append(d, data[d]);
} else {
params.append(Object.keys(data)[index], d);
params.append(filekey, d, d.name);
}
} else {
params.append(Object.keys(newdatas)[index], d);
}
});
paramsdata = params;
} else if (method && method == 'get') {
const getmethoddata = {};
_Object.values(data).map((h, index) => {
_Object.values(newdatas).map((h, index) => {
if ((h && h != '') || typeof h == 'number') {
getmethoddata[Object.keys(data)[index]] = h;
getmethoddata[Object.keys(newdatas)[index]] = h;
}
});
paramsdata = { params: getmethoddata };
} else {
if (data && data != '' && parse_param) {
data = parse_param(data);
if (newdatas && newdatas != '' && parse_param) {
newdatas = parse_param(newdatas);
}
for (const p in data) {
if (!data[p]) {
data[p] = '';
for (const p in newdatas) {
if (!newdatas[p]) {
newdatas[p] = '';
}
if (data[p]) {
params.append(p, data[p]);
if (newdatas[p]) {
params.append(p, newdatas[p]);
}
}

View File

@ -0,0 +1,420 @@
<template>
<div class="Special_offer_box">
<div class="table_box_header">
<el-tabs class="demo-tabs" v-model="activeName" @tab-change="TabChange">
<el-tab-pane
v-for="item in tabs"
:key="item.value"
:label="item.label"
:name="item.value"
></el-tab-pane>
</el-tabs>
<SearchForm :inputs="Inputs" @onSearch="onSearch" @onRest="onRest" />
</div>
<div class="table_box_center">
<Table
ref="TableRef"
:key="TableKey"
:TabLoading="TabLoading"
:TableData="TableData"
:TableLabel="TableLabel"
>
<template #OperateButton="{ row }">
<OperateButton
:ButtonList="row.ButtonGroup"
:row="row"
></OperateButton></template
></Table>
<PaginaTion
:total="totalNumbel"
v-model:current-page="commodityInfoDto.pageNo"
v-model:page-size="commodityInfoDto.pageSize"
@handleSizeChange="handleSizeChange"
@handleCurrentChange="getDatas"
></PaginaTion>
</div>
</div>
</template>
<script setup>
import { ref, unref, computed, reactive, onMounted } from "vue";
import { router } from "@/router.js";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import SearchForm from "@components/searchForm/index.vue";
import Table from "@components/table.vue";
import OperateButton from "@/components/OperateButton.vue";
import PaginaTion from "@components/Pagination.vue";
import {
select_by_conditions,
get_commodity_id,
publish,
pull_off,
delete_one,
} from "@/api/CommodityManagement";
import { getshopInfo } from "@/api/newlybuiltgoods";
const activeName = ref("");
const tabs = ref([
{ label: "全部", value: "", total: 0 },
{ label: "草稿箱", value: "1", total: 0 },
{ label: "待发布", value: "2", total: 0 },
{ label: "发布成功", value: "-3", total: 0 },
{ label: "发布失败", value: "-4", total: 0 },
{ label: "手动下架", value: "-2", total: 0 },
{ label: "已售出", value: "3", total: 0 },
{ label: "其他", value: "99", total: 0 },
]);
const Inputs = ref([
{
type: "el-input",
placeholder: "查询闲鱼商品ID",
title: "闲鱼商品ID",
name: "commodityId",
value: "",
popover: true,
},
{
type: "el-select",
placeholder: "请选择闲鱼店铺",
title: "闲鱼店铺",
name: "xyId",
value: "",
options: [],
},
{
type: "el-select",
placeholder: "请输入商品类型",
title: "商品类型",
name: "auctionType",
value: "",
options: [
{ label: "一口价", value: "a" },
{ label: "拍卖", value: "b" },
],
},
{
type: "el-select",
placeholder: "请选择分类",
title: "商品分类",
name: "itemBizType",
value: "",
options: [
{ label: "普通商品", value: "2" },
{ label: "特卖商品", value: "24" },
],
},
{
type: "el-input",
placeholder: "请输入商品名称",
name: "title",
value: "",
title: "商品名称",
},
{
type: "el-date-picker",
title: "创建时间",
placeholder: "",
name: "createTime",
value: [],
width: "215px",
},
{
type: "el-date-picker",
title: "上架时间",
placeholder: "",
name: "shelfTime",
value: [],
width: "215px",
},
]);
const TableRef = ref(null);
const TableKey = ref(new Date().getTime());
const TabLoading = ref(false);
const TableData = ref([]);
const TableLabel = ref([
{
label: "闲鱼商品ID",
param: "commodityId",
align: "center",
show: true,
display: "top_left",
},
{
label: "创建时间",
param: "createTime",
align: "center",
show: true,
display: "top_left",
},
{
label: "上架时间",
param: "createTime",
align: "center",
show: true,
display: "top_left",
},
{
label: "商品",
param: "",
align: "center",
show: true,
minwidth: "210",
},
{
label: "商品状态",
param: "publishStatusName",
align: "center",
show: true,
minwidth: "150",
},
{
label: "商品类型",
param: "itemBizType",
align: "center",
show: true,
minwidth: "150",
},
{
label: "分类",
param: "auctionType",
align: "center",
show: true,
minwidth: "150",
},
{
label: "售价(元)",
param: "retailPrice",
align: "center",
show: true,
minwidth: "150",
},
{
label: "库存(个)",
param: "stock",
align: "center",
show: true,
minwidth: "150",
},
{
label: "销量",
param: "salesVolume",
align: "center",
show: true,
minwidth: "150",
},
{
label: "闲鱼店铺",
param: "xyName",
align: "center",
show: true,
minwidth: "150",
},
{
label: "操作",
align: "center",
show: true,
fixed: "right",
minwidth: "150",
},
]);
const New_TableLabel = ref([]);
const ButtonListGroup = ref([
{
AssemblyName: "el-link",
name: "编辑",
show: false,
type: "primary",
mode: "detail",
confirm: (row) => {
get_commodity_id(row.id).then((res) => {
if (res.code === "200") {
router.push({
path: "/NewlyBuiltGoods",
query: {
params: JSON.stringify(res.data),
},
});
}
});
},
},
{
AssemblyName: "el-link",
name: "复制",
show: false,
type: "primary",
mode: "detail",
confirm: (row) => {},
},
{
AssemblyName: "el-link",
name: "上架",
show: false,
type: "primary",
mode: "detail",
confirm: (row) => {
publish(row.id).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
getDatas();
}
});
},
},
{
AssemblyName: "el-popconfirm",
name: "下架",
title: "是否下架?",
cancelText: "不用了",
popconfirmIcon: "el-icon-info",
iconColor: "red",
type: "danger",
show: false,
confirm: (row) => {
pull_off(row.id).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
getDatas();
}
});
},
},
{
AssemblyName: "el-popconfirm",
name: "删除",
title: "是否删除?",
cancelText: "不用了",
popconfirmIcon: "el-icon-info",
iconColor: "red",
type: "danger",
show: false,
confirm: (row) => {
delete_one(row.id).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
getDatas();
}
});
},
},
{
AssemblyName: "el-link",
name: "日志",
show: false,
type: "warning",
mode: "detail",
confirm: (row) => {},
},
]);
let commodityInfoDto = reactive({
pageNo: 1,
pageSize: 20,
publishStatus: "",
});
const totalNumbel = ref(0);
const getDatas = () => {
TabLoading.value = true;
select_by_conditions(commodityInfoDto)
.then((res) => {
TabLoading.value = false;
if (res.code === "200") {
const newData = Object.assign([], res.data.data);
newData.map((item) => {
item.ButtonGroup = ButtonListGroup.value.map((el) => {
if (
(el.name === "编辑" &&
[1, -4, -2].includes(item.publishStatus)) ||
(el.name === "下架" && [-3].includes(item.publishStatus)) ||
(el.name === "复制" &&
[1, -2, -3, -4, 3].includes(item.publishStatus)) ||
(el.name === "上架" && [-2, -4].includes(item.publishStatus)) ||
(el.name === "删除" && [1, -4, -2].includes(item.publishStatus))
) {
return { ...el, show: true };
}
return el;
});
});
console.log(newData);
TableData.value = newData;
totalNumbel.value = res.data.totalCount;
}
})
.catch((err) => {
TabLoading.value = false;
});
};
//
const onSearch = (value) => {
if (value.createTime) {
value.startCreateTime = new Date(value.createTime[0]).getTime();
value.endCreateTime = new Date(value.createTime[1]).getTime() + 86399999;
} else if (value.shelfTime) {
value.startShelfTime = new Date(value.shelfTime[0]).getTime();
value.endShelfTime = new Date(value.shelfTime[1]).getTime() + 86399999;
}
commodityInfoDto = {
...commodityInfoDto,
...value,
};
getDatas();
};
//
const onRest = (value) => {
commodityInfoDto = {
pageNo: 1,
pageSize: 20,
publishStatus: activeName.value,
};
getDatas();
};
const get_shopInfo = () => {
getshopInfo().then((res) => {
if (res.code === "200") {
const storeList = [];
res.data.forEach((item) => {
storeList.push({ label: item.xyName, value: item.id });
});
Inputs.value.find((e) => e.title == "闲鱼店铺").options = storeList;
}
});
};
onMounted(() => {
TabChange();
get_shopInfo();
});
const handleSizeChange = () => {
commodityInfoDto.pageNo = 1;
getDatas();
};
const TabChange = (val) => {
commodityInfoDto.publishStatus = activeName.value;
getDatas();
TableLabel.value.forEach((e) => {
e.show = !(
e.hasOwnProperty("NumberType") && !e.NumberType.includes(Number(val))
);
});
New_TableLabel.value = TableLabel.value;
TableKey.value = new Date().getTime();
};
</script>
<style lang="scss" scoped>
.Special_offer_box {
height: calc(100vh - 38px);
background: #f1f2f5;
}
.table_box_header {
width: 100%;
padding: 0 20px;
box-sizing: border-box;
background: #fff;
}
.table_box_center {
padding: 20px;
box-sizing: border-box;
}
</style>

View File

@ -208,9 +208,11 @@ const onCheckImg = () => {
checkimages.value = false;
let token = e.datas.token;
console.log(token,"token")
if (e.datas.token) {
axioshooks({
url: "auth/login3rd",
headers: {
loginType: "erpLogin",
token: e.datas.token,
@ -223,7 +225,7 @@ const onCheckImg = () => {
// addStorage("virtoken", e.data);
addStorage(
"virtoken",
"9wEUErM0vX7OGuPq7byzZA0KdSMhROI8cCWvQAK5bH8TyOwHhekuHF0vwF9cMg5h92fVFtoZssQv9Oo36CYbZmXjrWa56NWWLNppUGRiTFEHYNzPhn7NYBP7SqvPPI6z"
"47ewUzuYl8Omr40VtNlOONmiqIgOe9gjWsl5BWrnwWHMHp1XB1Ac9ADtwxMDp2G4p5e6fG079cSsfEDOmGY2SAXe3611imSBKgmq2SzGOOfP1d2TPlKYmnuvWSNFNou0"
);
if (props.callback) {
props.callback();

View File

@ -66,7 +66,7 @@
:type="el.type"
text
size="small"
@click="el.handler(item, index)"
@click="operation(el.label, item, index)"
>{{ el.label }}</el-button
>
</div>
@ -150,8 +150,14 @@ let that = newDataList;
const submit_specification = (formEl) => {
formEl.validate((valid) => {
if (!valid || !ruleForm.name) return;
if (
newDataList.value.find(
(e) => e.label.replace(/\s+/g, "") === ruleForm.name.replace(/\s+/g, "")
)
)
return ElMessage.warning("商品规格不能重复!");
if (newDataList.value.length >= 2)
return ElMessage.warning("超过输入限制!");
return ElMessage.warning("超过输入限制,商品规格最多添加两个");
specification_list_index.value++;
newDataList.value.push({
label: ruleForm.name,
@ -170,16 +176,10 @@ const submit_specification = (formEl) => {
{
type: "primary",
label: "编辑",
handler: (item) => {
item.disabled = true;
},
},
{
type: "danger",
label: "删除",
handler: (item, index) => {
newDataList.value.splice(index, 1);
},
},
],
inputGroup: {
@ -191,16 +191,24 @@ const submit_specification = (formEl) => {
ruleForm.name = "";
});
};
function operation(status, item, index) {
if (status == "编辑") {
item.disabled = true;
} else {
newDataList.value.splice(index, 1);
}
}
function onDelValueItem(index, ind) {
let newdatas = JSON.parse(JSON.stringify(newDataList.value[index].valueGrop));
newdatas.splice(ind, 1);
newDataList.value[index].valueGrop = newdatas;
newDataList.value = Object.assign([], newDataList.value);
console.log(newDataList.value, "newDataList.value111");
newDataList.value[index].valueGrop.splice(ind, 1);
}
function input_child_keydown(e, name, index) {
if (e.key !== "Enter" || !name) return;
if (
newDataList.value[index].valueGrop.find(
(e) => e.label.replace(/\s+/g, "") === name.replace(/\s+/g, "")
)
)
return ElMessage.warning("商品属性不能重复!");
if (newDataList.value.length <= 1) {
if (newDataList.value[index].valueGrop.length >= 10) return;
} else {

View File

@ -7,7 +7,6 @@
label-width="auto"
class="demo-ruleForm"
:size="formSize"
status-icon
>
<div class="head">
<div class="title">{{ createGoods.title }}</div>
@ -44,7 +43,7 @@
</div>
</el-form-item>
<el-form-item
v-if="ruleForm[createGoods.radio_group_select.params] === '24'"
v-if="ruleForm[createGoods.radio_group_select.params] === 24"
:label="createGoods.radio_group_sell.label"
:prop="createGoods.radio_group_sell.prop"
>
@ -52,7 +51,7 @@
v-loading="createGoods.radio_group_sell.loading"
element-loading-text="加载中..."
v-model="
ruleForm.flash_sale_do[createGoods.radio_group_sell.params]
ruleForm.flashSaleDO[createGoods.radio_group_sell.params]
"
@change="createGoods.radio_group_sell.change"
>
@ -165,6 +164,7 @@
:autoUpload="false"
:multiple="goodsInfo.more_src.multiple"
@onSuccessFiles="goodsInfo.more_src.onSuccessFiles"
@handleRemove="goodsInfo.more_src.handleRemove"
/>
</div>
</div>
@ -174,8 +174,9 @@
:limit="goodsInfo.White_src.limit"
:imgList="goodsInfo.White_src.fileImgList"
:autoUpload="false"
:multiple="goodsInfo.White_src.multiple"
@onSuccessFiles="goodsInfo.White_src.onSuccessFiles"
@handleSuccess="goodsInfo.more_src.handleSuccess"
@handleRemove="goodsInfo.White_src.handleRemove"
/>
</el-form-item>
<el-form-item label="商品标题" prop="title">
@ -275,6 +276,22 @@
</div>
</div>
</div>
<el-input
v-model="ruleForm.bidDto[item.params]"
style="width: 480px"
:placeholder="`请输入${item.label}`"
:clearable="true"
:disabled="item.disabled"
type="text"
v-if="
item.type === 'el-input' &&
(item.label == '保证金' || item.label == '加价幅度')
"
>
<template #suffix v-if="item.suffix">
{{ item.suffix }}
</template>
</el-input>
<el-input
v-model="ruleForm[item.params]"
style="width: 480px"
@ -282,7 +299,7 @@
:clearable="true"
:disabled="item.disabled"
type="text"
v-if="item.type === 'el-input'"
v-else-if="item.type === 'el-input'"
>
<template #suffix v-if="item.suffix">
{{ item.suffix }}
@ -305,7 +322,7 @@
:label="el.label"
align="center"
>
<template #header="scope">
<template #header>
<el-input
style="width: 80px"
v-if="el.label === '售价' || el.label === '库存'"
@ -382,11 +399,11 @@
</el-table-column>
</el-table>
<el-select
v-if="item.type === 'el-select'"
style="width: 240px"
v-model="ruleForm[item.params]"
:placeholder="`请选择${item.label}`"
:clearable="true"
v-if="item.type === 'el-select'"
><el-option
v-for="el in item.options"
:key="el.value"
@ -397,18 +414,19 @@
></el-select>
<el-date-picker
v-if="item.type === 'daterange'"
v-model="ruleForm[item.params]"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:size="size"
@change="item.change"
/>
</el-form-item>
</div>
</div>
<div class="main-box">
<div class="title">{{ logistics.title }}</div>
<div class="price_list">
<div class="logistics">
<el-form-item
:label="logistics.configured.label"
:prop="logistics.configured.prop"
@ -426,12 +444,12 @@
</el-radio-group>
</el-form-item>
</div>
<div>
<el-form-item prop="logistics">
<div class="logistics_input" v-if="ruleForm.logistics === '2'">
<el-form-item label=" ">
<el-input
placeholder="请输入金额"
style="width: 180px"
v-model="ruleForm.transportFee"
:placeholder="el.label"
size="small"
>
</el-input>
</el-form-item>
@ -460,6 +478,7 @@
<script setup>
import { Plus, Edit, Filter } from "@element-plus/icons-vue";
import { router } from "@/router.js";
import { useRoute } from "vue-router";
import { ref, reactive, onMounted } from "vue";
import UploadImage from "@components/Upload/newfileupload.vue";
import SpecificationDialog from "./components/specificationDialog.vue";
@ -467,13 +486,63 @@ import { ElMessage } from "element-plus";
import { deepClone } from "@/services/commont";
const ruleFormRef = ref(null);
const tableRef = ref(null);
const route = useRoute();
import {
getGoodsType,
getGoodsInfo,
getshopInfo,
uploadImage,
region,
qualityList,
address_default,
publish_shelve,
} from "@/api/newlybuiltgoods";
let ruleForm = reactive({
bidDate: [],
auctionType: "b", //
itemBizType: 24, // 0 1 2 24
flashSaleDO: {
tag: 1,
foodProDate: "0", // -
foodExpireDate: "0", // -
}, //
xyShopId: "",
channelCatId: "", //id
classValue: [],
spBizType: "99", //99 :1, :2, :3, :8, 3C:9, :16, :17, :18, /:19, :20, :21
pvListDtoList: [],
title: "", //
desc: "", //
reservePrice: "", //
originalPrice: "", //
stuffStatus: "", //
divisionId: "", //
categoryId: 0, //Id,: 50025386long810
bidDto: {
bidBail: "", //
bidStep: "", //
bidEndTime: "", //
bidStartTime: "", //
}, //
quantity: 1, //
skuList: [
{
quantity: 0, //
price: 0, //
property: [{ key: "", value: "" }], //
},
],
xyImages: [], //
aliImages: [], //
whiteBgImage: "", // ()
flag: "1", //稿-0 -1
republishId: 0, //id
logistics: "1", // 1 2 bidStep
transportFee: "", // 2
templateId: 0, // 3
});
const createGoods = reactive({
title: "新建商品",
radio_group_goods: {
@ -484,8 +553,9 @@ const createGoods = reactive({
options: [
{
label: "一口价",
value: "a",
value: "b",
change: () => {
ruleFormRef.value.clearValidate();
priceList.fixPrice = [
{
type: "add",
@ -520,66 +590,99 @@ const createGoods = reactive({
prop: "stuffStatus",
params: "stuffStatus",
disabled: true,
options: [{ label: "888", value: 6 }],
options: qualityData.value,
},
];
},
},
{
label: "拍卖",
value: "b",
value: "a",
change: () => {
ruleFormRef.value.clearValidate();
priceList.fixPrice = [
{
type: "el-input",
label: "起拍价",
prop: "",
params: "",
prop: "reservePrice",
params: "reservePrice",
disabled: false,
},
{
type: "el-input",
label: "原价",
prop: "",
params: "",
prop: "originalPrice",
params: "originalPrice",
disabled: false,
},
{
type: "el-input",
label: "加价幅度",
prop: "",
params: "",
prop: "bidStep",
params: "bidStep",
disabled: false,
},
{
type: "el-input",
label: "保证金",
prop: "",
params: "",
disabled: true,
prop: "bidBail",
params: "bidBail",
disabled: false,
},
{
type: "daterange",
label: "拍卖时间",
prop: "",
params: "",
disabled: true,
params: "bidDate",
prop: "bidDate",
disabled: false,
change: (e) => {
const now = new Date();
const startTime = new Date(e[0]);
const endTime = new Date(e[1]);
//
if (startTime.getTime() <= now.getTime()) {
ElMessage.warning("拍卖开始时间必须大于当前时间");
return false; //
}
// 15
const maxEndTime = new Date(
now.getTime() + 15 * 24 * 60 * 60 * 1000
); // 15
if (
endTime.getTime() <= startTime.getTime() ||
endTime.getTime() > maxEndTime.getTime()
) {
ElMessage.warning(
"结束时间必须在开始时间之后且小于当前时间后的15天"
);
return false; //
}
if (e) {
ruleForm.bidDto.bidStartTime = new Date(e[0]).getTime();
ruleForm.bidDto.bidEndTime = new Date(e[1]).getTime();
} else {
ruleForm.bidDto.bidStartTime = "";
ruleForm.bidDto.bidEndTime = "";
}
},
},
{
type: "el-input",
label: "库存",
prop: "",
params: "",
prop: "quantity",
params: "quantity",
disabled: true,
suffix: "拍卖商品支支持发布一个库存",
},
{
type: "el-select",
label: "成色",
prop: "",
params: "",
disabled: true,
options: [{ label: "888", value: 6 }],
prop: "stuffStatus",
params: "stuffStatus",
disabled: false,
options: qualityData.value,
},
];
},
@ -618,39 +721,39 @@ const createGoods = reactive({
options: [
{
label: "临期",
value: "1",
value: 1,
},
{
label: "孤品",
value: "2",
value: 2,
},
{
label: "断码",
value: "3",
value: 3,
},
{
label: "微瑕",
value: "4",
value: 4,
},
{
label: "尾货",
value: "5",
value: 5,
},
{
label: "官翻",
value: "6",
value: 6,
},
{
label: "全新",
value: "7",
value: 7,
},
{
label: "福袋",
value: "8",
value: 8,
},
{
label: "其他",
value: "99",
value: 9,
},
],
change: () => {
@ -705,9 +808,10 @@ const information = reactive({
});
item.child.find((e) => e.value === 0);
information.goods_attribute.group.push({
label: item.property_name,
propertyId: item.propertyId,
propertyId: item.property_id,
options: item.child.slice(0, 8),
add_attribute: {
querySearchAsync: (queryString, cb) => {
@ -721,6 +825,8 @@ const information = reactive({
}, 500 * Math.random());
},
handleSelect: (item, el, index) => {
console.log(item, "itemtemtekte");
const pvlistdto = item.options.find((e) => e.link == el);
ruleForm.pvListDtoList[index] = {
propertyId: item.propertyId,
@ -766,39 +872,58 @@ const goodsInfo = reactive({
type: "UploadImage",
label: "多图",
params: "inspection_avatars",
// prop: "inspection_avatar",
prop: "inspection_avatar",
limit: 9,
fileImgList: [],
paramslist: [],
multiple: true,
onSuccessFiles: (filelist) => {
goodsInfo.more_src.fileImgList = filelist;
goodsInfo.more_src.paramslist = filelist.raw;
console.log(
goodsInfo.more_src.paramslist,
"goodsInfo.more_src.paramslist"
);
uploadImage({
filekey: "files",
xyShopId: ruleForm.xyShopId,
files: goodsInfo.more_src.paramslist,
type: 1,
files: filelist,
}).then((res) => {
console.log(res);
if (res.code === "200") {
console.log(res);
ruleForm.xyImages = res.data.xy; //
ruleForm.aliImages = res.data.ali; //
} else {
ElMessage.warning(res.msg);
}
});
},
handleRemove: (filelist) => {
if (!ruleForm.aliImages.length) return;
const nameToFind = filelist[0].name;
const index = ruleForm.aliImages.findIndex((url) => {
const urlParts = url.split("/");
const filename = urlParts[urlParts.length - 1];
return filename.includes(nameToFind);
});
ruleForm.aliImages.splice(index, 1);
ruleForm.xyImages.splice(index, 1);
},
},
White_src: {
type: "UploadImage",
label: "主图",
label: "白底图",
params: "inspection_avatar",
// prop: "inspection_avatar",
prop: "inspection_avatar",
limit: 1,
fileImgList: [],
onSuccessFiles: (file, filelist) => {
console.log(file, filelist, "file,filelist");
multiple: false,
onSuccessFiles: (filelist) => {
uploadImage({
filekey: "files",
xyShopId: ruleForm.xyShopId,
files: filelist,
}).then((res) => {
if (res.code === "200") {
ruleForm.whiteBgImage = res.data.xy[0];
}
});
},
handleRemove: () => {
ruleForm.whiteBgImage = "";
},
},
Deliver_location: {
@ -809,10 +934,12 @@ const goodsInfo = reactive({
clearable: true,
options: [],
visibleChange: (e) => {
ruleForm.divisionId = goodsInfo.Deliver_location.params[3];
if (e) return;
ruleForm.divisionId = goodsInfo.Deliver_location.params.slice(-1)[0];
},
},
});
const qualityData = ref([]);
const priceList = reactive({
title: "定价与库存",
dialogTitle: "设置商品规格",
@ -853,7 +980,7 @@ const priceList = reactive({
prop: "stuffStatus",
params: "stuffStatus",
disabled: true,
options: [{ label: "888", value: 6 }],
options: qualityData.value,
},
],
});
@ -880,55 +1007,30 @@ const logistics = reactive({
change: () => {},
},
});
const ruleForm = reactive({
auctionType: "a", //
itemBizType: "24", // 0 1 2 24
flash_sale_do: {
tag: "1",
foodProDate: "", // -
foodExpireDate: "", // -
}, //
xyShopId: "",
channelCatId: "", //id
classValue: [],
spBizType: "99", //99 :1, :2, :3, :8, 3C:9, :16, :17, :18, /:19, :20, :21
pvListDtoList: [],
title: "", //
desc: "", //
reservePrice: "", //
originalPrice: "", //
stuffStatus: "", //
divisionId: "", //
categoryId: 0, //Id,: 50025386long810
bidDto: {
bidBail: 0, //
bidEndTime: 0, //
bidStartTime: 0, //
bidStep: 0, //
}, //
quantity: 1, //
skuList: [
{
quantity: 0, //
price: 0, //
property: [{ key: "", value: "" }], //
},
],
xyImages: [], //
aliImages: [], //
whiteBgImage: 0, //
flag: 0, //稿-0 -1
republishId: 0, //id
logistics: "1", // 1 2 3
transportFee: "", // 2
templateId: 0, // 3
});
const bidStep = (rule, value, callback) => {
if (ruleForm.bidDto.bidStep === "") {
callback(new Error("出价幅度,不能为空"));
} else {
callback();
}
};
const bidBail = (rule, value, callback) => {
if (ruleForm.bidDto.bidBail === "") {
callback(new Error("保证金,不能为空"));
} else {
callback();
}
};
const rules = reactive({
auctionType: [{ trigger: "blur", required: true, message: "请选择商品类型" }],
title: [{ trigger: "blur", required: true, message: "请输入商品标题" }],
desc: [{ trigger: "blur", required: true, message: "请输入商品描述" }],
title: [
{ trigger: "blur", required: true, message: "请输入商品标题" },
{ min: 3, max: 30, message: "最少输入3个字符", trigger: "blur" },
],
desc: [
{ trigger: "blur", required: true, message: "请输入商品描述" },
{ min: 5, max: 5000, message: "最少输入5个字符", trigger: "blur" },
],
divisionId: [{ trigger: "blur", required: true, message: "请选择发货地" }],
reservePrice: [
{ trigger: "blur", required: true, message: "请输入商品售价" },
@ -936,7 +1038,17 @@ const rules = reactive({
stuffStatus: [{ trigger: "blur", required: true, message: "请输入商品成色" }],
quantity: [{ trigger: "blur", required: true, message: "请输入库存" }],
logistics: [{ trigger: "blur", required: true, message: "请选择物流配置" }],
inspection_avatar: [
{ trigger: "blur", required: true, message: "请选择商品图片" },
],
classValue: [
{ trigger: "change", required: true, message: "请选择商品分类" },
],
bidStep: [{ validator: bidStep, trigger: "blur", required: true }],
bidBail: [{ validator: bidBail, trigger: "blur", required: true }],
bidDate: [{ trigger: "change", required: true, message: "请选择拍卖时间" }],
});
const createFilter = (queryString) => {
return (restaurant) => {
return (
@ -955,17 +1067,15 @@ const add_xyShop = () => {
};
//
const select_store = (item) => {
console.log(ruleForm, "dsfjsdklfjsdlfhsdlfhsdlakhfsadlfhsadkhfkls");
ruleForm.xyShopId = item.id;
};
const newDataList = ref([]);
const specificationSubmit = (row) => {
ruleFormRef.value.resetFields();
ruleFormRef.value.clearValidate();
if (!row.length) return;
newDataList.value = deepClone(row);
priceList.specification_arr = deepClone(row);
console.log(priceList, "priceList", row);
const specification_list = [];
const tabelList = [];
@ -1028,7 +1138,7 @@ const specificationSubmit = (row) => {
prop: "stuffStatus",
params: "stuffStatus",
disabled: true,
options: [{ label: "888", value: 6 }],
options: qualityData.value,
},
];
},
@ -1046,6 +1156,11 @@ const specificationSubmit = (row) => {
params: "price",
keydown: (e, data, el) => {
if (e.key !== "Enter") return;
if (data.tableData.every((item) => !item.price)) {
data.new_tableData.forEach((item) => {
item.price = el.search;
});
}
data.tableData.forEach((item) => {
item.price = el.search;
});
@ -1057,6 +1172,11 @@ const specificationSubmit = (row) => {
params: "inventory",
keydown: (e, data, el) => {
if (e.key !== "Enter") return;
if (data.tableData.every((item) => !item.price)) {
data.tableData.forEach((item) => {
item.inventory = el.search;
});
}
data.tableData.forEach((item) => {
item.inventory = el.search;
});
@ -1068,8 +1188,8 @@ const specificationSubmit = (row) => {
{
type: "el-input",
label: "原价",
prop: "originalPrice",
params: "originalPrice",
prop: "reservePrice",
params: "reservePrice",
disabled: false,
},
{
@ -1078,7 +1198,7 @@ const specificationSubmit = (row) => {
prop: "stuffStatus",
params: "stuffStatus",
disabled: true,
options: [{ label: "888", value: 6 }],
options: qualityData.value,
},
];
row.forEach((item) => {
@ -1134,7 +1254,6 @@ const specificationSubmit = (row) => {
});
});
priceList.fixPrice.map((item) => {
console.log(item, "itemmm");
if (item.type === "edit") {
item.specification_list = specification_list;
} else if (item.type === "el-table") {
@ -1149,8 +1268,6 @@ const get_filters = (arr) => {
arr.valueGrop.map((e) => {
filters.push({ label: e.label, value: e.label });
});
console.log(filters, "arr");
return filters;
};
const generateCombinations = (attributeGroups) => {
@ -1176,7 +1293,6 @@ const generateCombinations = (attributeGroups) => {
let result = []; //
generate(0, {}); //
console.log(result, "result");
return result;
};
const specificationClose = () => {
@ -1193,97 +1309,155 @@ const get_shopInfo = () => {
};
//
const get_region = () => {
region().then((res) => {
address_default(1).then((res) => {
if (res.code === "200") {
const transformData = (data) => {
return data.map((item) => {
let result = {
label: item.name,
value: item.id,
ruleForm.divisionId = res.data.district_id;
goodsInfo.Deliver_location.params = [
res.data.province_id,
res.data.city_id,
res.data.district_id,
];
region().then((res) => {
if (res.code === "200") {
const transformData = (data) => {
return data.map((item) => {
let result = {
label: item.name,
value: item.id,
};
if (item.child && Array.isArray(item.child)) {
result.children = transformData(item.child);
}
return result;
});
};
if (item.child && Array.isArray(item.child)) {
result.children = transformData(item.child);
}
return result;
goodsInfo.Deliver_location.options = transformData(res.data);
}
});
}
});
};
//
const get_qualityList = () => {
qualityList().then((res) => {
if (res.code === "200") {
res.data.forEach((item) => {
qualityData.value.push({
label: item.quality,
value: item.number,
});
};
goodsInfo.Deliver_location.options = transformData(res.data);
});
}
});
};
//稿
const SaveDraft = () => {};
const SaveDraft = () => {
console.log(priceList.fixPrice, "priceList.specification_arr");
};
const publish = (formRef) => {
if (!formRef) return;
formRef.validate((valid, fields) => {});
formRef.validate((valid, fields) => {
if (!valid) return;
const dataList = priceList.fixPrice.filter(
(item) => item.label === "销售规格"
)[0];
if (dataList) {
const ruleFormSkuList = generateSkuList(
dataList.tableData,
dataList.tabelList
);
ruleForm.skuList = ruleFormSkuList;
}
publish_shelve(ruleForm).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
} else {
ElMessage.warning(res.msg);
}
});
});
};
function generateSkuList(array1, array2) {
let skuList = [];
array1.forEach((skuVariant) => {
let sku = {
quantity: "", // 0
price: "", // 0
property: [], //
};
array2.forEach((item) => {
console.log(item, "item,");
let value = skuVariant[item.params];
console.log(value, "value", skuVariant, "skuVariant");
sku.quantity = skuVariant.inventory;
sku.price = skuVariant.price;
if (
value &&
item.filters &&
item.filters.some((filter) => filter.value === value)
) {
sku.property.push({ key: item.label, value: value });
}
});
skuList.push(sku);
});
return skuList;
}
onMounted(() => {
if (route.query.params) {
let params = JSON.parse(route.query.params);
// console.log(params,"praaafsdf");
// ruleForm = {
// bidDate: [],
// auctionType: params.auctionType, //
// itemBizType: params.itemBizType, // 0 1 2 24
// flashSaleDO: {
// tag: params.flashSaleType,
// foodProDate: "", // -
// foodExpireDate: "", // -
// }, //
// xyShopId: "",
// channelCatId: "", //id
// classValue: [],
// spBizType: "99", //99 :1, :2, :3, :8, 3C:9, :16, :17, :18, /:19, :20, :21
// pvListDtoList: [],
// title: "", //
// desc: "", //
// reservePrice: "", //
// originalPrice: "", //
// stuffStatus: "", //
// divisionId: "", //
// categoryId: 0, //Id,: 50025386long810
// bidDto: {
// bidBail: "", //
// bidStep: "", //
// bidEndTime: "", //
// bidStartTime: "", //
// }, //
// quantity: 1, //
// skuList: [
// {
// quantity: 0, //
// price: 0, //
// property: [{ key: "", value: "" }], //
// },
// ],
// xyImages: [], //
// aliImages: [], //
// whiteBgImage: "", // ()
// flag: "1", //稿-0 -1
// republishId: 0, //id
// logistics: "1", // 1 2 bidStep
// transportFee: "", // 2
// templateId: 0, // 3
// };
}
get_shopInfo();
get_region();
get_qualityList();
createGoods.radio_group_sell.change();
});
// const submitSpecification = (valName) => {
// specification_list_index.value++;
// priceList.specification_arr.push({
// label: valName,
// num: 0,
// index: specification_list_index.value,
// disabled: false,
// keydown: (e, item, index) => {
// if (e.key !== "Enter") return;
// if (item.label.length <= 4) {
// item.disabled = false;
// } else {
// ElMessage.warning("4");
// }
// },
// buttonGroup: [
// {
// type: "primary",
// label: "",
// handler: (item) => {
// item.disabled = true;
// },
// },
// {
// type: "danger",
// label: "",
// handler: (item, index) => {
// priceList.specification_arr.splice(index, 1);
// },
// },
// ],
// inputGroup: {
// valueName: "",
// placeholder: "",
// keydown: (e, name, index) => {
// if (e.key !== "Enter" || !name) return;
// if (priceList.specification_arr.length <= 1) {
// if (priceList.specification_arr[index].valueGrop.length >= 10) return;
// } else {
// if (
// priceList.specification_arr[0].valueGrop.length *
// priceList.specification_arr[1].valueGrop.length >=
// 100
// )
// return;
// }
// priceList.specification_arr[index].valueGrop.push({
// type: "danger",
// label: priceList.specification_arr[index].inputGroup.valueName,
// delete: (item, ind) => {
// priceList.specification_arr[index].valueGrop.splice(ind, 1);
// },
// });
// priceList.specification_arr[index].num =
// priceList.specification_arr[index].valueGrop.length;
// priceList.specification_arr[index].inputGroup.valueName = "";
// },
// },
// valueGrop: [],
// });
// };
</script>
<style lang="scss" scoped>
@ -1443,6 +1617,11 @@ onMounted(() => {
}
}
}
.logistics {
:deep(.el-form-item) {
margin-bottom: 0 !important;
}
}
}
}

View File

@ -91,7 +91,7 @@
<script setup>
import { router } from "@/router.js";
import { ref, reactive, onMounted, watch, computed } from "vue";
import { ref, reactive, onMounted, computed } from "vue";
import { Delete, Edit, Search, Share, Upload } from "@element-plus/icons-vue";
import CreateStoreDialog from "./CreateStoreDialog/CreateStoreDialog.vue";
import {
@ -104,7 +104,6 @@ import {
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
const route = useRoute();
const CreateStoreDialogVisible = ref(route.query.CreateStoreDialogVisible);
const get_win_width = computed(() => {
const xl = window.innerWidth > 1920 ? 4 : 6;
return xl;
@ -116,7 +115,7 @@ const buttonGroup = ref([
icon: Edit,
handler: (item) => {
CreateStore.CreateStoreTitle = "编辑店铺";
CreateStore.editText = "编辑";
CreateStore.editText = "确定";
CreateStore.CreateStoreDialogVisible = true;
CreateStore.ruleForm = {
id: item.id,
@ -165,7 +164,7 @@ const CreateStore = reactive({
multiple: true,
fileImgList: [],
onSuccessFiles: (files) => {
upload({ file: files.raw }).then((res) => {
upload({ file: files[0] }).then((res) => {
if (res.code === "200") {
CreateStore.ruleForm.lcon = res.data;
ElMessage.success("上传成功");
@ -254,17 +253,11 @@ const get_list_shop = () => {
});
};
onMounted(() => {
CreateStore.CreateStoreDialogVisible = route.query.CreateStoreDialogVisible;
if (route.query.CreateStoreDialogVisible) {
operation("create");
}
get_list_shop();
});
watch(
() => route.query.CreateStoreDialogVisible,
(val) => {
if (val) {
CreateStore.CreateStoreDialogVisible = CreateStoreDialogVisible;
}
}
);
</script>
<style scoped lang='scss'>

View File

@ -1,792 +0,0 @@
<template>
<div class="salecontainer">
<div class="saleordertopbox">
<el-tabs class="demo-tabs" v-model="activeName" @tab-click="onTabChange">
<el-tab-pane v-for="item in tabsdatas" :key="item.value" :label="renderlaebl(item)" :name="item.value"></el-tab-pane>
</el-tabs>
</div>
<SearchForm :inputs="Inputs" @onSearch="onSearch" @onRest="onRest"/>
<Table :data="list" @looksLogs="looksLogs" :select="false" width="auto" :spanMethod="true" @onSelect="onSelect" @delivery="doDelivery" :columns="newcolumns" :loading="loading" :pageSize="pageSize" :page="page" :total="total" :handleSizeChange="handleSizeChange" :handleCurrentChange="handleCurrentChange" @quality="onQuality" @processing="onProcessing" @judgment="onJudgment" @ConfirmReceipt="onConfirmReceipt"/>
<el-dialog v-model="logsState" :before-close="()=>logsState=false" title="售后日志">
<el-table
:data="logsList"
border
height="260px"
style="width: 100%"
v-loading="logsloading"
element-loading-text="加载中"
element-loading-spinner="el-icon-loading"
>
<el-table-column type="index" label="序号" width="60" />
<el-table-column prop="content" label="内容" min-width="180">
<template #default="scope">
<span v-if="scope.row.content">
{{ scope.row.content }}
</span>
<span v-else-if="scope.row.log_content">
{{ scope.row.log_content }}
</span>
<span v-else>
{{ scope.row.content }}
</span>
</template>
</el-table-column>
<el-table-column prop="truename" label="操作人">
<template #default="scope">
<span v-if="scope.row.truename">
{{ scope.row.truename }}({{ scope.row.username }})
</span>
<span v-else>
{{ scope.row.username }}
</span>
</template>
</el-table-column>
<el-table-column prop="add_time" label="操作时间" min-width="180" />
</el-table>
<template #footer>
<span class="dialog-footer">
<el-button size="small" @click="()=>logsState=false"> </el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="draveState" :before-close="()=>draveState=false" title="发货" :width="900">
<DriverForm :DeliveryInfoList="DeliveryInfoList" @deliveryConfirm="DeliveryConfirm" @deliveryCancel="DeliveryCancel"/>
</el-dialog>
<el-dialog v-model="processState" :before-close="()=>processState=false" title="人工处理" :width="600">
<el-radio-group v-model="processValue">
<el-radio :value="1">已核实地址符合情况--售后单状态改为待售后收货</el-radio>
<el-radio :value="2">忽略本次异常--状态改为已处理</el-radio>
</el-radio-group>
<div class="btnbox">
<el-button text class="btn" @click="()=>processState=false"
>取消<i
class="el-icon-circle-close"
style="margin-left: 5px"
/></el-button>
<el-button
text
type="primary"
class="btn"
@click="doProcess(processData)"
>确定</el-button
>
</div>
</el-dialog>
<el-dialog v-model="judgState" :before-close="()=>judgState=false" title="判责情况" :width="600">
<h4>判责</h4>
<el-radio-group v-model="judgValue.mode">
<el-radio value="1">卖家责任</el-radio>
<el-radio value="2">买家责任</el-radio>
</el-radio-group>
<el-row :gutter="24">
<el-col :span="12">
<h4>说明</h4>
<el-input placeholder="请输入说明" type="textarea" v-model="judgValue.info"></el-input>
</el-col>
<el-col :span="10">
<h4>图片</h4>
<el-upload
class="avatar-uploader"
:show-file-list="false"
:before-upload="beforeAvatarUpload"
>
<img v-if="judgValue.imageUrl" :src="judgValue.imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</el-col>
</el-row>
<div class="btnbox">
<el-button text class="btn" @click="()=>judgState=false"
>取消<i
class="el-icon-circle-close"
style="margin-left: 5px"
/></el-button>
<el-button
text
type="primary"
class="btn"
@click="doJudg(judgData)"
>确定</el-button
>
</div>
</el-dialog>
<el-dialog v-model="receState.state" :before-close="()=>receState.state=false" title="手动收货" :width="600">
<h4>快递单号/说明</h4>
<el-input placeholder="请输入快递单号/说明" type="textarea" v-model="receState.value"></el-input>
<div class="btnbox" style="margin-top:15px">
<el-button text class="btn" @click="()=>receState.state=false"
>取消<i
class="el-icon-circle-close"
style="margin-left: 5px"
/></el-button>
<el-button
text
type="primary"
class="btn"
@click="doRecive(receState.data)"
>确定</el-button
>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref,unref,computed,reactive,onMounted} from 'vue';
import Table from "@components/table.vue";
import axioshooks from "@axioshooks";
import {ElMessage} from "element-plus";
import {formatDate,initOss} from "@services/commont";
import DriverForm from "@components/driverForm/index.vue"
import { useRouter } from 'vue-router';
import {Plus} from "@element-plus/icons-vue";
import SearchForm from "@components/searchForm/index.vue";
const router=useRouter();
const activeName=ref('');
const tabs=[
{label:"全部",value:"",total:0},
{label:"待商家处理",value:"9",total:0},
{label:"商家拒绝售后",value:"10",total:0},
{label:"等待寄出",value:"1",total:0},
{label:"待售后收货",value:"2",total:0},
{label:"待质检",value:"3",total:0},
{label:"待判责",value:"4",total:0},
{label:"判责完成",value:"5",total:0},
{label:"已寄出待收货",value:"6",total:0},
{label:"售后异常订单",value:"7",total:0},
{label:"售后异常订单-已处理",value:"8",total:0}
];
const murecedata=reactive({
data:[],
state:false
});
const receState=reactive({
state:false,data:[],value:""
});
const imeipopover=ref(false);
const imeivalue=reactive({
imei:"",
inspect:""
});
const searchparams=reactive({
imei:"",
inspect:""
});
const pageSize=ref(10);
const page=ref(1);
const total=ref(0);
const loading=ref(false);
const logsList=ref(false);
const logsState=ref(false);
const logsloading=ref(false);
const draveState=ref(false);
const refund_status=ref('');
const DeliveryInfoList=ref({});
const processState=ref(false);
const processData=ref({xy_sale_after_additional_id:''});
const processValue=ref(1);
const judgState=ref(false);
const judgData=ref({xy_sale_after_additional_id:''});
const judgValue=ref({mode:"1",info:"",imageUrl:""});
const list=ref([]);
const select=computed(()=>{
if(activeName.value=="2"){
return true;
}else{
return false;
}
});
const onTabChange=(e)=>{
if(activeName.value!=e.props.name){
activeName.value=e.props.name;
if(e.props.name=="9"){
refund_status.value="1";
}else if(e.props.name=="10"){
refund_status.value="6";
}else{
refund_status.value="";
}
getDatas(1);
}
}
const params=ref({});
const onSearch=(values)=>{
let time = {}
if(values.quality_inspection_time){
values.quality_inspection_time_start = values.quality_inspection_time[0],
values.quality_inspection_time_end = values.quality_inspection_time[1]
}
let obj = {
...values,
...time
}
params.value=obj;
getDatas(1);
}
const onRest=()=>{
params.value={};
getDatas(1);
}
const renderlaebl=(item)=>{
if(item.total>0){
return `${item.label} ${item.total}`
}
return item.label
}
const mutrevice=()=>{
if(!murecedata.data){
ElMessage("请选择要收货的订单");
return false;
}
murecedata.state=true;
}
const onSelect=(values)=>{
murecedata.data=values;
}
const Inputs=ref([
{
type:"el-input",
placeholder:"查询IMEI/SN/机器编号",
value:"",
title:"IMEI/SN/机器编号",
name:"imei",
popover:true
},
{
type:"el-input",
placeholder:"查询质检码",
name:"quality_inspection_code",
value:"",
popover:true,
title:"查询质检码",
},
{
type:"el-input",
placeholder:"请输入销售单号",
name:"sales_order_number",
value:"",
title:"销售单号",
},
{
type:"el-input",
placeholder:"请输入商品名称",
name:"title",
value:"",
title:"商品名称",
},
{
type:"el-input",
placeholder:"请输入买家姓名",
name:"consignee_name",
value:"",
title:"买家姓名",
},
{
type:"el-input",
placeholder:"请输入买家手机号",
name:"consignee_phone",
value:"",
title:"买家手机号",
},
{
type:"el-input",
placeholder:"请输入买家地址",
name:"consignee_address",
value:"",
title:"收货人",
},
{
type:"el-input",
placeholder:"请输入快递单号",
name:"refund_post_no",
value:"",
title:"快递单号",
},
{
type:"el-input",
placeholder:"请输入售后订单号",
name:"after_sales_order_number",
value:"",
title:"售后订单号",
} ,
{
type:"el-date-picker",
placeholder:"",
name:"quality_inspection_time",
value:"",
title:"质检时间",
width:"215px"
},
]);
const columns=[
{
dataKey: `machine_name`,
title:"机器信息",
width:300,
show:true,
align: "center",
},
{
dataKey: `title`,
title:"商品标题",
show:true,
width:100,
align: "center",
},
{
dataKey: `merchant_name`,
title:"闲鱼账号",
width:100,
align: "center",
},{
dataKey: `price`,
title:"订单价格",
width:100,
align: "center",
},{
dataKey: `buy_info`,
title:"买家信息",
width:150,
align: "center",
show:true,
},{
dataKey: `buyer_apply_reason`,
title:"售后原因",
show:true,
align: "center",
width:100,
align: "center",
},
// {
// dataKey: `sale_after_quality_inspection_code`,
// title:"",
// width:150,
// show:true,
// align: "center",
// },
{
dataKey: `inspect_report`,
title:"售前质检报告",
width:150,
show:true,
align: "center",
},
{
key: `买家退货物流`,
dataKey: `refund_post_no`,
title:"买家退货物流",
width:150,
show:true,
align: "center",
},
{
dataKey: `receiver`,
title:"收货人/收货时间",
width:140,
show:true,
align: "center",
},
{
dataKey: `inspect_report`,
title:"质检员",
width:150,
show:true,
align: "center",
},
{
dataKey: `quality_inspection_time`,
title:"质检时间",
width:150,
show:true,
align: "center",
},
{
dataKey: `responsibility_type`,
title:"判责情况",
width:150,
show:true,
align: "center",
},
{
dataKey: `return_tracking_number`,
title:"寄回物流信息",
width:150,
show:true,
align: "center",
}, {
dataKey: `sale_after_additional_status`,
title:"售后状态",
width:100,
show:true,
align: "center",
},{
key: `操作`,
dataKey: `opction`,
title:"操作",
width:100,
show:true,
fixed:'right',
align: "center",
status:['Logs','Delivery']
}
];
const newcolumns=computed(()=>{
console.log(activeName.value);
let cludata=Object.assign([],columns);
if(activeName.value=='10'){
cludata.splice(columns.length-2,0,{
dataKey: `seller_refuse_reason`,
title:"卖家拒绝原因",
show:true,
align: "center",
width:150,
align: "center",
});
}
// else if(activeName.value=='8'){
// cludata.splice(columns.length-2,0,{
// dataKey: `address_accord_with`,
// title:"",
// show:true,
// align: "center",
// width:100,
// align: "center",
// });
// }
return cludata;
});
const tabsdatas=computed(()=>{
return Object.assign([],tabs).map((f)=>{
f.total=0;
if(f.value==activeName.value){
f.total= total.value;
}
return f;
});
});
const getDatas=(p)=>{
page.value=p?p:1;
loading.value=true;
total.value=0;
let newtab=activeName.value;
axioshooks({
data:{sale_after_additional_status:Number(activeName.value)<9?activeName.value:"",list_row:pageSize.value,page:page.value,refund_status:refund_status.value,...params.value},
url:"trusteeship/after_sales_list",
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
if(newtab==activeName.value){
list.value=e.datas.datas_list;
total.value=e.datas.total;
}
loading.value=false;
}else{
ElMessage(e.msg);
loading.value=false;
}
}else if(err){
ElMessage(err);
loading.value=false;
}
}
});
}
onMounted(()=>{
getDatas(1);
});
const handleSizeChange=(v)=>{
if(pageSize.value!=v){
pageSize.value=v;
getDatas(1);
}
}
const looksLogs=(data)=>{
logsloading.value=true;
logsState.value=true;
axioshooks({
data:{refund_id:data.after_sales_order_number},
url:"xy/sale_after_log",
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
logsList.value=e.datas;
logsloading.value=false;
}else{
ElMessage(e.msg);
logsloading.value=false;
}
}else if(err){
ElMessage(err);
logsloading.value=false;
}
}
});
}
const doDelivery=(data)=>{
draveState.value=true;
logsloading.value=true;
axioshooks({
data:{xy_sale_after_additional_id:data.xy_sale_after_additional_id},
url:"trusteeship/shipping_info",
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
DeliveryInfoList.value=Object.assign({},data,e.datas);
logsloading.value=false;
}else{
ElMessage(e.msg);
logsloading.value=false;
}
}else if(err){
ElMessage(err);
logsloading.value=false;
}
}
});
}
const handleCurrentChange=(v)=>{
if(page.value!=v){
getDatas(v);
}
}
const DeliveryCancel=()=>{
draveState.value=false;
}
const DeliveryConfirm=()=>{
draveState.value=false;
getDatas(page.value);
}
const onProcessing=(data)=>{
processData.value=data;
processState.value=true;
}
const onJudgment=(data)=>{
judgState.value=data;
judgData.value.xy_sale_after_additional_id = data.xy_sale_after_additional_id;
}
const onQuality=(data)=>{
let imei=data.imei1?data.imei1:data.imei2||data.sn;
router.push({path:'qualityWork',query:{imei:imei}});
}
const doProcess=(data)=>{
if(!processValue.value){
ElMessage('请选择处理结果');
return false;
}
if(!data.xy_sale_after_additional_id){
ElMessage('非法点击');
return false;
}
axioshooks({
url:'trusteeship/exception_handling',
data:{address_accord_with:processValue.value,xy_sale_after_additional_id:data?.xy_sale_after_additional_id},
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
ElMessage("操作成功");
processData.value={};
processValue.value=1;
processState.value=false;
getDatas(page.value);
}else{
ElMessage(e.msg);
}
}else if(err){
ElMessage(err);
}
}
});
}
const doJudg=(data)=>{
if(!judgValue.value.mode){
ElMessage('请选择处理结果');
return false;
}
if(!data.xy_sale_after_additional_id){
ElMessage('非法点击');
return false;
}
axioshooks({
url:'trusteeship/judgment_responsibility',
data:{responsibility_type:judgValue.value.mode,xy_sale_after_additional_id:data?.xy_sale_after_additional_id,responsibility_explanation:judgValue.value.info,responsibility_img:judgValue.value.imageUrl},
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
ElMessage("操作成功");
judgValue.value={mode:"1",info:"",imageUrl:""};
judgState.value=false;
getDatas(page.value);
}else{
ElMessage(e.msg);
}
}else if(err){
ElMessage(err);
}
}
});
}
const beforeAvatarUpload=(rawFile)=>{
let types=["image/jpeg","image/png","image/gif","image/bmp","image/jpg"];
if(!types.includes(rawFile.type)){
ElMessage.error('图片格式有误!')
return false
}
if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('图片超过 2MB 大小!')
return false
}
initOss(rawFile).then((link)=>{
judgValue.value.imageUrl=link;
});
return false;
}
const onConfirmReceipt=(data)=>{
receState.data=data;
receState.state=true;
}
const doRecive=(data)=>{
console.log(receState.value,receState.data,"doRecive");
if(!receState.value){
ElMessage("请输入快递单号或说明");
return false;
}
if(!data.xy_sale_after_additional_id){
ElMessage('非法点击');
return false;
}
let ids = [data.xy_sale_after_additional_id]
axioshooks({
url:'trusteeship/receiving_goods',
data:{xy_sale_after_additional_id:ids||[1],tracking_number:receState.value},
customHandler:(err,e)=>{
if(!err&&e){
if(e.errcode==0){
ElMessage("操作成功");
receState.value="";
receState.data={};
receState.state=false;
getDatas(page.value);
}else{
ElMessage(e.msg);
}
}else if(err){
ElMessage(err);
}
}
});
}
</script>
<style lang="scss" scoped>
.avatar-uploader .avatar {
width:80px;
height:80px;
display: block;
}
.salecontainer{
background:#F1F2F5;
flex:1;
display:flex;
flex-direction:column;
}
.saleordertopbox{
background: #fff;
padding:20px 20px 0;
}
.searchbox{
margin-top:5px;
display:grid;
align-items:center;
grid-gap: 10px;
grid-template-columns:3fr 3fr 1fr 1fr 4fr;
}
.receivingWorkbenchbox {
padding: 10px;
flex:1;
}
.topinput{
height:36px;
}
.imeiicondefault{
height:26px;
width:26px;
box-sizing: border-box;
border-radius: 4px;
background: #f0f2f5;
cursor: pointer;
}
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.toolbox{
display:flex;
align-items:center;
justify-content: space-between;
padding:20px 20px 0;
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px;
height:80px;
text-align: center;
background: #f1f1f1;
}
</style>