This commit is contained in:
feifei_admin 2024-08-21 17:29:51 +08:00
parent 72a6cdb8a5
commit 592e8aaead
16 changed files with 711 additions and 4163 deletions

View File

@ -55,11 +55,19 @@ export function commodity_log(data) {
data data
}) })
} }
// 同步订单 // 批量下架
// export function manual_after_order(data) { export function pull_off_list(data) {
// return request({ return request({
// url: `xy_openapi/afterSale/manual_after_order`, url: `xy_openapi/commodity_info/pull_off_list`,
// method: 'post', method: 'post',
// data data
// }) })
// } }
// 批量删除
export function delete_list(data) {
return request({
url: `xy_openapi/commodity_info/delete_list`,
method: 'delete',
data
})
}

35
src/api/returnAddress.js Normal file
View File

@ -0,0 +1,35 @@
import request from '@axioshooks'
// 获取退货地址列表
export function getAfterSaleAddress(data) {
return request({
url: 'xy_openapi/afterSaleAddress/getAfterSaleAddress',
method: 'post',
data
})
}
// 新增退货地址列表
export function AddressAdd(data) {
return request({
url: 'xy_openapi/afterSaleAddress/add',
method: 'post',
data
})
}
// 删除退货地址列表
export function AddressDelete(data) {
return request({
url: `xy_openapi/afterSaleAddress/delete/${data}`,
method: 'delete',
data
})
}
// 修改退货地址
export function AddressUpdate(data) {
return request({
url: `xy_openapi/afterSaleAddress/update`,
method: 'put',
data
})
}

View File

@ -0,0 +1,99 @@
<template>
<el-dialog
class="ag-dialog"
:title="$slots.title ? '' : title"
v-model="show"
:custom="custom"
v-bind="attrs"
>
<!-- 有写弹窗头部则采用输入的 -->
<template v-if="$slots.title">
<span slot="title">
<slot name="title" />
</span>
</template>
<!-- 弹窗内容区域 -->
<slot />
<!-- 默认底部 -->
<template v-if="!$slots.footer && custom">
<!-- <div #footer class="dialog-footer">
<el-button class="btn" size="small" @click="cancel">取消</el-button>
<el-button class="btn sure" size="small" type="primary" @click="submit"
>确定</el-button
>
</div> -->
</template>
<!-- 弹窗底部区域,可自定义 -->
<template v-if="$slots.footer">
<!-- <template #footer>
<slot name="footer" />
</template> -->
</template>
</el-dialog>
</template>
<script>
//slot=title使shot=title
// export default {
// name: "agDialog",
// props: {
// visible: {
// type: Boolean,
// default: false,
// },
// title: {
// type: String,
// default: "",
// },
// custom: {
// type: Boolean,
// default: true,
// },
// },
// computed: {
// attrs() {
// return {
// width: "30%",
// top: "15vh",
// boolean: "dialog",
// "show-close": false,
// "append-to-body": true,
// "modal-append-to-body": true,
// "destroy-on-close": true,
// ...this.$attrs,
// };
// },
// show: {
// get() {
// return this.visible;
// },
// set(val) {
// this.$emit("update:visible", val); // visible
// },
// },
// },
// data() {
// return {};
// },
// methods: {
// cancel() {
// this.$emit("cancel");
// },
// submit() {
// this.$emit("submit");
// },
// },
// };
</script>
<style scoped lang='scss'>
::v-deep {
.el-dialog__header {
padding: 20px 20px 0;
}
.el-dialog__body {
padding: 10px 20px;
}
}
</style>

View File

