<template>
<div class="app-container shop-order-index"
style="position: relative; height: calc(100vh - 110px);">
<!-- style="height: calc(100% - 8px);" -->
<div class="container" >
<!--工具栏-->
<div class="head-container work-order-head">
<!-- 搜索 -->
<el-form
:inline="true"
:model="query"
class="demo-form-inline"
:show-message="false"
label-width="90px"
>
<el-form-item label="客服工单号">
<el-input
v-model="query.workOrderNum"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请输入客服工单号"
@keyup.enter.native="toQuery"
/>
</el-form-item>
<el-form-item label="订单号">
<el-input
v-model="query.orderId"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请输入订单号"
@keyup.enter.native="toQuery"
/>
</el-form-item>
<el-form-item label="工单来源">
<el-select
v-model="query.fromType"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择工单来源"
>
<el-option
v-for="(item, ind) in queryTypeOptions"
:key="'laiyuan' + ind"
:label="item.display_name"
:value="item.key"
/>
</el-select>
</el-form-item>
<el-form-item label="订单来源">
<el-select
v-model="query.orderSource"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择订单来源"
>
<el-option label="福利商城" value="1"></el-option>
<el-option label="陆海商城" value="0"></el-option>
<el-option label="鲁西福礼" value="3"></el-option>
<el-option label="浪潮商城" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="提报人姓名">
<el-input
v-model="query.linkUserName"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请输入提报人姓名"
@keyup.enter.native="toQuery"
/>
</el-form-item>
<el-form-item label="提报人电话">
<el-input
v-model="query.linkUserPhone"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请输入提报人电话"
@keyup.enter.native="toQuery"
/>
</el-form-item>
<el-form-item label="工单添加人">
<el-input
v-model="query.addUser"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请输入工单添加人"
@keyup.enter.native="toQuery"
/>
</el-form-item>
<el-form-item label="状态">
<el-select
v-model="query.isPass"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择状态"
>
<el-option
v-for="(item, ind) in isPassOptions"
:key="'jiejue' + ind"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="商户" >
<el-select
v-model="query.merId"
clearable
filterable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择商户"
>
<el-option
v-for="(item, ind) in queryMersOptions"
:key="'sh' + ind"
:label="item.merchantName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="问题分类">
<el-select
v-model="query.problemType"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择问题分类"
>
<el-option
v-for="item in problemTypes"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="处理方式">
<el-select
v-model="query.dealingType"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择处理方式"
>
<el-option
v-for="item in dealingTypes"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="售后类型">
<el-select
v-model="query.saleType"
clearable
size="small"
style="width:150px;font-size:12px"
placeholder="请选择售后类型"
>
<el-option
v-for="item in AftersalesStatus"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="query.addTime"
:default-time="['00:00:00', '23:59:59']"
type="datetimerange"
:unlink-panels="true"
range-separator=":"
size="small"
class="date-item"
style="width:307px;font-size:12px"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="请选择开始时间"
end-placeholder="请选择结束时间"
/>
</el-form-item>
<el-form-item>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-search" @click="toQuery">查 询</el-button>
<el-button plain class="filter-item" size="small" icon="el-icon-close" @click="toQuerys">清 空</el-button>
</el-form-item>
</el-form>
<!-- 新增 -->
<div style="width: 100%;">
<el-button v-if="permission.add" class="filter-item" size="small" type="primary" icon="el-icon-plus" @click="addList">新增</el-button>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-check" @click="batchReview">批量复核</el-button>
<el-button v-if="permission.delete" class="filter-item" size="small" type="primary" icon="el-icon-close" @click="delList">批量删除</el-button>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-check" @click="submitList">批量提交</el-button>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-download" @click="exportXlsx">导出工单</el-button>
<el-button class="filter-item" size="small" type="primary" icon="el-icon-download" @click="exportXlsxStatistics">导出统计</el-button>
</div>
</div>
<!--表单组件-->
<work-form ref="workFormForm" :is-add="isAdd" />
<deliver-good ref="deliverGoodForm" :is-add="isAdd" />
<!--表格渲染-->
<div >
<el-table v-loading="loading" :data="data" size="small"
style="width: 100%;" :height="tableHeight"
@selection-change="handleSelectionChange"
:row-class-name="tableRowClassName"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<!--<el-table-column prop="id" label="ID"/>-->
<el-table-column prop="workOrderNum" label="客服工单编号" align="center" width="128"/>
<el-table-column prop="orderId" label="订单号" align="center" width="180"/>
<el-table-column prop="orderTime" label="订单日期" align="center" width="140"/>
<el-table-column prop="saleType" label="售后类型" width="80" align="center">
<template slot-scope="scope">
<div>
<div v-if="scope.row.saleType == 1" :type="'success'">退款</div>
<div v-if="scope.row.saleType == 2" :type="'success'">退货退款</div>
<div v-if="scope.row.saleType == 3" :type="'success'">换货</div>
<div v-if="scope.row.saleType == 4" :type="'success'">补寄</div>
<div v-if="scope.row.saleType == 5" :type="'success'">待发货退款</div>
</div>
</template>
</el-table-column>
<el-table-column prop="isTemp" label="售后状态" width="150" align="center">
<template slot-scope="scope">
{{analysisOrderStatus(scope.row.afterSaleType)}}
</template>
</el-table-column>
<el-table-column prop="isPass" label="解决状态" width="80" align="center">
<template slot-scope="scope">
<div>
<!-- <span>{{ scope.row.isPass==0?'未解决':scope.row.isPass==1?'部分解决':scope.row.isPass==2?'全部解决':scope.row.isPass==3?'已复核':'' }}</span> -->
<el-tag v-if="scope.row.isPass == 0" :type="'danger'">未解决</el-tag>
<el-tag v-else-if="scope.row.isPass == 1" :type="'warning'"
>部分解决</el-tag
>
<el-tag v-else-if="scope.row.isPass == 2" :type="''"
>全部解决</el-tag>
<el-tag v-else-if="scope.row.isPass == 3" :type="'success'"
>已复核</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="isTemp" label="工单状态" width="80" align="center">
<template slot-scope="scope">
<div>
<el-tag v-if="scope.row.isTemp == 1" :type="'warning'">暂存</el-tag>
<el-tag v-else :type="'success'">已提交</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="fromType" label="工单来源" width="80">
<template slot-scope="scope">
<span>{{ scope.row.fromType==1?'小程序':scope.row.fromType==2?'电话':scope.row.fromType==3?'客服评价':'' }}</span>
</template>
</el-table-column>
<el-table-column label="订单来源" align="center" prop="orderSource">
<template slot-scope="scope">
<span v-if="scope.row.orderSource === '0'">陆海商城</span>
<span v-if="scope.row.orderSource === '1'">福利商城</span>
<span v-if="scope.row.orderSource === '3'">鲁西福礼</span>
<span v-if="scope.row.orderSource === '2'">浪潮商城</span>
</template>
</el-table-column>
<el-table-column prop="merName" label="所属商户" width="150" show-overflow-tooltip />
<el-table-column
prop="payPrice"
label="商品信息"
width="320px"
>
<template slot-scope="scope">
<el-row :gutter="10" v-for="(item,index) in scope.row.detailList" :key="index">
<el-col :span="4" style="height: 46px; padding: 0; overflow: hidden;" v-if="item.image">
<img :src="item.image" :width="45" :height="45" />
</el-col>
<el-col :span="20">
<div>
<el-tag v-if="item.isCombination == '1'" @click="queryProductCombinationOrderDetail(item.orderCartId)" size="mini" effect="dark"><span style="cursor: pointer;">组</span></el-tag>
<span
style="border-bottom: 1px dashed #409eff;color: #409eff;cursor: pointer;padding-bottom: 3px;"
@click="lookDetail(item.productId)"
v-if="item.productId"
>
{{ item.productName }}
</span>
<span
style="color: #409eff;padding-bottom: 3px;"
v-if="!item.productId"
>
{{ item.productName }}
</span>
| {{ item.productNum }}
</div>
<div v-if="item.problemTypeName">问题分类:{{ item.problemTypeName}}</div>
<div v-if="item.dealingTypeName">处理方式:{{ item.dealingTypeName}}</div>
<div v-if="item.problemDesc">问题描述:{{ item.problemDesc }}</div>
</el-col>
</el-row>
</template>
</el-table-column>
<el-table-column
prop="payPrice"
label="图片记录"
width="370px"
>
<template slot-scope="scope">
<div v-if="scope.row.problemPhotoUrlList.length > 0">
<div v-for="item in scope.row.problemPhotoUrlList" :key="item">
<el-image
style="width:85px;height:85px;float:left;margin-right:2px;"
:src="item"
:preview-src-list="scope.row.problemPhotoUrlList"
fit="contain"
:z-index="999"
/>
</div>
</div>
<!-- <img :src="" :preview-src-list="dialogUrl" @click="handlepic(scope.row.problemPhotoUrlList)" :width="85" :height="85" /> -->
</template>
</el-table-column>
<el-table-column prop="linkUserName" label="提报人姓名" width="90" />
<el-table-column prop="linkUserPhone" label="提报人电话" width="100" />
<el-table-column prop="addUser" label="工单添加人" width="80" />
<el-table-column prop="addTime" label="创建时间" width="150">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.addTime) }}</span>
</template>
</el-table-column>
<el-table-column prop="passUser" label="解决人" width="90" />
<el-table-column label="解决时间" width="140" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.passTime) }}</span>
</template>
</el-table-column>
<el-table-column prop="reviewUser" label="复核人" width="90" />
<el-table-column label="复核时间" width="140" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.reviewTime) }}</span>
</template>
</el-table-column>
<el-table-column min-width="280" label="操作" align="center" fixed="right" v-if="permission.coupon_edit||permission.coupon_delete">
<template slot-scope="scope">
<el-link type="info" icon="el-icon-info" @click="detail(scope.row.id,1)" v-if="permission.detail && scope.row.saleType == null">详情</el-link>
<el-link type="info" icon="el-icon-info" @click="checkDetail(scope.row)" v-if="permission.detail && scope.row.saleType != null">详情</el-link>
<el-link title="修改" type="warning" icon="el-icon-edit" style="margin-left:5px" v-if="scope.row.isTemp == 1 && permission.edit" @click="detail(scope.row.id,2)">修改</el-link>
<el-link type="primary" icon="el-icon-truck" @click="deliverGood(scope.row, scope.$index)" :underline="false" v-show="scope.row.isTemp == 0 && scope.row.isPass<2 && scope.row.isDeliveryEnd!='2'" v-if="permission.redelivery && scope.row.saleType == null" style="margin-left:5px">补发快递</el-link>
<el-popover :ref="'pass'+scope.row.id" placement="top" width="180">
<p>确定本条工单已处理完成吗?</p>
<div style="text-align: right; margin: 0">
<el-button
size="mini"
type="text"
@click="$refs['pass'+scope.row.id].doClose()"
>取消
</el-button>
<el-button
:loading="delLoading"
type="primary"
size="mini"
@click="getWorkOut(scope.row.id)"
>确定
</el-button>
</div>
<el-link slot="reference" type="primary" icon="el-icon-document-checked" :underline="false" v-show="scope.row.isTemp == 0 && scope.row.isPass<2" v-if="permission.workOut && scope.row.saleType == null" style="margin-left:5px">解决</el-link>
</el-popover>
<el-popover :ref="'review'+scope.row.id" placement="top" width="180">
<p>确定本条工单复核完成吗?</p>
<div style="text-align: right; margin: 0">
<el-button
size="mini"
type="text"
@click="$refs['review'+scope.row.id].doClose()"
>取消
</el-button>
<el-button
:loading="delLoading"
type="primary"
size="mini"
@click="getRecordList(scope.row.id)"
>确定
</el-button>
</div>
<!-- <el-link title="复核" icon="el-icon-edit" type="warning" v-if="permission.recheck" style="text-decoration:none;margin-left:5px;" v-show="scope.row.isPass==2">复核</el-link> -->
<!-- <el-link slot="reference" type="warning" icon="el-icon-edit" :underline="false" v-if="scope.row.isPass==2" style="text-decoration:none;margin-left:5px;">复核</el-link> -->
<el-link slot="reference" type="warning" icon="el-icon-check" :underline="false" v-if="scope.row.isTemp == 0 && scope.row.isPass==2 && permission.recheck" style="margin-left:5px">复核</el-link>
</el-popover>
<el-popover :ref="scope.row.id" placement="top" width="180">
<p>确定删除本条数据吗?</p>
<div style="text-align: right; margin: 0">
<el-button
size="mini"
type="text"
@click="$refs[scope.row.id].doClose()"
>取消
</el-button>
<el-button
:loading="delLoading"
type="primary"
size="mini"
@click="subDelete(scope.row.id)"
>确定
</el-button>
</div>
<el-link slot="reference" type="danger" icon="el-icon-delete" :underline="false" v-if="scope.row.isTemp==1 && permission.delete" style="margin-left:5px">删除</el-link>
</el-popover>
<!-- <el-link title="处理工单" type="warning" icon="el-icon-edit" style="margin-left:5px" v-show="scope.row.isPass!=2" @click="detail(scope.row.id,2)">处理工单</el-link> -->
<el-link title="工单记录" type="warning" icon="el-icon-tickets" style="margin-left:5px" v-if="permission.orderRecord" @click="gdrecord(scope.row.id,2)">工单记录</el-link>
<el-link type="primary" icon="el-icon-chat-line-round" @click="sendmessage(scope.row, scope.$index)" v-if="scope.row.isTemp == 1 && scope.row.isSendSms == 0 && scope.row.orderSource == 2" :underline="false" style="margin-left:5px">发送短信</el-link>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-footer class="footer-contains">
<!--分页组件-->
<el-pagination :total="total" :current-page="page + 1" style="margin-top: 8px;" layout="total, prev, pager, next, sizes" @size-change="sizeChange" @current-change="pageChange" />
</el-footer>
<!-- 新增 -->
<el-dialog
:append-to-body="true"
:close-on-click-modal="false"
:before-close="cancel"
:visible.sync="addDialog"
title="新增客服工单"
width="400px"
>
<el-form ref="form" :model="form" size="small" label-width="90px" v-loading="loading">
<el-row >
<el-col :span="24">
<el-form-item label="订单号:" prop="orderId" :rules=" [{ required: true, message: '请输入订单号', trigger: 'blur',}]">
<input type="text" clearable
size="small" v-model=" form.orderId " style="width:80%;"/>
</el-form-item>
</el-col>
</el-row>
<div class="dialog-footer">
<el-button :disabled="loading" type="primary" @click="doSubmit">确定</el-button>
<el-button plain @click="cancel">关闭</el-button>
</div>
</el-form>
</el-dialog>
<work-order ref="workOrderFrom" ></work-order>
<order-Record ref="orderRecord" ></order-Record>
<product-detail ref="productDetailComp" :pshow.sync="aa"></product-detail>
<sendmessage ref="sendmessage" ></sendmessage>
<!--组合商品详情组件-->
<groupDetail ref="groupDetail"></groupDetail>
<detail ref="detail"></detail>
</div>
</template>
<script>
import sendmessage from './sendmessage.vue'
import checkPermission from '@/utils/permission'
import initData from '@/mixins/crud'
import {
del,delList,submitList,getAllInfo,getWorkOut,getOrderAllInfoByOid,reviewByIds,reviewById,exportData,exportStatistics
} from '@/api/store/yxStoreWorkOrder'
import workForm from './workForm'
import deliverGood from './toDeliverGood'
import {
parseTime
} from '@/utils/index'
import {
mapGetters
} from "vuex";
import workOrder from "./form";
import orderRecord from "./orderRecord";
import { da } from 'date-fns/locale'
import productDetail from "../../stock/warning/productDetail";
import {
getAllMerchants
} from "@/api/store/yxStoreProduct";
import { queryProductCombinationOrderDetail } from "@/api/store/yxStoreOrder";
import groupDetail from '@/views/shop/order/groupDetail.vue'
import detail from "./index_detail";
import {
dataCustom_to_sheetFormat,
exportFile,
mergeCell
} from "@/utils/processFile";
// import xlsx from "xlsx";
import * as xlsx from 'xlsx-js-style';
import { saveAs } from 'file-saver';
export default {
components: {
workForm,
deliverGood,
workOrder,
orderRecord,
sendmessage,
"product-detail": productDetail,
groupDetail,
detail
},
mixins: [initData],
data() {
return {
addDialog:false,
delLoading: false,
cids:[],
cnames:'',
query:{
"orderId":undefined,
"fromType":undefined,
"linkUserName":undefined,
"addUser":undefined,
"linkUserPhone":undefined,
"isPass":undefined,
"workOrderNum":undefined,
"merId":undefined,
"problemType":undefined,
"dealingType":undefined,
"saleType":undefined,
},
queryTypeOptions: [
{
key: "1",
display_name: "小程序"
},
{
key: "2",
display_name: "电话"
},
{
key: "3",
display_name: "客服评价"
}
],
problemTypes:[
{label: '漏发', value: 1},
{label: '破损', value: 2},
{label: '错发', value: 3},
{label: '无物流信息', value: 4},
{label: '物流信息错误', value: 5},
{label: '临期产品', value: 6},
{label: '退货', value: 7},
{label: '商品与图片不符', value: 8},
{label: '其他', value: 9},
{label: '质量问题', value: 10},
{label: '待确认', value: -1}
],
dealingTypes:[
{label: '补发', value: 1},
{label: '换货', value: 2},
{label: '退货', value: 3},
{label: '退货退款', value: 4},
{label: '仅退款', value: 5},
{label: '等待商户答复', value: 6},
{label: '待确认', value: -1}
],
AftersalesStatus:[{label: '退款', value: 1},{label: '退货退款', value: 2},{label: '换货', value: 3},{label: '补寄', value: 4},{label: '待发货退款', value: 5}],
isPassOptions: [
{
value: "0",
label: "未解决"
},
{
value: "1",
label: "部分解决"
},
{
value: "2",
label: "全部解决"
},
{
value: "3",
label: "已复核"
}],
isAdd:false,
workdialog:false,
form:{
orderId:''
},
queryMersOptions: [],
qustionList:[{
id:1,
label:'漏发'
},{
id:2,
label:'破损'
},{
id:3,
label:'错发'
},{
id:4,
label:'无物流信息'
},{
id:5,
label:'物流信息错误'
},{
id:6,
label:'临期产品'
},{
id:7,
label:'退货'
},{
id:8,
label:'商品与图片不符'
},{
id:10,
label:'质量问题'
},{
id:9,
label:'其他'
},{
id:-1,
label:'待确认'
}],
orderStatus: [
{ key: 0, value: '无售后' },
{ key: 1, value: '用户取消售后申请' },
{ key: 2, value: '超时自动取消售后申请' },
{ key: 3, value: '售后完成' },
{ key: 4, value: '赔付E卡' },
{ key: 5, value: '待上门取件' },
{ key: 6, value: '返品质检不通过' },
{ key: 7, value: '待返品质检' },
{ key: 8, value: '待用户提交返品物流单号' },
{ key: 11, value: '退款待审核' },
{ key: 12, value: '退款审核通过' },
{ key: 13, value: '退款审核不通过' },
{ key: 14, value: '退款补发成功' },
{ key: 15, value: '退款成功' },
{ key: 21, value: '退货退款待审核' },
{ key: 22, value: '退货退款审核不通过' },
{ key: 23, value: '待退款' },
{ key: 24, value: '退货退款成功' },
{ key: 31, value: '换货待审核' },
{ key: 32, value: '换货审核不通过' },
{ key: 33, value: '待生成换货订单' },
{ key: 34, value: '换货成功' },
{ key: 41, value: '补寄待审核' },
{ key: 42, value: '补寄审核不通过' },
{ key: 43, value: '补寄成功' }
],
exportLoading:false,
tableHeight:document.body.clientHeight - 360,
aa:false,
dialogVisible:false,
dialogUrl:[],
}
},
created() {
this.$nextTick(() => {
this.init()
})
this.getAllMers()
},
computed: {
...mapGetters(["permission"])
},
filters:{
filterType(val){
console.log('val++',val)
this.qustionList.forEach(item=>{
if(item.id==val){
return item.label
}
})
}
},
mounted() {
this.setTableHeight();
window.addEventListener('resize', this.setTableHeight);
},
beforeDestroy() {
window.removeEventListener('resize', this.setTableHeight);
},
methods: {
analysisOrderStatus(val) {
const status = this.orderStatus.find(item => item.key == val);
return status ? status.value : '未知状态';
},
/** 导出 */
// exportXlsx() {
// let addTimeStart
// let addTimeEnd
// if(this.query.addTime != undefined && this.query.addTime.length>0){
// addTimeStart=this.query.addTime[0]
// addTimeEnd=this.query.addTime[1]
// }else{
// addTimeStart=null
// addTimeEnd=null
// }
// let params = {
// orderId:this.query.orderId,
// fromType:this.query.fromType,
// linkUserName:this.query.linkUserName,
// addUser:this.query.addUser,
// linkUserPhone:this.query.linkUserPhone,
// isPass:this.query.isPass,
// problemType:this.query.problemType,
// dealingType:this.query.dealingType,
// saleType:this.query.saleType,
// orderSource:this.query.orderSource,
// workOrderNum:this.query.workOrderNum,
// isDel: 0,
// addTimeStart:addTimeStart,
// addTimeEnd:addTimeEnd,
// }
// const loading = this.$loading({
// lock: true,
// text: '数据正在导出中...',
// spinner: 'el-icon-loading',
// background: 'rgba(0, 0, 0, 0.7)'
// });
// this.exportLoading = true;
// exportData(params).then((res) => {
// this.exportLoading = false;
// if (res.data.success) {
// loading.close();
// let flag = null;
// let arr = [];
// res.data.data.forEach((item, index) => {
// if (flag != item.工单编号) {
// flag = item.工单编号;
// } else {
// if (!arr.find((item1) => item1.name == item.工单编号)) {
// let len = res.data.data.filter((item1) => item1.工单编号 == item.工单编号).length;
// arr.push({ name: item.工单编号, index, len });
// }
// }
// });
// let header = {};
// header = {
// 工单编号: "工单编号",
// 订单号: "订单号",
// 订单日期: "订单日期",
// 状态: "状态",
// 订单来源: "订单来源",
// 领导工单: '领导工单',
// 商户名称: "商户名称",
// 商品名称: "商品名称",
// 商品编码: "商品编码",
// 问题类型: "问题类型",
// 处理方式: "处理方式",
// 问题描述: "问题描述",
// 快递公司: "快递公司",
// 快递单号: "快递单号",
// 提报人: "提报人",
// 提报人联系方式: "提报人联系方式",
// 售后收货地址: "售后收货地址",
// 创建时间: "创建时间",
// 解决人:'解决人',
// 图片链接:'图片链接',
// };
// exportFile({
// titleStartRow: 0,
// titleStartCol: 0,
// startRow: 0,
// data: res?.data?.data,
// header,
// fileName: "客服工单",
// Func: (ws) => {
// arr.forEach((item) => {
// mergeCell(
// ws,
// `A${item.index + 1}`,
// `A${item.index + item.len}`
// );
// mergeCell(
// ws,
// `B${item.index + 1}`,
// `B${item.index + item.len}`
// );
// });
// return ws;
// },
// });
// }else{
// loading.close();
// }
// })
// .catch((err) => {
// loading.close();
// this.exportLoading = false;
// });
// },
exportXlsx() {
let addTimeStart;
let addTimeEnd;
if (this.query.addTime && this.query.addTime.length > 0) {
addTimeStart = this.query.addTime[0];
addTimeEnd = this.query.addTime[1];
} else {
addTimeStart = null;
addTimeEnd = null;
}
let params = {
orderId: this.query.orderId,
fromType: this.query.fromType,
linkUserName: this.query.linkUserName,
addUser: this.query.addUser,
linkUserPhone: this.query.linkUserPhone,
isPass: this.query.isPass,
problemType: this.query.problemType,
dealingType: this.query.dealingType,
saleType: this.query.saleType,
orderSource: this.query.orderSource,
workOrderNum: this.query.workOrderNum,
isDel: 0,
addTimeStart,
addTimeEnd,
};
const loading = this.$loading({
lock: true,
text: '数据正在导出中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.exportLoading = true;
exportData(params).then((res) => {
this.exportLoading = false;
if (res.data.success) {
loading.close();
// 定义表头
let header = {
工单编号: "工单编号",
订单号: "订单号",
订单日期: "订单日期",
状态: "状态",
订单来源: "订单来源",
领导工单: "领导工单",
商户名称: "商户名称",
商品名称: "商品名称",
商品编码: "商品编码",
问题类型: "问题类型",
处理方式: "处理方式",
问题描述: "问题描述",
快递公司: "快递公司",
快递单号: "快递单号",
提报人: "提报人",
提报人联系方式: "提报人联系方式",
售后收货地址: "售后收货地址",
创建时间: "创建时间",
解决人: "解决人",
用户上传凭证: "用户上传凭证"
};
// 使用 xlsx.utils 创建空工作表
const ws = {};
const wb = xlsx.utils.book_new();
// 表头行
const headerRow = Object.values(header);
xlsx.utils.sheet_add_aoa(ws, [headerRow], { origin: "A1" });
// 图片插入准备
const imagePromises = [];
const imageInfoList = [];
// 每行数据 + 图片处理
res.data.data.forEach((item, rowIndex) => {
const rowData = [
item.工单编号,
item.订单号,
item.订单日期,
item.状态,
item.订单来源,
item.领导工单,
item.商户名称,
item.商品名称,
item.商品编码,
item.问题类型,
item.处理方式,
item.问题描述,
item.快递公司,
item.快递单号,
item.提报人,
item.提报人联系方式,
item.售后收货地址,
item.创建时间,
item.解决人
];
// 插入数据行
xlsx.utils.sheet_add_aoa(ws, [rowData], { origin: `A${rowIndex + 2}` });
// 图片插入
const imageUrl = item['用户上传凭证'][0];
console.log(imageUrl)
if (imageUrl) {
const imagePromise = fetch(imageUrl)
.then(res => res.arrayBuffer())
.then(buffer => {
const imageType = imageUrl.split('.').pop().toLowerCase();
const ext = imageType === 'jpg' || imageType === 'jpeg' ? 'jpeg' : imageType;
const image = {
image: buffer,
extension: ext,
};
imageInfoList.push({
image,
position: `T${rowIndex + 2}`, // 插入到 T 列
});
});
imagePromises.push(imagePromise);
}
});
console.log(imagePromises)
// 等待所有图片加载完成
Promise.all(imagePromises).then(() => {
// 插入图片
xlsx.utils.sheet_add_img(ws, 0, imageInfoList);
// 添加工作表到工作簿
xlsx.utils.book_append_sheet(wb, ws, "客服工单");
// 导出文件
xlsx.write(wb, {
bookType: 'xlsx',
type: 'binary',
cellStyles: true
});
// 使用 FileSaver.js 保存文件
xlsx.writeFile(wb, "客服工单.xlsx");
});
} else {
loading.close();
this.$message.error(res.data.message || '导出失败');
}
}).catch((err) => {
loading.close();
this.exportLoading = false;
this.$message.error('导出过程中发生错误');
console.error('导出错误:', err);
});
},
checkDetail(row) {
let _this = this.$refs.detail
getAllInfo(row.id).then(res => {
let data = res.data.data
_this.form = data
_this.form.merchantName = row.merchantName
_this.form.merchantPhone = row.merchantPhone;
let merchantAddressId = data.merchantAddressId
if(merchantAddressId){
_this.queryMerAddressById({id:merchantAddressId})
}
_this.dialog = true;
}).catch(err => {
})
},
queryProductCombinationOrderDetail(id){
queryProductCombinationOrderDetail(id).then((res)=>{
//主商品信息
let mainProduct = res.data.data.productInfo
//子商品信息
let subProduct = res.data.data.combinationList
this.$refs.groupDetail.form = mainProduct
this.$refs.groupDetail.form.image = mainProduct.image.split(',')
this.$refs.groupDetail.form.sliderImage = mainProduct.sliderImage.split(',')
this.$refs.groupDetail.shopInfoData = subProduct
this.$refs.groupDetail.dialog = true
})
},
exportXlsxStatistics(){
let time = this.query.addTime
let addTimeStart
let addTimeEnd
if(this.query.addTime != undefined && this.query.addTime.length>0){
addTimeStart=time[0]
addTimeEnd=time[1]
}else{
addTimeStart=null
addTimeEnd=null
}
let params = {
orderId:this.query.orderId,
fromType:this.query.fromType,
linkUserName:this.query.linkUserName,
addUser:this.query.addUser,
linkUserPhone:this.query.linkUserPhone,
isPass:this.query.isPass,
problemType:this.query.problemType,
dealingType:this.query.dealingType,
saleType:this.query.saleType,
workOrderNum:this.query.workOrderNum,
isDel: 0,
addTimeStart:addTimeStart,
addTimeEnd:addTimeEnd,
}
this.exportLoading = true;
exportStatistics(params).then((res) => {
this.exportLoading = false;
if (res.data.success) {
let flag = null;
let arr = [];
res.data.data.forEach((item, index) => {
if (flag != item.id) {
flag = item.id;
} else {
if (!arr.find((item1) => item1.name == item.id)) {
let len = res.data.data.filter((item1) => item1.id == item.id).length;
arr.push({ name: item.id, index, len });
}
}
});
let header = {};
header = {
商户名称: "商户名称",
质量问题: "质量问题",
商品与图片不符: "商品与图片不符",
无物流信息: "无物流信息",
物流信息错误: "物流信息错误",
临期产品: "临期产品",
漏发: "漏发",
破损: "破损",
退货: "退货",
错发: "错发",
其他: "其他",
};
exportFile({
titleStartRow: 0,
titleStartCol: 0,
startRow: 0,
data: res?.data?.data,
header,
fileName: "导出统计",
Func: (ws) => {
// arr.forEach((item) => {
// mergeCell(
// ws,
// `A${item.index + 1}`,
// `A${item.index + item.len}`
// );
// });
return ws;
},
});
}
})
.catch((err) => {
this.exportLoading = false;
});
},
getAllMers() {
getAllMerchants().then(({ data }) => {
if (data && data.code === 200) {
this.queryMersOptions = data.data;
} else {
this.$message({
message: data.msg,
type: "error"
});
this.queryMersOptions = [];
}
});
},
getRecordList(id){
this.delLoading = true
reviewById(id).then(res => {
console.log(res)
// if(res.data.code==200){
// this.init()
// this.$notify({
// title: res.data.msg,
// type: 'success',
// duration: 2500
// })
// }
this.delLoading = false
this.$refs['review'+id].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '复核成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
this.$refs['review'+id].doClose()
console.log(err)
})
},
lookDetail(id) {
this.aa = true;
let that=this
this.$nextTick(() => {
that.$refs.productDetailComp.getProductDetail(id);
})
},
gdrecord(id){
let _this = this.$refs.orderRecord;
_this.query.workOrderId=id
this.$nextTick(() => {
_this.init()
})
_this.recordDialog=true;
},
batchReview(){
if(this.cids.length<=0){
this.$notify({
title: '请至少选择一条数据!',
type: 'warning',
duration: 2500
})
return false
}
this.$confirm("确定所选工单复核通过吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
reviewByIds(this.cids).then(res => {
this.delLoading = false
this.dleChangePage()
this.init()
this.$notify({
title: '复核成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
console.log(err)
})
})
.catch(() => {});
},
setTableHeight() {
// console.log(window.innerWidth);
// 1328
this.tableHeight = window.innerHeight - 120; // 假设顶部有其他内容占用100px
},
cancel() {
this.addDialog = false;
},
addList(){
this.form.orderId="";
this.addDialog=true;
},
doSubmit(){
let _thisAdd = this.$refs.workOrderFrom,orderObj;
this.$refs['form'].validate(valid => {
if (valid) {
getOrderAllInfoByOid(this.form.orderId).then(res => {
// console.log('res+++',res)
if(res.data.code==200){
this.addDialog=false;
orderObj=res.data.data
const odeDetailList=JSON.parse(JSON.stringify(orderObj.detailList))
// odeDetailList.map(item => {
// item.orderCartId=item.id
// })
_thisAdd.goodsList = odeDetailList.map(item => {
item.orderCartId=item.id
item.maxProductNum = item.productNum;
item.previewSrcList = [];
return item;
});
// console.log(odeDetailList)
_thisAdd.form = {
id: orderObj.id, //工单ID
oid: orderObj.id, //工单ID
orderId: orderObj.orderId, //订单编号
fromType:"",
rmk:"",
linkUserName:orderObj.linkUserName,
addUser:orderObj.addUser,
linkUserPhone:orderObj.linkUserPhone,
linkUserAddress:orderObj.linkUserAddress,
detailList:[],
};
_thisAdd.workdialog = true;
}
})
}
})
},
deliverGood(row){
const _this = this.$refs.deliverGoodForm;
_this.resetForm();
_this.listId=row.id;
_this.getMore();
_this.goodDialog = true;
_this.loading = false;
},
sendmessage(row){
this.$refs.sendmessage.form.linkUserPhone = row.linkUserPhone;
this.$refs.sendmessage.form.id = row.id;
this.$refs.sendmessage.sendDialog = true;
},
//解决
getWorkOut(id){
this.delLoading = true
getWorkOut(id).then(res => {
this.delLoading = false
this.$refs['pass'+id].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '解决成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
this.$refs['pass'+id].doClose()
console.log(err)
})
},
//批量删除
delList(){
if(this.cids.length<=0){
this.$notify({
title: '请至少选择一条数据',
type: 'warning',
duration: 2500
})
return false
}
this.$confirm("确定删除所选工单吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
delList(this.cids).then(res => {
this.delLoading = false
// this.$refs[id].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
console.log(err)
})
})
.catch(() => {});
},
//批量提交
submitList(){
if(this.cids.length<=0){
this.$notify({
title: '请至少选择一条数据',
type: 'warning',
duration: 2500
})
return false
}
this.$confirm("确定提交所选工单吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
submitList(this.cids).then(res => {
this.delLoading = false
// this.$refs[id].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '提交成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
console.log(err)
})
})
.catch(() => {});
},
parseTime,
checkPermission,
handleSelectionChange(val){
let delIds = [];
// this.cnames = ''
val.forEach(x=>{
delIds.push(x.id)
this.cnames += x.title + ','
})
console.log(delIds)
this.cids=delIds;
console.log(this.cids)
// console.log(this.cnames)
},
beforeInit() {
this.url = 'api/lh-yshop-system/yxWorkOrder/list'
const sort = 'id,desc'
// console.log(this.query.addTime)
// let time = this.query.addTime
// let addTimeStart = ''
// let addTimeEnd = ''
// if(this.query.addTime != undefined && this.query.addTime.length>0){
// addTimeStart=time[0]
// addTimeEnd=time[1]
// }else{
// addTimeStart=""
// addTimeEnd=""
// }
this.params = {
addTime: this.query.addTime,
current: this.page + 1,
orderId:this.query.orderId,
fromType:this.query.fromType,
linkUserName:this.query.linkUserName,
addUser:this.query.addUser,
linkUserPhone:this.query.linkUserPhone,
isPass:this.query.isPass,
problemType:this.query.problemType,
dealingType:this.query.dealingType,
saleType:this.query.saleType,
workOrderNum:this.query.workOrderNum,
size: this.size,
isDel: 0,
}
return true
},
toQuerys() {
delete this.query.fromType;
delete this.query.isPass;
(this.query.workOrderNum = ""),
(this.query.orderId = ""),
(this.query.linkUserName = ""),
(this.query.addUser = ""),
(this.query.linkUserPhone = ""),
(this.query.merId = ""),
(this.query.problemType = ""),
(this.query.dealingType = ""),
(this.query.addTime = []),
(this.query.saleType = ""),
this.$nextTick(() => {
this.init();
});
},
subDelete(id) {
this.delLoading = true
del(id).then(res => {
this.delLoading = false
this.$refs[id].doClose()
this.dleChangePage()
this.init()
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
}).catch(err => {
this.delLoading = false
this.$refs[id].doClose()
console.log(err.response.data.message)
})
},
detail(rowId,val) {
this.isAdd = true
const _this = this.$refs.workFormForm,that=this
_this.listId=rowId;
if(val==1){
_this.formFlag=true
}else if(val==2){
_this.formFlag=false
}
getAllInfo(rowId).then(res => {
let data=res.data.data
const detailList = JSON.parse(JSON.stringify(data.detailList));
let formDetailList = detailList.map((item,ind)=>{
item.dealingType=Number(item.dealingType);
item.problemType=Number(item.problemType);
item.isPass=Number(item.isPass)
console.log('dizhi +++',item.problemPhotoUrl)
if(item.problemPhotoUrl!=''){
let ary = item.problemPhotoUrl.split(',')
let previewSrcList = [];
// _this.form.detailList[ind].problemPhotoUrl=ary
// that.$set('_this.previewSrcList[ind]','srcList','')
// _this.previewSrcList.push({srcList:[]})
ary.forEach((image,k)=>{
// _this.previewSrcList[ind].srcList.push({'url':item})
if(image) {
previewSrcList.push({'url':image})
}
})
item.previewSrcList = previewSrcList
}else{
item.previewSrcList=[]
// _this.previewSrcList.push({srcList:[]})
// _this.previewSrcList[ind].srcList.push('[]')
}
// console.log(' _this.previewSrcList', _this.previewSrcList)
return item;
})
_this.previewSrcList=[]
_this.form={
id:data.id,
merId:data.merId,
orderId:data.orderId,
orderSource: data.orderSource,
workOrderNum:data.workOrderNum,
linkUserName:data.linkUserName,
addUser:data.addUser,
linkUserPhone:data.linkUserPhone,
linkUserAddress:data.linkUserAddress,
orderAddTime:data.orderAddTime,
orderPayTime:data.orderPayTime,
isMultAdress:Number(data.isMultAdress),
isDeliveryEnd:Number(data.isDeliveryEnd),
isPass:Number(data.isPass),
dealingType:Number(data.dealingType),
problemType:Number(data.problemType),
isTemp: data.isTemp,
rmk:data.rmk,
addTime:data.addTime,
detailList:formDetailList
}
_this.workdialog = true
_this.handelChage()
}).catch(err => {
// console.log(err.response.data.message)
})
},
edit(data) {
this.isAdd = false
const _this = this.$refs.workFormForm
_this.form = {
id: data.id,
title: data.title,
integral: data.integral,
couponPrice: data.couponPrice,
useMinPrice: data.useMinPrice,
couponTime: data.couponTime,
sort: data.sort,
isTemp: data.isTemp,
addTime: data.addTime,
isDel: data.isDel
}
_this.dialog = true
},
/** 设置行的样式 */
tableRowClassName({ row, rowIndex }) {
if (row.isLeader === "1" && (row.isPass == 0 || row.isPass == 1)) {
return "leader-row";
}
return "";
},
}
}
</script>
<style lang="scss" scoped>
// ::v-deep .el-input {
// position: relative;
// font-size: 12px;
// line-height: normal;
// }
// ::v-deep .el-range-editor--small .el-range-input {
// font-size: 12px;
// }
// .el-col input{border:#C0C4CC solid 1px !important; border-radius:3px !important;height:32px !important;width:100%;}
// ::v-deep .el-form-item__label{font-size:12px !important; font-weight:500 !important;}
// .dialog-footer { display: flex; justify-content:flex-end;}
::v-deep .el-form-item{
margin-bottom: 0px;
}
.el-table ::v-deep .leader-row {
background: #e6a23c;
}
.app-container .app-container {
padding: 0;
}
::v-deep .app-container {
padding-top: 10px;
}
::v-deep .el-select {
.el-input {
.el-icon-circle-close {
line-height: 30px !important;
}
}
}
.el-table ::v-deep .leader-row {
background: #e6a23c;
}
.el-col ::v-deep {
margin-bottom: 0;
}
::v-deep .el-button--mini{
padding: 7px 8px;
}
</style>