salary
qsh 5 months ago
parent e3c85cbaae
commit 5aab5c0f82
  1. 26
      src/api/clue/afterSale.js
  2. 10
      src/api/clue/payment.js
  3. 104
      src/views/Clue/Order/Comp/AfterSales.vue
  4. 122
      src/views/Clue/Order/Comp/DialogAfterSale.vue
  5. 101
      src/views/Clue/Order/Comp/DialogFeeback.vue
  6. 32
      src/views/Clue/Order/Comp/DialogOrder.vue
  7. 34
      src/views/Clue/Order/Comp/OrderList.vue
  8. 125
      src/views/Clue/Order/Comp/Reback.vue

@ -0,0 +1,26 @@
import request from '@/config/axios'
// 查询(精简)列表
export const getAfterSaleList = async (params) => {
return await request.get({ url: '/admin-api/crm/sign-after-sale/list', params })
}
// 查询(精简)列表
export const getAfterSalePage = async (params) => {
return await request.get({ url: '/admin-api/crm/sign-after-sale/page', params })
}
// 新增
export const createAfterSale = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-after-sale/create', data })
}
// 审核
export const auditAfterSale = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-after-sale/check', data })
}
// 撤销
export const cancelApplyAfterSale = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-after-sale/revoke', data })
}

@ -5,6 +5,11 @@ export const getPaymentList = async (params) => {
return await request.get({ url: '/admin-api/crm/sign-pay-record/list', params })
}
// 查询(精简)列表
export const getPaymentPage = async (params) => {
return await request.get({ url: '/admin-api/crm/sign-pay-record/page', params })
}
// 新增
export const createPayment = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-pay-record/create', data })
@ -14,3 +19,8 @@ export const createPayment = async (data) => {
export const auditPayment = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-pay-record/check', data })
}
// 撤销
export const cancelApplyPayment = async (data) => {
return await request.post({ url: '/admin-api/crm/sign-pay-record/revoke', data })
}

