424 lines
13 KiB
Vue
424 lines
13 KiB
Vue
<template>
|
||
<div>
|
||
<el-form :model="searchForm" label-width="0" inline>
|
||
<template v-if="appStore.getAppInfo?.instanceType == 2">
|
||
<el-form-item>
|
||
<el-input v-model="searchForm.signOrderId" placeholder="成交单号" clearable />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-input v-model="searchForm.signId" placeholder="子订单号" clearable />
|
||
</el-form-item>
|
||
</template>
|
||
<el-form-item v-else>
|
||
<el-input v-model="searchForm.signId" placeholder="成交单号" clearable />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-input v-model="searchForm.name" placeholder="线索名称" clearable />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-select v-model="searchForm.state" placeholder="审核状态" clearable style="width: 120px">
|
||
<el-option label="待审核" :value="1" />
|
||
<el-option label="已撤销" :value="2" />
|
||
<el-option label="已通过" :value="3" />
|
||
<el-option label="已驳回" :value="4" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-select
|
||
v-model="searchForm.signUser"
|
||
placeholder="登记人"
|
||
clearable
|
||
filterable
|
||
style="width: 120px"
|
||
>
|
||
<el-option
|
||
v-for="item in userOptions"
|
||
:key="item.id"
|
||
:label="item.nickname"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-date-picker
|
||
v-model="searchForm.dealDate"
|
||
type="daterange"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
range-separator="-"
|
||
start-placeholder="成交日期"
|
||
end-placeholder="成交日期"
|
||
style="width: 240px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-select
|
||
v-model="searchForm.applyUser"
|
||
placeholder="申请人"
|
||
clearable
|
||
filterable
|
||
style="width: 120px"
|
||
>
|
||
<el-option
|
||
v-for="item in userOptions"
|
||
:key="item.id"
|
||
:label="item.nickname"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-date-picker
|
||
v-model="searchForm.applyTime"
|
||
type="daterange"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
range-separator="-"
|
||
start-placeholder="申请日期"
|
||
end-placeholder="申请日期"
|
||
style="width: 240px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-date-picker
|
||
v-model="searchForm.checkTime"
|
||
type="daterange"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
range-separator="-"
|
||
start-placeholder="审核日期"
|
||
end-placeholder="审核日期"
|
||
style="width: 240px"
|
||
/>
|
||
</el-form-item>
|
||
<template v-if="appStore.getAppInfo?.instanceType == 1">
|
||
<el-form-item>
|
||
<el-select v-model="searchForm.area" placeholder="选择区域" clearable filterable>
|
||
<el-option
|
||
v-for="item in areaOptions"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</template>
|
||
<el-form-item>
|
||
<el-button @click="handleSearch" v-hasPermi="['clue:order:after-sale-search']">
|
||
查询
|
||
</el-button>
|
||
<el-button @click="handleReset" v-hasPermi="['clue:order:after-sale-reset']">
|
||
重置
|
||
</el-button>
|
||
<el-button @click="batchAudit" v-hasPermi="['clue:order:after-sale-batch-audit']">
|
||
批量审核
|
||
</el-button>
|
||
<el-upload
|
||
ref="salaryFile"
|
||
action="#"
|
||
:limit="1"
|
||
accept=".xls,.xlsx"
|
||
:show-file-list="false"
|
||
style="margin-left: 10px; height: 32px"
|
||
:before-upload="fileBeforeUpload"
|
||
:http-request="afterSalesUpload"
|
||
:disabled="uploading"
|
||
v-hasPermi="['clue:order:after-sale-import']"
|
||
>
|
||
<el-button type="primary"> 导入 </el-button>
|
||
</el-upload>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<el-table
|
||
v-loading="loading"
|
||
:data="tableList"
|
||
border
|
||
@selection-change="handleSelectionChange"
|
||
>
|
||
<el-table-column type="selection" width="55" :selectable="(row) => row.state == 1" />
|
||
<!-- <el-table-column prop="signId" label="成交单号" min-width="150px" /> -->
|
||
<el-table-column
|
||
v-if="appStore.getAppInfo?.instanceType == 1"
|
||
prop="signId"
|
||
label="成交单号"
|
||
min-width="120px"
|
||
/>
|
||
<el-table-column
|
||
v-if="appStore.getAppInfo?.instanceType == 2"
|
||
prop="signOrderId"
|
||
label="成交单号"
|
||
min-width="120px"
|
||
/>
|
||
<el-table-column
|
||
v-if="appStore.getAppInfo?.instanceType == 2"
|
||
prop="signId"
|
||
label="子订单号"
|
||
min-width="120px"
|
||
/>
|
||
<el-table-column prop="name" label="线索名称" min-width="150px" />
|
||
<el-table-column prop="phone" label="联系方式" min-width="120px" />
|
||
<el-table-column
|
||
v-if="appStore.getAppInfo?.instanceType == 1"
|
||
prop="area"
|
||
label="区域"
|
||
min-width="90"
|
||
/>
|
||
<el-table-column prop="reason" label="售后原因" min-width="150px" />
|
||
<el-table-column prop="refundAmount" label="退款金额" min-width="90px" />
|
||
<el-table-column prop="percentageDeductAmount" label="提成扣款" min-width="90px" />
|
||
<el-table-column prop="isCompanyReceipts" label="是否公司收款" min-width="120px" />
|
||
<el-table-column prop="isReturns" label="是否退货" min-width="90px" />
|
||
<el-table-column prop="solution" label="解决方案" min-width="150px" />
|
||
<el-table-column prop="signUserName" label="登记人" min-width="90px" />
|
||
<el-table-column
|
||
prop="dealDate"
|
||
label="成交日期"
|
||
min-width="120px"
|
||
:formatter="dateFormatter"
|
||
/>
|
||
<el-table-column prop="applyUserName" label="申请人" min-width="90px" />
|
||
<el-table-column
|
||
prop="applyTime"
|
||
label="申请时间"
|
||
min-width="120px"
|
||
:formatter="dateFormatter"
|
||
/>
|
||
<el-table-column prop="checkUser" label="审核人" min-width="90" />
|
||
<el-table-column
|
||
prop="checkTime"
|
||
label="审核时间"
|
||
min-width="120px"
|
||
:formatter="dateFormatter"
|
||
/>
|
||
<el-table-column prop="stateName" label="审核状态" fixed="right" min-width="90px" />
|
||
<el-table-column label="操作" width="150px" fixed="right">
|
||
<template #default="{ row }">
|
||
<el-button
|
||
type="primary"
|
||
style="padding: 0"
|
||
text
|
||
v-hasPermi="['clue:order:after-sale-detail']"
|
||
@click="handleDetail(row.id)"
|
||
>
|
||
详情
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
style="padding: 0"
|
||
text
|
||
v-if="row.state == 1 && currentUserId == row.applyUser"
|
||
v-hasPermi="['clue:order:after-sale']"
|
||
@click="handleCancel(row.id)"
|
||
>
|
||
撤销
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
style="padding: 0"
|
||
text
|
||
v-if="row.state == 1"
|
||
v-hasPermi="['clue:order:after-sale-audit']"
|
||
@click="handleAudit(row)"
|
||
>
|
||
审核
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<Pagination
|
||
v-model:limit="searchForm.pageSize"
|
||
v-model:page="searchForm.pageNo"
|
||
:total="total"
|
||
@pagination="getList"
|
||
/>
|
||
<DialogAfterSaleAudit ref="afterSaleAuditDialog" @success="getList" />
|
||
<DialogAfterSaleDetail ref="afterSaleDetailDialog" />
|
||
<DialogBatchAudit ref="batchAuditDialog" @success="getList" />
|
||
</div>
|
||
</template>
|
||
|
||
<script setup name="AfterSales">
|
||
import * as AfterSaleApi from '@/api/clue/afterSale'
|
||
import { getSimpleUserList as getUserOption } from '@/api/system/user'
|
||
import { getAreaSimpleList } from '@/api/school/setting/area'
|
||
import { useUserStore } from '@/store/modules/user'
|
||
|
||
import DialogAfterSaleAudit from './DialogAfterSaleAudit.vue'
|
||
import DialogAfterSaleDetail from './DialogAfterSaleDetail.vue'
|
||
import DialogBatchAudit from './DialogBatchAudit.vue'
|
||
|
||
import { removeNullField } from '@/utils'
|
||
import { dateFormatter } from '@/utils/formatTime'
|
||
import { useAppStore } from '@/store/modules/app'
|
||
import { exportArrayToExcel } from '@/utils/index'
|
||
|
||
const afterSaleAuditDialog = ref()
|
||
|
||
const userStore = useUserStore()
|
||
const appStore = useAppStore()
|
||
const message = useMessage() // 消息弹窗
|
||
|
||
const currentUserId = userStore.getUser.id
|
||
|
||
const searchForm = ref({
|
||
signId: undefined,
|
||
name: undefined,
|
||
dealDate: [],
|
||
state: undefined,
|
||
dealUser: undefined,
|
||
createDate: [],
|
||
createUser: undefined,
|
||
checkTime: [],
|
||
signOrderId: undefined,
|
||
pageNo: 1,
|
||
pageSize: 20
|
||
})
|
||
|
||
const userOptions = ref([])
|
||
|
||
const tableList = ref([])
|
||
const total = ref(0)
|
||
|
||
function handleSearch() {
|
||
searchForm.value.pageNo = 1
|
||
getList()
|
||
}
|
||
|
||
function handleReset() {
|
||
searchForm.value = {
|
||
signId: undefined,
|
||
name: undefined,
|
||
state: undefined,
|
||
dealDate: [],
|
||
dealUser: undefined,
|
||
createDate: [],
|
||
createUser: undefined,
|
||
checkTime: [],
|
||
signOrderId: undefined,
|
||
pageNo: 1,
|
||
pageSize: 20
|
||
}
|
||
}
|
||
|
||
const loading = ref(false)
|
||
async function getList() {
|
||
loading.value = true
|
||
try {
|
||
const data = await AfterSaleApi.getAfterSalePage(removeNullField(searchForm.value))
|
||
tableList.value = data.list
|
||
total.value = data.total
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
const batchIds = ref([])
|
||
function handleSelectionChange(val) {
|
||
batchIds.value = val.map((it) => it.id)
|
||
}
|
||
|
||
const batchAuditDialog = ref()
|
||
function batchAudit() {
|
||
if (batchIds.value.length) {
|
||
batchAuditDialog.value.open('aftersale', batchIds.value)
|
||
} else {
|
||
message.info('请选择表格中需要审核的数据')
|
||
}
|
||
}
|
||
|
||
const afterSaleDetailDialog = ref()
|
||
function handleDetail(id) {
|
||
afterSaleDetailDialog.value.open(id)
|
||
}
|
||
async function handleCancel(id) {
|
||
try {
|
||
// 删除的二次确认
|
||
await message.confirm('是否确认撤销申请?')
|
||
// 发起删除
|
||
await AfterSaleApi.cancelApplyAfterSale({ id })
|
||
message.success('撤销成功!')
|
||
// 刷新列表
|
||
await getList()
|
||
} catch (err) {
|
||
console.log(err)
|
||
}
|
||
}
|
||
function handleAudit(row) {
|
||
afterSaleAuditDialog.value.open(row)
|
||
}
|
||
|
||
const fileBeforeUpload = (file) => {
|
||
let format = '.' + file.name.split('.')[1]
|
||
if (!['.xls', '.xlsx'].includes(format)) {
|
||
message.error(`请上传指定格式".xls,.xlsx"文件`)
|
||
return false
|
||
}
|
||
let isRightSize = file.size / 1024 / 1024 < 20
|
||
if (!isRightSize) {
|
||
message.error('文件大小超过 20MB')
|
||
}
|
||
return isRightSize
|
||
}
|
||
|
||
const uploading = ref(false)
|
||
async function afterSalesUpload(data) {
|
||
uploading.value = true
|
||
const fd = new FormData()
|
||
fd.append('file', data.file)
|
||
try {
|
||
const resp = await AfterSaleApi.importAfterSales(fd)
|
||
debugger
|
||
if (resp && resp.data && resp.data.length) {
|
||
const succList = resp.data.filter((item) => item.success)
|
||
const failList = resp.data.filter((item) => !item.success)
|
||
let msg = `导入完成!成功 ${succList.length} 条,失败 ${failList.length} 条。`
|
||
if (failList.length) {
|
||
// 如果有失败,提示下载失败文件
|
||
msg += '\n请点击消息下载失败明细进行查看。'
|
||
}
|
||
ElNotification({
|
||
title: '导入结果',
|
||
message: msg,
|
||
type: 'info',
|
||
duration: 0,
|
||
onClick: () => {
|
||
if (failList.length) {
|
||
// 将failList生成文件,使用前端下载
|
||
exportArrayToExcel(failList, `售后导入失败明细${new Date().getTime()}`, [
|
||
{ title: '手机号', key: 'phone' },
|
||
{ title: '售后原因', key: 'reason' },
|
||
{ title: '退款金额', key: 'refundAmount' },
|
||
{ title: '提成扣款', key: 'percentageDeductAmount' },
|
||
{ title: '解决方案', key: 'solution' },
|
||
{ title: '备注', key: 'remark' },
|
||
{ title: '失败原因', key: 'message' }
|
||
])
|
||
}
|
||
}
|
||
})
|
||
}
|
||
} finally {
|
||
uploading.value = false
|
||
getList()
|
||
}
|
||
}
|
||
|
||
const areaOptions = ref([])
|
||
function getOptions() {
|
||
// 区域
|
||
getAreaSimpleList().then((data) => {
|
||
areaOptions.value = data
|
||
})
|
||
getUserOption().then((data) => {
|
||
userOptions.value = data
|
||
})
|
||
}
|
||
onMounted(() => {
|
||
getOptions()
|
||
handleSearch()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped></style>
|