@ -40,6 +40,7 @@
</template> </template>
<script setup> <script setup>
import { defineProps } from "vue"; import { defineProps } from "vue";
const props = defineProps({ const props = defineProps({
ButtonList: { ButtonList: {

View File

@ -1,247 +0,0 @@
<template>
<div class="text-msg-pic-upload">
<div class="uploadcontainer">
<div v-for="(item, index) in tempFileList" :key="index" class="prewimg">
<img :src="item.base64" />
<div></div>
</div>
<label for="uploadinput" class="inputlabel"> 上传 </label>
<input
type="file"
id="uploadinput"
class="fileinput"
multiple
accept="image/jpeg,image/png,image/gif,image/jpg"
:onChange="onUpload"
/>
</div>
<!-- <el-upload
ref="upload"
id="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"
accept="jpeg"
:show-file-list="props.limit > 1 || !props.limit"
>
<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, onMounted } 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([]);
const onUpload = (e) => {
const ImgList = [];
for (let i = 0; i < e.target.files.length; i++) {
if (isPngImage(e.target.files[i])) {
let file = isPngImage(e.target.files[i]);
const render = new FileReader();
render.onload = (re) => {
ImgList.push({ file: file, base64: re.target.result });
if (e.target.files.length - 1 == i) {
if (!handleExceed(ImgList, tempFileList.value)) return;
tempFileList.value.push(...ImgList);
$emit("onSuccessFiles", tempFileList.value);
}
};
render.readAsDataURL(file);
}
}
};
const isPngImage = (file) => {
if (!file.type.startsWith("image/")) {
console.error("这不是一个图片文件");
return false;
}
const fileName = file.name || "";
const extension = fileName.split(".").pop().toLowerCase();
if (props.limitType.includes(extension)) return file;
};
watch(
props,
(newval) => {
// if (Array.isArray(props.imgList)) {
// console.log(
// props.imgList,
// "props.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgListprops.imgList"
// );
// tempFileList.value = props.imgList||[];
// }
},
{ deep: true, immediate: true }
);
//
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 !"
// : " JPGPNG !"
// );
// return false;
// }
// if (!isLt20M) {
// ElMessage(" 2MB!");
// return false;
// }
// isPngImage(file.raw);
// $emit("onSuccessFiles", tempFileList.value);
// return false;
};
//
const handleUpload = (op, filelist) => {};
const handleExceed = (files, fileList) => {
console.log(files.length + fileList.length, "files.length + fileList.length");
if (files.length + fileList.length > props.limit) {
ElMessage(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${
files.length
} 个文件共选择了 ${files.length + fileList.length} 个文件`
);
return false;
}
return true;
};
</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;
}
.inputlabel {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
height: 80px;
border: 1px dashed #e5e5e5;
border-radius: 6px;
&:hover {
border: 1px dashed #409eff;
}
}
.uploadcontainer {
display: flex;
align-items: stretch;
gap: 10px;
}
.fileinput {
display: none;
}
.prewimg {
width: 80px;
height: 80px;
border: 1px solid #e5e5e5;
border-radius: 6px;
display: block;
img {
width: 100%;
height: 100%;
display: block;
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,699 +0,0 @@
<template>
<div>
<e-table ref="xTable" :row-config="{ isHover: true }" :data="newtableData" :span-method="colspanMethod"
:height="height" :checkbox-config="{
checkField: 'checked',
checkMethod: checCheckboxkMethod3,
visibleMethod: showCheckboxkMethod2,
}" :header-cell-style="{
height: '70px',
color: '#606266',
'text-align': 'center',
}" :scroll-y="{ enabled: false, gt: 10 }" :loading="loading" border @checkbox-change="selectEvent"
@checkbox-all="selectAllEvent">
<vxe-column type="checkbox" width="50" :border="false"></vxe-column>
<vxe-column v-for="(item, index) in tablelabel" :key="index" :visible="item.show" :title="item.label"
:field="item.param" :fixed="item.fixed" :column-key="item.param" :min-width="item.minwidth"
:filters="item.filters" :sortable="item.sortable" :show-overflow="item.remarkshow" align="center">
<!-- <template
v-if="
item.label == '预计结算价'
"
v-slot:header="{ column, rowIndex }"
>
<span>{{ item.label }}</span>
<el-tooltip
class="item"
effect="dark"
content="点击批量修改"
placement="top-start"
>
<i
class="el-icon-document-copy"
style=" margin-left: 5px; cursor: pointer"
/>
</el-tooltip>
</template> -->
<template slot-scope="{ row }">
<span v-if="row.render" class="firstspan">
<span v-if="row.business_id">
<span v-if="item.link" style="display: flex; align-items: center">
质检码
<el-link :underline="false" type="primary" @dblclick.native="jump(row, '质检码')">{{ row.business_id
}}</el-link>
</span>
<!-- <span v-else-if="item.isdetail" style="display: flex; align-items: center">
质检码
<el-link :underline="false" type="primary" @dblclick.native="jump(row, '审核页')">{{ row.business_id
}}</el-link>
</span> -->
<span v-else> 质检码{{ row.business_id }} </span>
</span>
<span v-if="row.biz_order_id">订单编号{{ row.biz_order_id }}</span>
<span v-if="row.refund_id">售后订单编号{{ row.refund_id }}</span>
<span v-if="
row.publish_time && /^\d{10}$|^\d{13}$/.test(row.publish_time)
">发布时间{{
row.publish_time | dateformat("YYYY-MM-DD HH:mm:ss")
}}</span>
<span v-if="row.last_truename">最近翻库人{{ row.last_truename }}</span>
<span v-if="row.last_publish_time">最近翻库日期{{
row.last_publish_time | dateformat("YYYY-MM-DD HH:mm:ss")
}}</span>
<span v-if="row.buyer_nick">买家昵称{{ row.buyer_nick }}</span>
</span>
<span v-else-if="!row.render">
<div v-if="item.label === '机器信息'" class="machineinfo">
<p>
{{ row.brand_name }} {{ row.model_name }} {{ row.rom_name }}
{{ row.color_name }}
</p>
<div class="info">
<div class="info-left">
<el-popover v-if="row['img']" placement="right" width="375" trigger="click">
<img v-if="row['img']" style="height: 350px" :src="row['img']" />
<img v-if="row['img']" slot="reference" style="float: left; height: 70px" :src="row['img']" />
</el-popover>
<img v-else style="float: left; height: 70px" src="./../assets/noimg.jpg" />
</div>
<ul class="info-right">
<li>
<span v-if="item.link" style="display: flex; align-items: center">
机器编号
<el-link :underline="false" type="primary" @dblclick.native="jump(row, '机器编号')">{{
row.serial_number }}</el-link>
</span>
<span v-else> 机器编号{{ row.serial_number }} </span>
</li>
<li>IMEI{{ row.imei1 }}</li>
<li>IMEI2{{ row.imei2 }}</li>
<li>SN:{{ row.sn }}</li>
</ul>
</div>
</div>
<span v-else-if="item.label === '机器成色'">
{{
Number(row.stuff_status) > 0
? row.stuff_status + "新"
: row.stuff_status
}}
</span>
<span v-else-if="
item.label === '机器状态' ||
item.label === '订单状态' ||
item.label === '商品状态' ||
item.label === '售后状态'
">
<el-tag>{{ row[item.param] || "/" }}</el-tag>
</span>
<span v-else-if="item.label === '订单价格\n(利润)'">
<span style="display: block">{{ row.payment / 100 }}</span>
<span :class="row.payment / 100 - row.total_cost > 0 ? 'red' : 'green'
">{{
(row.payment / 100 - Number(row.total_cost)).toFixed(2)
}}</span>
</span>
<span v-else-if="item.label == '质检报告'" class="look">
<el-link :underline="false" type="primary" @click="lookquily(row, '0')">质检报告</el-link>
<el-link v-if="item.detailshow" :underline="false" type="primary"
@click="lookquily(row, '1')">商品详情</el-link>
</span>
<span v-else-if="item.label == '预计结算价'">
<span :style="6 ? 'color:#ff6b81' : 'color:#2ed573'">{{
Number((row.price * 0.99) / 100).toFixed(2)
}}</span>
</span>
<span v-else-if="item.label == '预估利润'">
<span :style="6 ? 'color:#2ed573' : 'color:#ff6b81'">{{
Number(
(row.price * 0.99) / 100 - row.total_cost - row.ag_server_fee
).toFixed(2)
}}</span>
</span>
<span v-else-if="
item.label == '退款金额' ||
item.label == '申请退款金额' ||
item.label == '定价' ||
item.label == '保底价'
">
<span>{{ Number(row[item.param] / 100).toFixed(2) }}</span>
</span>
<span
v-else-if="
row[item.param] &&
((/^\d{10}$|^\d{13}$/.test(row[item.param]) &&
item.label == '交易成功时间') ||
item.label == '关闭时间' ||
item.label == '退款时间' ||
item.label == '订单创建时间' ||
item.label == '付款时间' ||
item.label == '发货时间' ||
item.label == '首次发布时间' ||
item.label == '申请退款时间')
"
>{{ row[item.param] | dateformat("YYYY-MM-DD HH:mm:ss") }}</span
>
<div v-else-if="item.label === '快递单号'">
<div>{{ row.refund_post_company }}</div>
<div>{{ row[item.param] }}</div>
</div>
<!-- 操作 -->
<span v-else-if="item.label === '操作'" class="operate">
<el-link v-if="
item.status.includes('AgreeReturn') &&
row.refund_status === 1 &&
row.need_return_goods === 'true'
" :underline="false" type="primary" @click="operate('AgreeReturn', row)">同意退货</el-link>
<el-link v-if="
item.status.includes('AgreeRefund') &&
row.refund_status === 1 &&
row.need_return_goods === 'false'
" :underline="false" type="success" @click="operate('AgreeRefund', row)">同意退款</el-link>
<el-link v-if="
(item.status.includes('ConfirmReceipt') &&
row.refund_status === 3) ||
(row.refund_status === 2 && row.need_return_goods === 'true')
" :underline="false" type="primary" @click="operate('ConfirmReceipt', row)">确认收货</el-link>
<el-link v-if="
(item.status.includes('RefusalReceipt') &&
row.refund_status === 3) ||
(row.refund_status === 2 && row.need_return_goods === 'true')
" :underline="false" type="danger" @click="operate('RefusalReceipt', row)">拒绝收货</el-link>
<el-popconfirm title="是否拒绝退款?" v-if="
(item.status.includes('RefundRefused') &&
row.refund_status === 1) ||
row.refund_status === 3
" @confirm="operate('RefundRefused', row)">
<el-link slot="reference" type="danger" :underline="false">拒绝退款</el-link>
</el-popconfirm>
<el-popconfirm title="请确认?" v-if="item.status.includes('Agree')" @confirm="operate('Agree', row)">
<el-link slot="reference" type="primary" :underline="false">同意</el-link>
</el-popconfirm>
<el-link
type="danger"
v-if="item.status.includes('Reject')"
@click="operate('Reject', row)"
:underline="false"
>驳回</el-link
>
<el-popconfirm
title="是否重新发布?"
v-if="item.status.includes('Republish')"
@confirm="operate('Republish', row)"
>
<el-link slot="reference" type="primary" :underline="false"
>重新发布</el-link
>
</el-popconfirm>
<el-popconfirm title="是否删除?" v-if="item.status.includes('Deletegoods')"
@confirm="operate('Deletegoods', row)">
<el-link slot="reference" type="danger" :underline="false">删除</el-link>
</el-popconfirm>
<el-link type="danger" :underline="false" v-if="item.status.includes('OffShelf')"
@click="operate('OffShelf', row)">下架</el-link>
<el-link v-if="item.status.includes('ChangePrice')" :underline="false" type="primary"
@click="operate('ChangePrice', row)">改价</el-link>
<el-link v-if="item.status.includes('AddOrder')" :underline="false" type="primary"
@click="operate('AddOrder', row)">补订单</el-link>
<el-link v-if="item.status.includes('CloseTrade')" :underline="false" type="success"
@click="operate('CloseTrade', row)">关闭交易</el-link>
<el-link v-if="
item.status.includes('Delivery') &&
(!row.refund_status ||
![1, 2, 3, 5, 8].includes(row.refund_status))
" :underline="false" type="primary" @click="operate('Delivery', row)">立即发货</el-link>
<el-link v-if="item.status.includes('LogisticsInfo')" :underline="false" type="primary"
@click="operate('LogisticsInfo', row)">物流信息</el-link>
<el-link v-if="item.status.includes('Intercept')" :underline="false" type="primary"
@click="operate('Intercept', row)">快递拦截</el-link>
<el-link v-if="item.status.includes('Print')" :underline="false" type="primary"
@click="operate('Print', row)">打印面单</el-link>
<el-link type="warning" :underline="false" v-if="item.status.includes('Logs')"
@click="operate('Logs', row)">日志</el-link>
<el-link type="success" :underline="false" v-if="item.status.includes('GoAudit')"
@click="operate('GoAudit', row)">审核</el-link>
</span>
<span v-else-if="item.label == '备注' && item.fixed == 'right'">
<vxe-button type="text" icon="vxe-icon-edit" @click="editEvent(row)" />
<span>{{ row.remark }}</span>
</span>
<span v-else>
{{ row[item.param] ? row[item.param] : "-" }}
</span>
</span>
</template>
</vxe-column>
</e-table>
<erp-xylog :xylogdialog-visible="xylogdialogVisible" :xylogid="xylogid" :xylogtype="xylogtype"
@xylogdialog="xylogdialog" />
</div>
</template>
<script sutep>
import Sortable from "sortablejs";
import erpXylog from "./Dialog/xyqualitydialog.vue";
import { ref,unref,markRaw} from 'vue';
const props=defineProps(['tableDate','tablelabel','excelName','loading','tabbar']);
const {tableDate,tablelabel,excelName,loading,tabbar}=props;
const xylogid=ref("");
const xylogtype=ref("");
const xylogdialogVisible=(false);
</script>
<script>
import Sortable from "sortablejs";
import erpXylog from "./Dialog/xyqualitydialog";
export default {
name:"erpXyTable",
components: {
erpXylog,
},
data() {
return {
xylogid: "",
xylogtype: "",
xylogdialogVisible: false,
};
},
props: {
tableDate: {
default: () => {
return [];
},
},
tablelabel: {
default: () => {
return [];
},
},
excelName: {
default: () => {
return "";
},
},
loading: {
default: () => {
return false;
},
},
tabbar: {
default: () => {
return false;
},
},
},
computed: {
newtableData() {
if (this.tableDate.length == 0) return;
let result = [];
const arr = this._.cloneDeep(this.tableDate);
result = arr.map((item) => [{ ...item }, { ...item }]).flat();
result.map((e, i) => {
if (i % 2 === 0) {
this.$set(e, "render", true);
this.$set(e, "checked", false);
} else {
this.$set(e, "render", false);
}
});
return result;
},
height() {
let height = "";
if (this.tabbar) {
height = document.documentElement.clientHeight - 235;
} else {
height = document.documentElement.clientHeight - 280;
}
return height;
},
tablelabelLen() {
let num = 0;
this.tablelabel.forEach((item) => {
if (item.show) {
num++;
}
});
return num;
},
},
mounted() { },
methods: {
colspanMethod({ _rowIndex, _columnIndex }) {
if (_rowIndex % 2 === 0) {
if (_columnIndex === 0) {
return { rowspan: 1, colspan: 1 };
} else if (_columnIndex === 1) {
return { rowspan: 1, colspan: this.tablelabelLen };
} else {
return { rowspan: 0, colspan: 0 };
}
}
},
checCheckboxkMethod3({ row }) {
return row.render == true;
},
showCheckboxkMethod2({ row }) {
return row.render == true;
},
//
tongyi(row) {
this.$emit("tongyi", row);
},
//
bohui(row) {
this.$emit("bohui", row);
},
//
jump(row, name) {
switch (name) {
case "机器编号":
this.$router.push({
name: "MachineDetails",
query: { row: row.res_id },
});
break;
case "质检码":
this.$router.push({
path: "idleFishIssue",
query: { xy_product_id: row.xy_product_id },
});
break;
default:
break;
}
},
//
operate(val, data) {
switch (val) {
case "Agree":
this.$emit("Agree", data);
break;
case "Reject":
this.$emit("Reject", data);
break;
case "OffShelf":
this.$emit("OffShelf", data);
break;
case "Logs":
this.$emit("looksLogs", data);
break;
case "ChangePrice":
this.$emit("ChangePrice", data);
break;
case "Republish":
this.$emit("Republish", data);
break;
case "Deletegoods":
this.$emit("Deletegoods", data);
break;
case "AddOrder":
this.$emit("AddOrder", data);
break;
case "CloseTrade":
this.$emit("CloseTrade", data);
break;
case "Delivery":
this.$emit("Delivery", data);
break;
case "LogisticsInfo":
this.$emit("LogisticsInfo", data);
break;
case "Intercept":
this.$emit("Intercept", data);
break;
case "AgreeReturn":
this.$emit("AgreeReturn", data);
break;
case "RefundRefused":
this.$emit("RefundRefused", data);
break;
case "AgreeRefund":
this.$emit("AgreeRefund", data);
break;
case "ConfirmReceipt":
this.$emit("ConfirmReceipt", data);
break;
case "RefusalReceipt":
this.$emit("RefusalReceipt", data);
break;
case "Print":
let params = {
tracking_number: data.express_no,
express_company_id: data.express_company_id,
};
this.$emit("Print", params);
break;
case "GoAudit":
this.$emit("GoAudit", data);
break;
default:
break;
}
},
//
lookquily(row, type) {
this.xylogdialogVisible = true;
if (type == "0") {
this.xylogtype = "0";
this.xylogid = row.id;
} else {
this.xylogtype = "1";
this.xylogid = row.item_id;
}
},
//
editEvent(row) {
const dataToEdit = row.remark;
let inputValue = dataToEdit; // 使
this.$confirm("", "修改备注", {
cancelButtonText: "重置",
confirmButtonText: "提交",
customClass: "custom-prompt",
inputPlaceholder: "请输入备注",
inputType: "textarea",
inputRows: 5,
inputValue: inputValue,
showInput: true,
distinguishCancelAndClose: true,
beforeClose: (action, instance, done) => {
//
if (action === "confirm" || action === "close") {
done();
} else if ((instance.inputValue = "cancel")) {
instance.inputValue = "";
}
},
})
.then(({ value }) => {
this.$emit("submitRemark", row, value);
})
.catch(() => {
//
});
},
// dilog
xylogdialog(e) {
this.xylogdialogVisible = e;
},
// sortable
InitializeSortable() {
const sortableId = document.querySelector(
".vxe-table--header-wrapper tr"
);
this.sortable = Sortable.create(sortableId, {
//
onChoose: function (/**Event*/ evt) {
evt.oldIndex; // element index widthin parent
},
//
onStart: function (/**Event*/ evt) {
evt.oldIndex; // element index widthin parent
},
//
onEnd: function (/**Event*/ evt) {
var itemEl = evt.item; // dragged HTMLElement
evt.to; // target list
evt.from; // previous list
evt.oldIndex; // element's old index widthin old parent
evt.newIndex; // element's new index widthin new parent
evt.clone; // the clone element
evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
},
//
onAdd: function (/**Event*/ evt) {
// same properties as onEnd
},
//
onUpdate: function (/**Event*/ evt) {
// same properties as onEnd
},
//
onSort: function (/**Event*/ evt) {
// same properties as onEnd
},
//
onRemove: function (/**Event*/ evt) {
// same properties as onEnd
},
// filtered
onFilter: function (/**Event*/ evt) {
var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event.
},
//
onMove: function (/**Event*/ evt, /**Event*/ originalEvent) {
// Example: https://jsbin.com/nawahef/edit?js,output
evt.dragged; // dragged HTMLElement
evt.draggedRect; // DOMRect {left, top, right, bottom}
evt.related; // HTMLElement on which have guided
evt.relatedRect; // DOMRect
evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
originalEvent.clientY; // mouse position
// return false; for cancel
// return -1; insert before target
// return 1; insert after target
},
// clone
onClone: function (/**Event*/ evt) {
var origEl = evt.item;
var cloneEl = evt.clone;
},
//
onChange: function (/**Event*/ evt) {
evt.newIndex; // most likely why this event is used is to get the dragging element's current index
// same properties as onEnd
},
});
},
//
columnDrop() {
const wrapperTr = document.querySelector(".vxe-table--header-wrapper tr");
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: (evt) => {
console.log(evt, "evt-----------");
const oldItem = this.tablelabel[evt.oldIndex];
this.tablelabel.splice(evt.oldIndex, 1);
this.tablelabel.splice(evt.newIndex, 0, oldItem);
this.InitializeSortable();
},
});
},
scrollHeight() {
setTimeout(() => {
this.$refs.xTable.scrollTo(0, 0);
}, 500);
},
//
selectAllEvent(val) {
this.$emit("selectAllEvent", val.records);
},
//
selectEvent(val) {
this.$emit("selectEvent", val.records);
},
},
};
</script>
<style lang="scss" scoped>
// .remark {
// display: flex;
// align-items: center;
// justify-content: center;
// }
// .item {
// width: 50%;
// display: inline-block;
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
// }
.firstspan {
display: flex;
span {
margin-right: 20px;
}
}
.machineinfo {
text-align: left !important;
font-weight: 500;
p {
margin-bottom: 0px;
}
.info {
display: flex;
align-items: center;
margin-top: 5px;
.info-right {
display: flex;
flex-direction: column;
justify-content: center;
margin: 0 0 0 15px;
}
}
}
.look {
display: flex;
flex-direction: column;
}
.operate {
display: flex;
flex-direction: column;
align-items: center;
span {
line-height: 20px;
}
}
::v-deep {
.vxe-table--body .vxe-cell--checkbox:nth-child(odd) :after {
content: "";
position: absolute;
top: 0px;
right: -5px;
display: inline-block;
width: 20px;
height: calc(100% - 1px);
background-color: #ffffff;
}
.vxe-body--row.row--hover {
.vxe-cell--checkbox:nth-child(odd) :after {
background-color: #f5f7fa;
}
}
/*调整表格 单元格背景颜色*/
.vxe-table .vxe-table--body-wrapper,
.vxe-table .vxe-table--footer-wrapper {
border: none;
background-color: rgba(255, 255, 255);
}
.vxe-cell--checkbox:nth-child(odd) {
display: flex;
align-items: center;
justify-content: center;
}
.vxe-body--row:nth-child(even) {
background-color: rgb(248 248 249);
}
}
</style>

View File

@ -8,6 +8,7 @@ import AfterSalesManagement from './views/AfterSalesManagement/index.vue';
import NewlyBuiltGoods from './views/NewlyBuiltGoods/index.vue'; import NewlyBuiltGoods from './views/NewlyBuiltGoods/index.vue';
import XyShop from "./views/XyShop/index.vue"; import XyShop from "./views/XyShop/index.vue";
import translateSet from "./views/translateSet/index.vue"; import translateSet from "./views/translateSet/index.vue";
import returnAddress from "./views/returnAddress/index.vue";
import { import {
@ -90,8 +91,14 @@ export const routes = [
path: '/translateSet', path: '/translateSet',
component: translateSet, component: translateSet,
}, },
{
meta: {
label: "退货物流配置 ",
icon: markRaw(Location)
},
path: '/returnAddress',
component: returnAddress,
},
] ]
}, },
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },

View File

@ -355,8 +355,6 @@ const buttonList = ref([
show: true, show: true,
Loading: false, Loading: false,
handler: (item) => { handler: (item) => {
console.log(item, "item");
if (!selectdateList.value.length) if (!selectdateList.value.length)
return ElMessage.warning("至少选择一条数据!"); return ElMessage.warning("至少选择一条数据!");
item.Loading = true; item.Loading = true;

View File

@ -11,7 +11,7 @@
</el-tabs> </el-tabs>
<SearchForm :inputs="Inputs" @onSearch="onSearch" @onRest="onRest" /> <SearchForm :inputs="Inputs" @onSearch="onSearch" @onRest="onRest" />
</div> </div>
<buttonGroup :buttonList="buttonList"></buttonGroup>
<div class="table_box_center"> <div class="table_box_center">
<Table <Table
ref="TableRef" ref="TableRef"
@ -19,6 +19,8 @@
:TabLoading="TabLoading" :TabLoading="TabLoading"
:TableData="TableData" :TableData="TableData"
:TableLabel="TableLabel" :TableLabel="TableLabel"
@selectEvent="selectEvent"
@selectAllEvent="selectAllEvent"
> >
<template #OperateButton="{ row }"> <template #OperateButton="{ row }">
<OperateButton <OperateButton
@ -50,6 +52,7 @@ import { router } from "@/router.js";
import { Plus } from "@element-plus/icons-vue"; import { Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import SearchForm from "@components/searchForm/index.vue"; import SearchForm from "@components/searchForm/index.vue";
import buttonGroup from "@/components/buttongroup.vue";
import Table from "@components/table.vue"; import Table from "@components/table.vue";
import OperateButton from "@/components/OperateButton.vue"; import OperateButton from "@/components/OperateButton.vue";
import PaginaTion from "@components/Pagination.vue"; import PaginaTion from "@components/Pagination.vue";
@ -63,6 +66,8 @@ import {
delete_one, delete_one,
get_commodity, get_commodity,
commodity_log, commodity_log,
pull_off_list,
delete_list,
} from "@/api/CommodityManagement"; } from "@/api/CommodityManagement";
import { getshopInfo } from "@/api/newlybuiltgoods"; import { getshopInfo } from "@/api/newlybuiltgoods";
const activeName = ref(""); const activeName = ref("");
@ -139,7 +144,7 @@ const Inputs = ref([
width: "215px", width: "215px",
}, },
]); ]);
const selectdateList = ref([]);
const TableRef = ref(null); const TableRef = ref(null);
const TableKey = ref(new Date().getTime()); const TableKey = ref(new Date().getTime());
const TabLoading = ref(false); const TabLoading = ref(false);
@ -344,6 +349,47 @@ const ButtonListGroup = ref([
}, },
}, },
]); ]);
const buttonList = ref([
{
name: "批量下架",
show: true,
Loading: false,
handler: (item) => {
if (!selectdateList.value.length)
return ElMessage.warning("至少选择一条数据!");
item.Loading = true;
const Ids = [];
selectdateList.value.map((e) => Ids.push(e.id));
pull_off_list({ idList: Ids }).then((res) => {
item.Loading = false;
if (res.code === "200") {
TableRef.value.clearCheckboxRow();
getDatas();
}
});
},
},
{
name: "批量删除",
show: true,
Loading: false,
handler: (item) => {
if (!selectdateList.value.length)
return ElMessage.warning("至少选择一条数据!");
item.Loading = true;
const Ids = [];
selectdateList.value.map((e) => Ids.push(e.id));
delete_list({ integers: Ids }).then((res) => {
item.Loading = false;
if (res.code === "200") {
TableRef.value.clearCheckboxRow();
getDatas();
}
});
},
},
]);
let commodityInfoDto = reactive({ let commodityInfoDto = reactive({
pageNo: 1, pageNo: 1,
pageSize: 20, pageSize: 20,
@ -439,6 +485,12 @@ const TabChange = (val) => {
New_TableLabel.value = TableLabel.value; New_TableLabel.value = TableLabel.value;
TableKey.value = new Date().getTime(); TableKey.value = new Date().getTime();
}; };
const selectEvent = (data) => {
selectdateList.value = data;
};
const selectAllEvent = (data) => {
selectdateList.value = data;
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -453,7 +505,7 @@ const TabChange = (val) => {
background: #fff; background: #fff;
} }
.table_box_center { .table_box_center {
padding: 20px; padding: 0 20px;
box-sizing: border-box; box-sizing: border-box;
} }
</style> </style>

View File

@ -401,7 +401,6 @@ const buttonList = ref([
show: true, show: true,
Loading: false, Loading: false,
handler: (item) => { handler: (item) => {
console.log(item, "item");
if (!selectdateList.value.length) if (!selectdateList.value.length)
return ElMessage.warning("至少选择一条数据!"); return ElMessage.warning("至少选择一条数据!");
item.Loading = true; item.Loading = true;

View File

@ -0,0 +1,127 @@
<template>
<div>
<el-dialog
:title="props.AddTitle"
v-model="props.AddDialogVisible"
width="20%"
:close-on-click-modal="false"
:before-close="AddClose"
>
<el-form
ref="ruleFormRef"
:model="props.ruleForm"
status-icon
:rules="props.rules"
label-width="125px"
class="demo-ruleForm"
>
<el-form-item
v-for="(item, index) in props.ruleFormList"
:key="index"
:label="item.label"
:prop="item.prop"
v-show="item.show == '1'"
>
<el-input
v-if="item.type === 'input'"
v-model="props.ruleForm[item.params]"
:clearable="item.clearable"
:disabled="item.disabled"
:placeholder="item.placeholder"
></el-input>
<el-select
v-if="item.type === 'select'"
v-model="props.ruleForm[item.params]"
:autocomplete="item.autocomplete"
:clearable="item.clearable"
:placeholder="item.placeholder"
@change="item.inputChange($event, item.ref)"
><el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option
></el-select>
<el-cascader
v-if="item.type === 'cascader'"
:ref="item.ref"
style="width: 100%"
v-model="props.ruleForm[item.params]"
:options="item.options"
:filterable="true"
:placeholder="item.placeholder"
@change="item.change($event, item)"
/>
<el-radio-group
v-if="item.type === 'radio'"
v-model="props.ruleForm[item.params]"
@change="item.radioChange"
>
<el-radio
v-for="el in item.options"
:key="el.value"
:value="el.value"
>{{ el.label }}</el-radio
>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="AddClose">取消</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">{{
editText
}}</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import UploadImage from "@components/Upload/newfileupload.vue";
import { ref, defineEmits, defineProps } from "vue";
const ruleFormRef = ref(null);
const $emit = defineEmits(["submitForm", "AddClose"]);
const props = defineProps({
AddDialogVisible: {
type: Boolean,
default: false,
},
AddTitle: {
type: String,
default: "",
},
editText: {
type: String,
default: "前往授权",
},
ruleForm: {
type: Object,
default: () => ({}),
},
ruleFormList: {
type: Array,
default: () => [],
},
rules: {
type: Object,
default: () => ({}),
},
});
const submitForm = (form) => {
form.validate((valid) => {
if (!valid) return;
$emit("submitForm");
});
};
const AddClose = () => {
$emit("AddClose");
ruleFormRef.value.resetFields();
};
</script>
<style scoped lang='scss'>
</style>

View File

@ -0,0 +1,366 @@
<template>
<div class="xy_shop">
<div class="head">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item
:label="item.label"
v-for="(item, index) in formSelect"
:key="index"
>
<el-input
style="width: 190px"
v-if="item.type == 'input'"
v-model="xyUserAddressDto[item.params]"
:placeholder="`请输入${item.label}`"
clearable
/>
<el-button
v-if="item.type == 'button'"
:type="item.status"
@click="item.handler(item)"
>{{ item.name }}</el-button
>
</el-form-item>
</el-form>
</div>
<div class="main">
<div class="table">
<vxe-table
border
ref="xTable"
height="auto"
:data="tableData"
align="center"
>
<vxe-column
v-for="(item, index) in tableColumn"
:key="index"
:type="item.type"
:field="item.field"
:title="item.title"
:fixed="item.fixed"
:min-width="item.width"
:filters="item.filters"
>
</vxe-column>
<vxe-column
field="ship_by_default"
title="是否打单发货默认物流"
width="210"
>
<template #default="{ row }">
<span>{{ row.receivFlag ? "是" : "否" }}</span>
</template>
</vxe-column>
<vxe-column title="操作" width="160">
<template #default="{ row }">
<el-button
type="text"
@click="edit(row)"
style="margin-right: 10px"
>编辑</el-button
>
<el-popconfirm title="您确定删除吗?" @confirm="delConfirm(row)">
<template #reference>
<el-button type="text" style="color: #f56c6c">删除</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
</div>
</div>
</div>
<AddDialog
:AddDialogVisible="AddDialogVisible"
:AddTitle="AddTitle"
:editText="editText"
:ruleForm="ruleForm"
:ruleFormList="ruleFormList"
:rules="rules"
@AddClose="AddClose"
@submitForm="submitForm"
></AddDialog>
</template>
<script setup>
import { router } from "@/router.js";
import { useRoute } from "vue-router";
import { ref, reactive, onMounted, computed } from "vue";
import { Delete, Edit, Search, Share, Upload } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import buttonGroup from "@/components/buttongroup.vue";
import AddDialog from "./components/addDialog.vue";
import {
getAfterSaleAddress,
AddressAdd,
AddressDelete,
AddressUpdate
} from "@/api/returnAddress";
import { region } from "@/api/newlybuiltgoods";
const formSelect = ref([
{
type: "input",
label: "姓名",
params: "name",
},
{
type: "input",
label: "电话",
params: "phone",
},
{
type: "button",
status: "primary",
name: "查询",
handler: (item) => {
get_afterSaleAddress();
},
},
{
type: "button",
status: "",
name: "重置",
handler: (item) => {
xyUserAddressDto.value = { phone: "", name: "" };
get_afterSaleAddress();
},
},
{
type: "button",
status: "",
name: "新增",
handler: (item) => {
AddTitle.value = "新增退货地址";
editText.value = "确定";
AddDialogVisible.value = true;
},
},
]);
let xyUserAddressDto = ref({
phone: "",
name: "",
});
const tableData = ref({});
const tableColumn = ref([
{ field: "name", title: "收货人姓名", width: 120 },
{ field: "phone", title: "收货人电话", width: 120 },
{ field: "province", title: "省", width: 120 },
{ field: "city", title: "市", width: 120 },
{ field: "district", title: "区", width: 120 },
{ field: "detailed", title: "详细地址", width: 120 },
]);
const AddDialogVisible = ref(false);
const AddTitle = ref("");
const editText = ref("确定");
const ruleForm = ref({
name: "", //
phone: "", //
province: "", //
city: "", //
district: "", //
detailed: "", //
receivFlag: "", //
province_id: "", //ID
city_id: "", //ID
district_id: "", //ID
area: [],
});
const ruleFormList = ref([
{
type: "input",
label: "收货人姓名",
params: "name",
prop: "name",
clearable: true,
show: true,
placeholder: "请输入姓名",
},
{
type: "input",
label: "收货人电话",
params: "phone",
prop: "phone",
clearable: true,
show: true,
placeholder: "请输入电话",
inputChange: (e, item) => {},
},
{
ref: "areaRef",
type: "cascader",
label: "省市区",
params: "area",
prop: "area",
clearable: true,
show: true,
placeholder: "选择省市区",
options: [],
change: (value, areaRef) => {
const selectedData = areaRef.options;
const areaList = findLabelsByPath(selectedData, value);
ruleForm.value = {
province: areaList[0],
city: areaList[1],
district: areaList[2],
province_id: value[0],
city_id: value[1],
district_id: value[2],
};
},
},
{
type: "input",
label: "详细地址",
params: "detailed",
prop: "detailed",
clearable: true,
show: true,
placeholder: "请输入详细地址",
},
{
type: "radio",
label: "是否默认寄回地址",
params: "receivFlag",
prop: "receivFlag",
show: true,
clearable: true,
options: [
{
label: "是",
value: "1",
},
{
label: "否",
value: "0",
},
],
},
]);
const rules = ref({});
const submitForm = () => {
if (editText.value == "确定") {
AddressAdd(ruleForm.value).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
get_afterSaleAddress();
AddClose();
}
});
} else {
AddressUpdate(ruleForm.value).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
get_afterSaleAddress();
AddClose();
}
});
}
};
const edit = (row) => {
AddTitle.value = "编辑快递公司";
editText.value = "编辑";
ruleForm.value = {
...row,
area: [row.provinceId, row.cityId, row.districtId],
receivFlag: row.receivFlag + "",
};
AddDialogVisible.value = true;
};
//
const delConfirm = (row) => {
AddressDelete(row.id).then((res) => {
if (res.code === "200") {
ElMessage.success(res.msg);
get_afterSaleAddress();
}
});
};
const AddClose = () => {
AddDialogVisible.value = false;
};
//
const get_region = () => {
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;
});
};
ruleFormList.value.find((e) => e.label === "省市区").options =
transformData(res.data);
}
});
};
//value['','','']
const findLabelsByPath = (options, path) => {
if (path.length === 0) {
return [];
}
const currentOption = options.find((option) => option.value === path[0]);
if (!currentOption) {
return [];
}
const currentLabel = [currentOption.label]; // label
const remainingPathLabels =
path.length > 1
? findLabelsByPath(currentOption.children, path.slice(1))
: [];
return [...currentLabel, ...remainingPathLabels];
};
//退
const get_afterSaleAddress = () => {
getAfterSaleAddress(xyUserAddressDto.value).then((res) => {
if (res.code === "200") {
tableData.value = res.data;
}
});
};
onMounted(() => {
get_afterSaleAddress();
get_region();
});
</script>
<style scoped lang='scss'>
.xy_shop {
background: #f1f2f5;
.head {
height: 80px;
padding: 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
}
:deep(.el-form-item) {
margin-bottom: 0;
margin-right: 10px;
}
.main {
height: calc(100vh - 115px);
padding:20px;
box-sizing: border-box;
.table {
height: 100%;
background-color: #fff;
padding: 20px;
box-sizing: border-box;
}
}
}
</style>

View File

@ -392,7 +392,7 @@ const ruleFormList = ref([
}, },
]); ]);
const rules = ref({}); const rules = ref({});
let xyUserAddressDto = reactive({ let xyUserAddressDto = ref({
logisticsCode: "", logisticsCode: "",
logisticsName: "", logisticsName: "",
}); });
@ -456,7 +456,7 @@ const formSelect = ref([
status: "", status: "",
name: "重置", name: "重置",
handler: (item) => { handler: (item) => {
xyUserAddressDto = { logisticsCode: "", logisticsName: "" }; xyUserAddressDto.value = { logisticsCode: "", logisticsName: "" };
get_userAddress(); get_userAddress();
}, },
}, },
@ -510,7 +510,6 @@ const edit = (row) => {
monthFlag: row.monthFlag ? String(row.monthFlag) : "0", monthFlag: row.monthFlag ? String(row.monthFlag) : "0",
defaultFlag: row.defaultFlag ? String(row.defaultFlag) : "0", defaultFlag: row.defaultFlag ? String(row.defaultFlag) : "0",
}; };
AddDialogVisible.value = true;
AddTitle.value = "编辑快递公司"; AddTitle.value = "编辑快递公司";
editText.value = "编辑"; editText.value = "编辑";
AddDialogVisible.value = true; AddDialogVisible.value = true;
@ -528,7 +527,7 @@ const AddClose = () => {
AddDialogVisible.value = false; AddDialogVisible.value = false;
}; };
const get_userAddress = () => { const get_userAddress = () => {
userAddress(xyUserAddressDto).then((res) => { userAddress(xyUserAddressDto.value).then((res) => {
if (res.code === "200") { if (res.code === "200") {
tableData.value = res.data; tableData.value = res.data;
} }