@ -2,13 +2,21 @@
<div>
<el-form :model="searchForm" label-width="0" inline>
<el-form-item>
<el-input v-model="searchForm.signId" placeholder="成交单号" />
<el-input v-model="searchForm.signId" placeholder="成交单号" clearable />
</el-form-item>
<el-form-item>
<el-input v-model="searchForm.name" placeholder="线索名称" />
<el-input v-model="searchForm.name" placeholder="线索名称" clearable />
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.dealUser" placeholder="登记人" clearable filterable>
<el-select v-model="searchForm.state" placeholder="审核状态" clearable>
<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>
<el-option
v-for="item in userOptions"
:key="item.id"
@ -27,7 +35,7 @@
/>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.createUser" placeholder="申请人" clearable filterable>
<el-select v-model="searchForm.applyUser" placeholder="申请人" clearable filterable>
<el-option
v-for="item in userOptions"
:key="item.id"
@ -38,7 +46,7 @@
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchForm.createDate"
v-model="searchForm.applyTime"
type="daterange"
range-separator="-"
start-placeholder="申请日期"
@ -53,28 +61,41 @@
</el-form>
<el-table :data="tableList" border>
<el-table-column prop="signId" label="成交单号" width="150px" />
<el-table-column prop="name" label="线索名称" width="120px" />
<el-table-column prop="phone" label="联系方式" width="150px" />
<el-table-column prop="signId" label="售后原因" width="150px" />
<el-table-column prop="signId" label="退款金额" width="90px" />
<el-table-column prop="signId" label="是否退货" width="90px" />
<el-table-column prop="signId" label="解决方案" width="150px" />
<el-table-column prop="signId" label="备注" width="200px" />
<el-table-column prop="signId" label="登记人" />
<el-table-column prop="signId" label="登记时间" width="150px" />
<el-table-column prop="signId" label="申请人" />
<el-table-column prop="signId" label="申请时间" width="150px" />
<el-table-column prop="signId" label="审核状态" fixed="right" width="90px" />
<el-table-column prop="signId" label="成交单号" min-width="150px" />
<el-table-column prop="name" label="线索名称" min-width="200px" />
<el-table-column prop="phone" label="联系方式" min-width="150px" />
<el-table-column prop="reason" label="售后原因" min-width="150px" />
<el-table-column prop="refundAmount" label="退款金额" min-width="90px" />
<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="150px" />
<el-table-column prop="applyUserName" label="申请人" min-width="90px" />
<el-table-column prop="applyTime" label="申请时间" min-width="150px" />
<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 @click="handleDetail(row.id)">
详情
</el-button>
<el-button type="primary" style="padding: 0" text @click="handleCancel(row.id)">
<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 @click="handleAudit(row.id)">
<el-button
type="primary"
style="padding: 0"
text
v-if="row.state == 1"
v-hasPermi="['clue:order:after-sale-audit']"
@click="handleAudit(row.id)"
>
审核
</el-button>
</template>
@ -90,10 +111,20 @@
</template>
<script setup name="AfterSales">
import * as AfterSaleApi from '@/api/clue/afterSale'
import { getSimpleUserList as getUserOption } from '@/api/system/user'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const message = useMessage() //
const currentUserId = userStore.getUser.id
const searchForm = ref({
signId: undefined,
name: undefined,
dealDate: [],
state: undefined,
dealUser: undefined,
createDate: [],
createUser: undefined,
@ -115,6 +146,7 @@ function handleReset() {
searchForm.value = {
signId: undefined,
name: undefined,
state: undefined,
dealDate: [],
dealUser: undefined,
createDate: [],
@ -124,8 +156,16 @@ function handleReset() {
}
}
function getList() {
tableList.value = [{ name: '测试' }]
const loading = ref(false)
async function getList() {
loading.value = true
try {
const data = await AfterSaleApi.getAfterSalePage(searchForm.value)
tableList.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
function batchAudit() {
@ -135,14 +175,30 @@ function batchAudit() {
function handleDetail(id) {
console.log(id)
}
function handleCancel(id) {
console.log(id)
async function handleCancel(id) {
try {
//
await message.confirm('是否确认撤销申请?')
//
await AfterSaleApi.cancelApplyAfterSale({ id })
message.success('撤销成功!')
//
await getList()
} catch (err) {
console.log(err)
}
}
function handleAudit(id) {
console.log(id)
}
function getOptions() {
getUserOption().then((data) => {
userOptions.value = data
})
}
onMounted(() => {
getOptions()
handleSearch()
})
</script>

@ -0,0 +1,122 @@
<template>
<Dialog title="售后记录" v-model="show" width="800px">
<el-table :data="aftersaleList" border stripe>
<el-table-column type="index" width="50" />
<el-table-column prop="reason" label="售后原因" />
<el-table-column prop="refundAmount" label="退款金额" />
<el-table-column prop="isReturns" label="是否退货" />
<el-table-column prop="applyTime" label="申请日期" width="180px" />
<el-table-column prop="stateName" label="审核状态" />
</el-table>
<el-divider direction="horizontal" />
<el-button v-show="showAdd" class="mb-10px" type="primary" @click="handleAdd">
新增售后
</el-button>
<el-form v-if="!showAdd" :model="form" ref="formRef" :rules="rules" label-width="80px">
<el-form-item label="退款原因" prop="reason">
<el-input v-model="form.reason" placeholder="请输入退款原因" />
</el-form-item>
<el-form-item label="退款金额" prop="refundAmount">
<el-input-number
v-model="form.refundAmount"
:min="0"
:controls="false"
placeholder="请输入金额"
/>
</el-form-item>
<el-form-item label="是否退货" prop="isReturns">
<el-radio-group v-model="form.isReturns">
<el-radio :label="true"> 退货 </el-radio>
<el-radio :label="false"> 不退货 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="解决方案" prop="solution">
<el-input
type="textarea"
:autoSize="{ minRows: 3 }"
v-model="form.solution"
placeholder="请输入退款原因"
/>
</el-form-item>
<el-form-item label="备注">
<Editor v-model:modelValue="form.remark" />
</el-form-item>
<el-form-item>
<el-button :disabled="formLoading" type="primary" @click="onSubmit">保存</el-button>
<el-button @click="showAdd = true">取消</el-button>
</el-form-item>
</el-form>
</Dialog>
</template>
<script setup name="DialogAfterSale">
import { getAfterSalePage, createAfterSale } from '@/api/clue/afterSale'
const message = useMessage() //
const show = ref(false)
const aftersaleList = ref([])
const orderId = ref('')
function open(signId) {
show.value = true
orderId.value = signId
try {
getList()
} catch (error) {
console.log(error)
}
}
const showAdd = ref(true)
const form = ref({})
const rules = {
refundAmount: { required: true, message: '回款金额不可为空', trigger: 'blur' },
reason: { required: true, message: '售后原因不可为空', trigger: 'blur' },
solution: { required: true, message: '解决方案不可为空', trigger: 'blur' }
}
function getList() {
getAfterSalePage({ signId: orderId.value, pageNo: 1, pageSize: 100 }).then((data) => {
aftersaleList.value = data.list
})
}
function handleAdd() {
showAdd.value = false
form.value = {
signId: orderId.value,
reason: undefined,
solution: undefined,
refundAmount: undefined,
isReturns: false,
remark: undefined
}
}
const formRef = ref()
const formLoading = ref(false)
async function onSubmit() {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
await createAfterSale(form.value)
message.success('申请成功!')
getList()
showAdd.value = true
} finally {
formLoading.value = false
}
}
defineExpose({
open
})
</script>
<style lang="scss" scoped></style>

@ -0,0 +1,101 @@
<template>
<Dialog title="回款记录" v-model="show" width="800px">
<el-table :data="feebackList" border stripe>
<el-table-column type="index" width="50" />
<el-table-column prop="money" label="回款金额" />
<el-table-column prop="applyTime" label="申请日期" />
<el-table-column prop="isPayoff" label="是否结清" />
<el-table-column prop="stateName" label="审核状态" />
</el-table>
<el-divider direction="horizontal" />
<el-button v-show="showAdd" class="mb-10px" type="primary" @click="handleAdd">
新增回款
</el-button>
<el-form v-if="!showAdd" :model="form" ref="formRef" :rules="rules" label-width="80px">
<el-form-item label="回款金额" prop="money">
<el-input-number v-model="form.money" :min="0" :controls="false" placeholder="请输入金额" />
</el-form-item>
<el-form-item label="是否结清" prop="isPayoff">
<el-radio-group v-model="form.isPayoff">
<el-radio label="结清"> 结清 </el-radio>
<el-radio label="未结清"> 未结清 </el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注">
<Editor v-model:modelValue="form.remark" />
</el-form-item>
<el-form-item>
<el-button :disabled="formLoading" type="primary" @click="onSubmit">保存</el-button>
<el-button @click="showAdd = true">取消</el-button>
</el-form-item>
</el-form>
</Dialog>
</template>
<script setup name="DialogFeeback">
import { getPaymentPage, createPayment } from '@/api/clue/payment'
const message = useMessage() //
const show = ref(false)
const feebackList = ref([])
const orderId = ref('')
function open(signId) {
show.value = true
orderId.value = signId
try {
getList()
} catch (error) {
console.log(error)
}
}
const showAdd = ref(true)
const form = ref({})
const rules = {
money: { required: true, message: '回款金额不可为空', trigger: 'blur' }
}
function getList() {
getPaymentPage({ signId: orderId.value, pageNo: 1, pageSize: 100 }).then((data) => {
feebackList.value = data.list
})
}
function handleAdd() {
showAdd.value = false
form.value = {
signId: orderId.value,
money: undefined,
isPayoff: '结清',
remark: undefined
}
}
const formRef = ref()
const formLoading = ref(false)
async function onSubmit() {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
await createPayment(form.value)
message.success('申请成功!')
getList()
showAdd.value = true
} finally {
formLoading.value = false
}
}
defineExpose({
open
})
</script>
<style lang="scss" scoped></style>

@ -15,13 +15,22 @@
</el-table>
</el-tab-pane>
<el-tab-pane label="回款记录" name="returnRecord">
<el-table :data="returnRecord" border stripe>
<el-table :data="returnRecordList" border stripe>
<el-table-column type="index" width="50" />
<el-table-column prop="money" label="回款金额" />
<el-table-column prop="" label="回款日期" />
<el-table-column prop="" label="是否结清" />
<el-table-column prop="remark" label="备注" />
<el-table-column prop="" label="审核状态" />
<el-table-column prop="applyTime" label="申请日期" />
<el-table-column prop="isPayoff" label="是否结清" />
<el-table-column prop="stateName" label="审核状态" />
</el-table>
</el-tab-pane>
<el-tab-pane label="售后记录" name="afterSale">
<el-table :data="aftersaleList" border stripe>
<el-table-column type="index" width="50" />
<el-table-column prop="reason" label="售后原因" />
<el-table-column prop="refundAmount" label="退款金额" />
<el-table-column prop="isReturns" label="是否退货" />
<el-table-column prop="applyTime" label="申请日期" width="180px" />
<el-table-column prop="stateName" label="审核状态" />
</el-table>
</el-tab-pane>
</el-tabs>
@ -34,7 +43,8 @@ import * as ClueApi from '@/api/clue'
import * as OrderApi from '@/api/clue/sign'
import { getSimpleFieldList as getClueFieldList } from '@/api/clue/clueField'
import { getSimpleFieldList as getOrderFieldList } from '@/api/clue/orderField'
import { getPaymentList } from '@/api/clue/payment'
import { getPaymentPage } from '@/api/clue/payment'
import { getAfterSalePage } from '@/api/clue/afterSale'
import { formatDate } from '@/utils/formatTime'
@ -42,7 +52,8 @@ const tabName = ref('clueInfo')
const show = ref(false)
const clueInfo = ref({})
const orderInfo = ref({})
const returnRecord = ref([])
const returnRecordList = ref([])
const aftersaleList = ref([])
function open(clueId, orderId) {
try {
@ -56,8 +67,11 @@ function open(clueId, orderId) {
orderInfo.value = { ...data, ...data.diyParams }
orderInfo.value.dealDate = formatDate(orderInfo.value.dealDate, 'YYYY-MM-DD HH:mm')
})
getPaymentList({ signId: orderId }).then((data) => {
returnRecord.value = data
getPaymentPage({ signId: orderId, pageNo: 1, pageSize: 100 }).then((data) => {
returnRecordList.value = data.list
})
getAfterSalePage({ signId: orderId, pageNo: 1, pageSize: 100 }).then((data) => {
aftersaleList.value = data.list
})
} catch (error) {
console.log(error)

@ -131,15 +131,6 @@
>
售后
</el-button>
<el-button
type="primary"
class="mr-10px"
link
style="padding: 0; margin-left: 0"
v-hasPermi="['clue:order:after-sale-audit']"
>
售后审核
</el-button>
<el-button
type="primary"
class="mr-10px"
@ -155,26 +146,20 @@
class="mr-10px"
link
style="padding: 0; margin-left: 0"
v-if="scope.row.isPayoff == '未结清'"
v-hasPermi="['clue:order:return']"
@click="feeBack(scope.row)"
>
回款
</el-button>
<el-button
type="primary"
class="mr-10px"
link
style="padding: 0; margin-left: 0"
v-hasPermi="['clue:order:return-audit']"
>
回款确认
</el-button>
</template>
</el-table-column>
</SSTable>
<!-- 详情 -->
<DialogOrder ref="orderDetailDialog" />
<DialogFeeback ref="feedbackDialog" />
<DialogAfterSale ref="afterSaleDialog" />
</div>
</template>
@ -187,6 +172,8 @@ import { getClassTypePage } from '@/api/school/class'
import { getSimpleProductList } from '@/api/mall/product'
import DialogOrder from './DialogOrder.vue'
import DialogFeeback from './DialogFeeback.vue'
import DialogAfterSale from './DialogAfterSale.vue'
import { removeNullField } from '@/utils'
import { useAppStore } from '@/store/modules/app'
@ -286,9 +273,16 @@ function handleDetail(row) {
orderDetailDialog.value.open(row.clueId, row.signId)
}
const feedbackDialog = ref()
const afterSaleDialog = ref()
//
function sellAfter() {
//
function sellAfter(row) {
afterSaleDialog.value.open(row.signId)
}
//
function feeBack(row) {
feedbackDialog.value.open(row.signId)
}
function changeSchool() {

@ -2,13 +2,21 @@
<div>
<el-form :model="searchForm" label-width="0" inline>
<el-form-item>
<el-input v-model="searchForm.signId" placeholder="成交单号" />
<el-input v-model="searchForm.signId" placeholder="成交单号" clearable />
</el-form-item>
<el-form-item>
<el-input v-model="searchForm.name" placeholder="线索名称" />
<el-input v-model="searchForm.name" placeholder="线索名称" clearable />
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.dealUser" placeholder="登记人" clearable filterable>
<el-select v-model="searchForm.state" placeholder="审核状态" clearable>
<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>
<el-option
v-for="item in userOptions"
:key="item.id"
@ -27,7 +35,7 @@
/>
</el-form-item>
<el-form-item>
<el-select v-model="searchForm.createUser" placeholder="申请人" clearable filterable>
<el-select v-model="searchForm.applyUser" placeholder="申请人" clearable filterable>
<el-option
v-for="item in userOptions"
:key="item.id"
@ -38,7 +46,7 @@
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchForm.createDate"
v-model="searchForm.applyTime"
type="daterange"
range-separator="-"
start-placeholder="申请日期"
@ -52,29 +60,42 @@
</el-form-item>
</el-form>
<el-table :data="tableList" border>
<el-table-column prop="signId" label="成交单号" width="150px" />
<el-table-column prop="name" label="线索名称" />
<el-table-column prop="phone" label="联系方式" width="150px" />
<el-table-column prop="signId" label="回款金额" />
<el-table-column prop="signId" label="是否结清" />
<el-table-column prop="signId" label="备注" width="200px" />
<el-table-column prop="signId" label="登记人" />
<el-table-column prop="signId" label="登记时间" width="150px" />
<el-table-column prop="signId" label="申请人" />
<el-table-column prop="signId" label="申请时间" width="150px" />
<el-table-column prop="signId" label="审核状态" fixed="right" />
<el-table v-loading="loading" :data="tableList" border>
<el-table-column prop="signId" label="成交单号" min-width="150px" />
<el-table-column prop="name" label="线索名称" min-width="200px" />
<el-table-column prop="phone" label="联系方式" min-width="150px" />
<el-table-column prop="money" label="回款金额" min-width="90" />
<el-table-column prop="isPayoff" label="是否结清" min-width="90" />
<el-table-column prop="signUserName" label="登记人" min-width="90" />
<el-table-column prop="dealDate" label="登记时间" min-width="150px" />
<el-table-column prop="applyUserName" label="申请人" min-width="90" />
<el-table-column prop="applyTime" label="申请时间" min-width="150px" />
<el-table-column prop="stateName" label="审核状态" fixed="right" min-width="90" />
<el-table-column label="操作" width="150px" fixed="right">
<template #default="{ row }">
<el-button type="primary" style="padding: 0" text @click="handleDetail(row.id)"
>详情</el-button
<el-button type="primary" style="padding: 0" text @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:return']"
@click="handleCancel(row.id)"
>
<el-button type="primary" style="padding: 0" text @click="handleCancel(row.id)"
>撤销</el-button
>
<el-button type="primary" style="padding: 0" text @click="handleAudit(row.id)"
>审核</el-button
撤销
</el-button>
<el-button
type="primary"
style="padding: 0"
text
v-if="row.state == 1"
v-hasPermi="['clue:order:return-audit']"
@click="handleAudit(row.id)"
>
审核
</el-button>
</template>
</el-table-column>
</el-table>
@ -88,13 +109,23 @@
</template>
<script setup name="Reback">
import * as FeebackApi from '@/api/clue/payment'
import { getSimpleUserList as getUserOption } from '@/api/system/user'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const message = useMessage() //
const currentUserId = userStore.getUser.id
const searchForm = ref({
signId: undefined,
name: undefined,
state: undefined,
dealDate: [],
dealUser: undefined,
createDate: [],
createUser: undefined,
signUser: undefined,
applyTime: [],
applyUser: undefined,
pageNo: 1,
pageSize: 20
})
@ -114,16 +145,25 @@ function handleReset() {
signId: undefined,
name: undefined,
dealDate: [],
dealUser: undefined,
createDate: [],
createUser: undefined,
state: undefined,
signUser: undefined,
applyTime: [],
applyUser: undefined,
pageNo: 1,
pageSize: 20
}
}
function getList() {
tableList.value = [{ name: '测试' }]
const loading = ref(false)
async function getList() {
loading.value = true
try {
const data = await FeebackApi.getPaymentPage(searchForm.value)
tableList.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
function batchAudit() {
@ -133,14 +173,31 @@ function batchAudit() {
function handleDetail(id) {
console.log(id)
}
function handleCancel(id) {
console.log(id)
async function handleCancel(id) {
try {
//
await message.confirm('是否确认撤销申请?')
//
await FeebackApi.cancelApplyPayment({ id })
message.success('撤销成功!')
//
await getList()
} catch (err) {
console.log(err)
}
}
function handleAudit(id) {
console.log(id)
}
function getOptions() {
getUserOption().then((data) => {
userOptions.value = data
})
}
onMounted(() => {
getOptions()
handleSearch()
})
</script>

Loading…
Cancel
Save