Merge remote-tracking branch 'origin/main' into dev-cl
This commit is contained in:
35
src/api/clue/afterSale.js
Normal file
35
src/api/clue/afterSale.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
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 batchAuditAfterSale = async (data) => {
|
||||||
|
return await request.post({ url: '/admin-api/crm/sign-after-sale/batch/check', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 撤销
|
||||||
|
export const cancelApplyAfterSale = async (data) => {
|
||||||
|
return await request.post({ url: '/admin-api/crm/sign-after-sale/revoke', params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询详情
|
||||||
|
export const getAfterSaleDetail = async (params) => {
|
||||||
|
return await request.get({ url: '/admin-api/crm/sign-after-sale/get', params })
|
||||||
|
}
|
||||||
@@ -49,3 +49,8 @@ export const getOpearateRecord = async (params) => {
|
|||||||
export const getPublicClue = async (data) => {
|
export const getPublicClue = async (data) => {
|
||||||
return await request.put({ url: '/admin-api/crm/sch-clue/public/save', data })
|
return await request.put({ url: '/admin-api/crm/sch-clue/public/save', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获得线索跟进用户信息
|
||||||
|
export const getFollowUserList = async (params) => {
|
||||||
|
return await request.get({ url: '/admin-api/crm/sch-clue/get-follow-user', params })
|
||||||
|
}
|
||||||
|
|||||||
35
src/api/clue/payment.js
Normal file
35
src/api/clue/payment.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// 查询(精简)列表
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审核
|
||||||
|
export const auditPayment = async (data) => {
|
||||||
|
return await request.post({ url: '/admin-api/crm/sign-pay-record/check', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const batchAuditPayment = async (data) => {
|
||||||
|
return await request.post({ url: '/admin-api/crm/sign-pay-record/batch/check', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 撤销
|
||||||
|
export const cancelApplyPayment = async (data) => {
|
||||||
|
return await request.post({ url: '/admin-api/crm/sign-pay-record/revoke', params: data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询详情
|
||||||
|
export const getPaymentDetail = async (params) => {
|
||||||
|
return await request.get({ url: '/admin-api/crm/sign-pay-record/get', params })
|
||||||
|
}
|
||||||
@@ -14,3 +14,8 @@ export const getSign = async (id) => {
|
|||||||
export const createSign = async (data) => {
|
export const createSign = async (data) => {
|
||||||
return await request.post({ url: '/admin-api/crm/sign/create', data: data })
|
return await request.post({ url: '/admin-api/crm/sign/create', data: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 取消登记
|
||||||
|
export const cancelDeal = async (id) => {
|
||||||
|
return await request.delete({ url: '/admin-api/crm/sign/delete?id=' + id })
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,5 +7,10 @@ export const getConfigByConfigKey = (params) => {
|
|||||||
|
|
||||||
// 保存配置项
|
// 保存配置项
|
||||||
export const updateConfig = (data) => {
|
export const updateConfig = (data) => {
|
||||||
return request.put({ url: '/admin-api/crm/config/update', data })
|
return request.put({ url: '/admin-api/crm/config/batchUpdateConfigValue', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据模块获取配置列表
|
||||||
|
export const getConfigList = (params) => {
|
||||||
|
return request.get({ url: '/admin-api/crm/config/query', params })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ const props = defineProps({
|
|||||||
data: {
|
data: {
|
||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
},
|
||||||
|
defaultShow: propTypes.bool.def(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
@@ -57,7 +58,7 @@ const getBindItemValue = (item: DescriptionsSchema) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 折叠
|
// 折叠
|
||||||
const show = ref(true)
|
const show = ref(props.defaultShow)
|
||||||
|
|
||||||
const toggleClick = () => {
|
const toggleClick = () => {
|
||||||
if (props.collapse) {
|
if (props.collapse) {
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export default defineComponent({
|
|||||||
// 表单label宽度
|
// 表单label宽度
|
||||||
labelWidth: propTypes.oneOfType([String, Number]).def('auto'),
|
labelWidth: propTypes.oneOfType([String, Number]).def('auto'),
|
||||||
// 是否 loading 数据中 add by 芋艿
|
// 是否 loading 数据中 add by 芋艿
|
||||||
vLoading: propTypes.bool.def(false)
|
vLoading: propTypes.bool.def(false),
|
||||||
|
inlineBlock: propTypes.bool.def(false)
|
||||||
},
|
},
|
||||||
emits: ['register'],
|
emits: ['register'],
|
||||||
setup(props, { slots, expose, emit }) {
|
setup(props, { slots, expose, emit }) {
|
||||||
@@ -289,6 +290,7 @@ export default defineComponent({
|
|||||||
model={props.isCustom ? props.model : formModel}
|
model={props.isCustom ? props.model : formModel}
|
||||||
class={prefixCls}
|
class={prefixCls}
|
||||||
v-loading={props.vLoading}
|
v-loading={props.vLoading}
|
||||||
|
style={props.inlineBlock ? 'display: inline' : ''}
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
// 如果需要自定义,就什么都不渲染,而是提供默认插槽
|
// 如果需要自定义,就什么都不渲染,而是提供默认插槽
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const props = defineProps({
|
|||||||
// 伸缩的界限字段
|
// 伸缩的界限字段
|
||||||
expandField: propTypes.string.def(''),
|
expandField: propTypes.string.def(''),
|
||||||
inline: propTypes.bool.def(true),
|
inline: propTypes.bool.def(true),
|
||||||
|
inlineBlock: propTypes.bool.def(false),
|
||||||
model: {
|
model: {
|
||||||
type: Object as PropType<Recordable>,
|
type: Object as PropType<Recordable>,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
@@ -154,6 +155,7 @@ initSearch()
|
|||||||
<!-- update by 芋艿:class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离,避免空隙过大 -->
|
<!-- update by 芋艿:class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离,避免空隙过大 -->
|
||||||
<Form
|
<Form
|
||||||
:inline="inline"
|
:inline="inline"
|
||||||
|
:inlineBlock="inlineBlock"
|
||||||
:is-col="isCol"
|
:is-col="isCol"
|
||||||
:is-custom="false"
|
:is-custom="false"
|
||||||
isSearch
|
isSearch
|
||||||
|
|||||||
@@ -1,18 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form :model="form" ref="formRef" label-width="auto">
|
<el-form :model="form" ref="formRef" label-width="auto">
|
||||||
<el-form-item>
|
<el-form-item v-if="getConfig('usePhoneConfig')">
|
||||||
<template #label>
|
<template #label>
|
||||||
<Tooltip message="请联系客服开通或关闭,客服电话:15955599959" />使用外呼
|
<Tooltip
|
||||||
|
v-if="getConfig('usePhoneConfig').remark"
|
||||||
|
:message="getConfig('usePhoneConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>使用外呼</span>
|
||||||
</template>
|
</template>
|
||||||
<el-radio-group v-model="form.callEnable" disabled>
|
<el-radio-group v-model="form.usePhoneConfig">
|
||||||
<el-radio :label="1"> 使用 </el-radio>
|
<el-radio
|
||||||
<el-radio :label="0"> 不使用 </el-radio>
|
v-for="(item, index) in getConfig('usePhoneConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="跟进信息">
|
<el-form-item v-if="getConfig('showFollowConfig')">
|
||||||
<el-radio-group v-model="form.followType">
|
<template #label>
|
||||||
<el-radio :label="1"> 展示所有 </el-radio>
|
<Tooltip
|
||||||
<el-radio :label="2"> 仅展示本人 </el-radio>
|
v-if="getConfig('showFollowConfig').remark"
|
||||||
|
:message="getConfig('showFollowConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>跟进信息</span>
|
||||||
|
</template>
|
||||||
|
<el-radio-group v-model="form.showFollowConfig">
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in getConfig('showFollowConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -23,23 +44,42 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="BasicSettingClue">
|
<script setup name="BasicSettingClue">
|
||||||
|
import * as ConfigApi from '@/api/system/set'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({})
|
||||||
followType: 1,
|
|
||||||
callEnable: 1
|
const configList = ref([])
|
||||||
})
|
|
||||||
|
function getConfig(val) {
|
||||||
|
return configList.value.find((it) => it.configKey == val)
|
||||||
|
}
|
||||||
|
|
||||||
function getData() {
|
function getData() {
|
||||||
form.value = {
|
ConfigApi.getConfigList({ module: 100 }).then((data) => {
|
||||||
followType: 1,
|
configList.value = data
|
||||||
callEnable: 1
|
// 获取所有配置项
|
||||||
}
|
data.map((it) => {
|
||||||
|
form.value[it.configKey] = it.configValue
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
message.success('保存成功')
|
const params = configList.value.map((it) => ({
|
||||||
|
configId: it.configId,
|
||||||
|
configKey: it.configKey,
|
||||||
|
configValue: form.value[it.configKey]
|
||||||
|
}))
|
||||||
|
ConfigApi.updateConfig(params).then(() => {
|
||||||
|
message.success('保存成功')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,16 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form :model="form" ref="formRef" label-width="auto">
|
<el-form :model="form" ref="formRef" label-width="auto">
|
||||||
<el-form-item label="是否关联成交率">
|
<el-form-item v-if="getConfig('saleCommissionRelateDealConfig')">
|
||||||
<el-radio-group v-model="form.withSuccess">
|
<template #label>
|
||||||
<el-radio :label="1"> 是 </el-radio>
|
<Tooltip
|
||||||
<el-radio :label="0"> 否 </el-radio>
|
v-if="getConfig('saleCommissionRelateDealConfig').remark"
|
||||||
|
:message="getConfig('saleCommissionRelateDealConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>是否关联成交率</span>
|
||||||
|
</template>
|
||||||
|
<el-radio-group
|
||||||
|
v-model="form.saleCommissionRelateDealConfig"
|
||||||
|
@change="form.saleCommissionRelateRulesConfig = []"
|
||||||
|
>
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in getConfig('saleCommissionRelateDealConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="关联规则" v-if="form.withSuccess">
|
<el-form-item label="关联规则" v-if="form.saleCommissionRelateDealConfig == 'true'">
|
||||||
<div>
|
<div>
|
||||||
<el-button @click="form.rules.push({})">新增规则</el-button>
|
<el-button @click="form.saleCommissionRelateRulesConfig.push({})">新增规则</el-button>
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in form.rules"
|
v-for="(item, index) in form.saleCommissionRelateRulesConfig"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="mt-10px flex justify-center items-center"
|
class="mt-10px flex justify-center items-center"
|
||||||
>
|
>
|
||||||
@@ -48,22 +63,52 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="BasicSettingClue">
|
<script setup name="BasicSettingClue">
|
||||||
|
import * as ConfigApi from '@/api/system/set'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({})
|
||||||
withSuccess: 1,
|
const configList = ref([])
|
||||||
rules: []
|
|
||||||
})
|
const jsonArr = ['saleCommissionRelateRulesConfig']
|
||||||
|
|
||||||
|
function getConfig(val) {
|
||||||
|
return configList.value.find((it) => it.configKey == val)
|
||||||
|
}
|
||||||
|
|
||||||
function getData() {
|
function getData() {
|
||||||
form.value = {
|
ConfigApi.getConfigList({ module: 101 }).then((data) => {
|
||||||
withSuccess: 1
|
configList.value = data
|
||||||
}
|
// 获取所有配置项
|
||||||
|
data.map((it) => {
|
||||||
|
form.value[it.configKey] = it.configValue
|
||||||
|
if (it.configKey == 'saleCommissionRelateRulesConfig') {
|
||||||
|
if (!form.value[it.configKey]) {
|
||||||
|
form.value[it.configKey] = []
|
||||||
|
} else {
|
||||||
|
form.value[it.configKey] = JSON.parse(it.configValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
message.success('保存成功')
|
const params = configList.value.map((it) => ({
|
||||||
|
configId: it.configId,
|
||||||
|
configKey: it.configKey,
|
||||||
|
configValue: jsonArr.includes(it.configKey)
|
||||||
|
? JSON.stringify(form.value[it.configKey])
|
||||||
|
: form.value[it.configKey]
|
||||||
|
}))
|
||||||
|
ConfigApi.updateConfig(params).then(() => {
|
||||||
|
message.success('保存成功')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
236
src/views/Clue/Order/Comp/AfterSales.vue
Normal file
236
src/views/Clue/Order/Comp/AfterSales.vue
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form :model="searchForm" label-width="0" inline>
|
||||||
|
<el-form-item>
|
||||||
|
<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>
|
||||||
|
<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"
|
||||||
|
: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="登记日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="searchForm.applyUser" placeholder="申请人" clearable filterable>
|
||||||
|
<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="申请日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleSearch">查询</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
<el-button @click="batchAudit">批量审核</el-button>
|
||||||
|
</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 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
|
||||||
|
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 { useUserStore } from '@/store/modules/user'
|
||||||
|
|
||||||
|
import DialogAfterSaleAudit from './DialogAfterSaleAudit.vue'
|
||||||
|
import DialogAfterSaleDetail from './DialogAfterSaleDetail.vue'
|
||||||
|
import DialogBatchAudit from './DialogBatchAudit.vue'
|
||||||
|
|
||||||
|
const afterSaleAuditDialog = ref()
|
||||||
|
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOptions() {
|
||||||
|
getUserOption().then((data) => {
|
||||||
|
userOptions.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
getOptions()
|
||||||
|
handleSearch()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
0
src/views/Clue/Order/Comp/Delivery.vue
Normal file
0
src/views/Clue/Order/Comp/Delivery.vue
Normal file
122
src/views/Clue/Order/Comp/DialogAfterSale.vue
Normal file
122
src/views/Clue/Order/Comp/DialogAfterSale.vue
Normal file
@@ -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>
|
||||||
135
src/views/Clue/Order/Comp/DialogAfterSaleAudit.vue
Normal file
135
src/views/Clue/Order/Comp/DialogAfterSaleAudit.vue
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
|
||||||
|
<Descriptions :data="orderInfo" :schema="schema" :columns="2" labelWidth="130px" />
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="状态" prop="state">
|
||||||
|
<el-radio-group v-model="formData.state">
|
||||||
|
<el-radio :label="3"> 通过 </el-radio>
|
||||||
|
<el-radio :label="4"> 驳回 </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<Editor v-model:modelValue="formData.remark" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script name="DialogAfterSaleAudit" setup>
|
||||||
|
import { auditAfterSale } from '@/api/clue/afterSale'
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
|
||||||
|
const schema = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '线索名称',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'phone',
|
||||||
|
label: '联系方式',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'signUserName',
|
||||||
|
label: '登记人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dealDate',
|
||||||
|
label: '登记时间',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'reason',
|
||||||
|
label: '售后原因',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'solution',
|
||||||
|
label: '解决方案',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'refundAmount',
|
||||||
|
label: '退款金额',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isReturns',
|
||||||
|
label: '是否退货',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyUserName',
|
||||||
|
label: '申请人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyTime',
|
||||||
|
label: '申请时间',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
const orderInfo = ref({})
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (row) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '售后审核'
|
||||||
|
resetForm(row.id)
|
||||||
|
// 修改时,设置数据
|
||||||
|
orderInfo.value = { ...row }
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef.value) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
await auditAfterSale(formData.value)
|
||||||
|
message.success('审核完成!')
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = (signId) => {
|
||||||
|
formData.value = {
|
||||||
|
saleId: signId,
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
137
src/views/Clue/Order/Comp/DialogAfterSaleDetail.vue
Normal file
137
src/views/Clue/Order/Comp/DialogAfterSaleDetail.vue
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
|
||||||
|
<Descriptions
|
||||||
|
title="申请详情"
|
||||||
|
:data="orderInfo"
|
||||||
|
:schema="applySchema"
|
||||||
|
:columns="2"
|
||||||
|
labelWidth="130px"
|
||||||
|
/>
|
||||||
|
<Descriptions
|
||||||
|
title="审核详情"
|
||||||
|
:data="orderInfo"
|
||||||
|
:schema="orderInfo.state == 2 ? cancelSchema : auditSchema"
|
||||||
|
:columns="orderInfo.state == 2 ? 2 : 3"
|
||||||
|
labelWidth="100px"
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script name="DialogAfterSaleDetail" setup>
|
||||||
|
import { getAfterSaleDetail } from '@/api/clue/afterSale'
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
|
||||||
|
const applySchema = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '线索名称',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'phone',
|
||||||
|
label: '联系方式',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'signUserName',
|
||||||
|
label: '登记人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dealDate',
|
||||||
|
label: '登记时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'reason',
|
||||||
|
label: '售后原因',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'refundAmount',
|
||||||
|
label: '退款金额',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isReturns',
|
||||||
|
label: '是否退货',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'solution',
|
||||||
|
label: '解决方案',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyUserName',
|
||||||
|
label: '申请人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyTime',
|
||||||
|
label: '申请时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const auditSchema = [
|
||||||
|
{
|
||||||
|
field: 'stateName',
|
||||||
|
label: '审核状态',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkUser',
|
||||||
|
label: '审核人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkTime',
|
||||||
|
label: '审核时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkRemark',
|
||||||
|
label: '备注',
|
||||||
|
span: 3,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const cancelSchema = [
|
||||||
|
{
|
||||||
|
field: 'stateName',
|
||||||
|
label: '审核状态',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'revokeTime',
|
||||||
|
label: '撤销时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const orderInfo = ref({})
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (id) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '售后申请详情'
|
||||||
|
try {
|
||||||
|
orderInfo.value = await getAfterSaleDetail({ id })
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
</script>
|
||||||
87
src/views/Clue/Order/Comp/DialogBatchAudit.vue
Normal file
87
src/views/Clue/Order/Comp/DialogBatchAudit.vue
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="状态" prop="state">
|
||||||
|
<el-radio-group v-model="formData.state">
|
||||||
|
<el-radio :label="3"> 通过 </el-radio>
|
||||||
|
<el-radio :label="4"> 驳回 </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<Editor v-model:modelValue="formData.remark" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script name="DialogAfterSaleAudit" setup>
|
||||||
|
import { batchAuditAfterSale } from '@/api/clue/afterSale'
|
||||||
|
import { batchAuditPayment } from '@/api/clue/payment'
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
const formType = ref('aftersale')
|
||||||
|
const titleMap = {
|
||||||
|
aftersale: '批量售后审核',
|
||||||
|
feeback: '批量回款审核'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = (type, ids) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
formType.value = type
|
||||||
|
dialogTitle.value = titleMap[type] || '批量审核'
|
||||||
|
resetForm(ids)
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef.value) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
if (formType.value == 'aftersale') {
|
||||||
|
await batchAuditAfterSale(formData.value)
|
||||||
|
message.success('审核完成!')
|
||||||
|
} else if (formType.value == 'feeback') {
|
||||||
|
await batchAuditPayment(formData.value)
|
||||||
|
message.success('审核完成!')
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = (ids) => {
|
||||||
|
formData.value = {
|
||||||
|
payIds: ids,
|
||||||
|
saleIds: ids,
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
101
src/views/Clue/Order/Comp/DialogFeeback.vue
Normal file
101
src/views/Clue/Order/Comp/DialogFeeback.vue
Normal file
@@ -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="true"> 结清 </el-radio>
|
||||||
|
<el-radio :label="false"> 未结清 </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: true,
|
||||||
|
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>
|
||||||
125
src/views/Clue/Order/Comp/DialogFeebackAudit.vue
Normal file
125
src/views/Clue/Order/Comp/DialogFeebackAudit.vue
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
|
||||||
|
<Descriptions :data="orderInfo" :schema="schema" :columns="2" labelWidth="130px" />
|
||||||
|
<el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="状态" prop="state">
|
||||||
|
<el-radio-group v-model="formData.state">
|
||||||
|
<el-radio :label="3"> 通过 </el-radio>
|
||||||
|
<el-radio :label="4"> 驳回 </el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<Editor v-model:modelValue="formData.remark" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script name="DialogFeebackAudit" setup>
|
||||||
|
import { auditPayment } from '@/api/clue/payment'
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
|
||||||
|
const schema = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '线索名称',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'phone',
|
||||||
|
label: '联系方式',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'signUserName',
|
||||||
|
label: '登记人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dealDate',
|
||||||
|
label: '登记时间',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'money',
|
||||||
|
label: '回款金额',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isPayoff',
|
||||||
|
label: '是否结清',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyUserName',
|
||||||
|
label: '申请人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyTime',
|
||||||
|
label: '申请时间',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formData = ref({
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
const orderInfo = ref({})
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (row) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '回款审核'
|
||||||
|
resetForm(row.id)
|
||||||
|
// 修改时,设置数据
|
||||||
|
orderInfo.value = { ...row }
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef.value) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
await auditPayment(formData.value)
|
||||||
|
message.success('审核完成!')
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = (signId) => {
|
||||||
|
formData.value = {
|
||||||
|
payId: signId,
|
||||||
|
state: 3,
|
||||||
|
remark: ''
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
127
src/views/Clue/Order/Comp/DialogFeebackDetail.vue
Normal file
127
src/views/Clue/Order/Comp/DialogFeebackDetail.vue
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible" width="900px">
|
||||||
|
<Descriptions
|
||||||
|
title="申请详情"
|
||||||
|
:data="orderInfo"
|
||||||
|
:schema="applySchema"
|
||||||
|
:columns="2"
|
||||||
|
labelWidth="130px"
|
||||||
|
/>
|
||||||
|
<Descriptions
|
||||||
|
title="审核详情"
|
||||||
|
:data="orderInfo"
|
||||||
|
:schema="orderInfo.state == 2 ? cancelSchema : auditSchema"
|
||||||
|
:columns="orderInfo.state == 2 ? 2 : 3"
|
||||||
|
labelWidth="100px"
|
||||||
|
/>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script name="DialogFeebackDetail" setup>
|
||||||
|
import { getPaymentDetail } from '@/api/clue/payment'
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
|
||||||
|
const applySchema = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '线索名称',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'phone',
|
||||||
|
label: '联系方式',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'signUserName',
|
||||||
|
label: '登记人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dealDate',
|
||||||
|
label: '登记时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'money',
|
||||||
|
label: '回款金额',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'isPayoff',
|
||||||
|
label: '是否结清',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyUserName',
|
||||||
|
label: '申请人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'applyTime',
|
||||||
|
label: '申请时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const auditSchema = [
|
||||||
|
{
|
||||||
|
field: 'stateName',
|
||||||
|
label: '审核状态',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkUser',
|
||||||
|
label: '审核人',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkTime',
|
||||||
|
label: '审核时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'checkRemark',
|
||||||
|
label: '备注',
|
||||||
|
span: 3,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const cancelSchema = [
|
||||||
|
{
|
||||||
|
field: 'stateName',
|
||||||
|
label: '审核状态',
|
||||||
|
span: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'revokeTime',
|
||||||
|
label: '撤销时间',
|
||||||
|
dateFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const orderInfo = ref({})
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (id) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '回款申请详情'
|
||||||
|
try {
|
||||||
|
orderInfo.value = await getPaymentDetail({ id })
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
</script>
|
||||||
121
src/views/Clue/Order/Comp/DialogOrder.vue
Normal file
121
src/views/Clue/Order/Comp/DialogOrder.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog title="成交详情" v-model="show" width="800px">
|
||||||
|
<el-tabs v-model="tabName">
|
||||||
|
<el-tab-pane label="线索信息" name="clueInfo">
|
||||||
|
<Descriptions :data="clueInfo" :schema="clueSchema" :columns="2" labelWidth="130px" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="成交信息" name="orderInfo">
|
||||||
|
<Descriptions :data="orderInfo" :schema="orderSchema" :columns="2" labelWidth="130px" />
|
||||||
|
<el-divider direction="horizontal" content-position="left">额外支出</el-divider>
|
||||||
|
<el-table :data="orderInfo.extraPay" border stripe>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<el-table-column prop="extraPayType" label="额外支出项" />
|
||||||
|
<el-table-column prop="extraPayMoney" label="支出金额" />
|
||||||
|
<el-table-column prop="remark" label="备注" />
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="回款记录" name="returnRecord">
|
||||||
|
<el-table :data="returnRecordList" 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-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>
|
||||||
|
<div class="mb-15px"></div>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="DialogOrder">
|
||||||
|
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 { getPaymentPage } from '@/api/clue/payment'
|
||||||
|
import { getAfterSalePage } from '@/api/clue/afterSale'
|
||||||
|
|
||||||
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
|
||||||
|
const tabName = ref('clueInfo')
|
||||||
|
const show = ref(false)
|
||||||
|
const clueInfo = ref({})
|
||||||
|
const orderInfo = ref({})
|
||||||
|
const returnRecordList = ref([])
|
||||||
|
const aftersaleList = ref([])
|
||||||
|
|
||||||
|
function open(clueId, orderId) {
|
||||||
|
try {
|
||||||
|
show.value = true
|
||||||
|
tabName.value = 'clueInfo'
|
||||||
|
getFields()
|
||||||
|
ClueApi.getClue(clueId).then((data) => {
|
||||||
|
clueInfo.value = { ...data, ...data.diyParams }
|
||||||
|
})
|
||||||
|
OrderApi.getSign(orderId).then((data) => {
|
||||||
|
orderInfo.value = { ...data, ...data.diyParams }
|
||||||
|
orderInfo.value.dealDate = formatDate(orderInfo.value.dealDate, 'YYYY-MM-DD HH:mm')
|
||||||
|
})
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const clueSchema = ref([])
|
||||||
|
const orderSchema = ref([])
|
||||||
|
function getFields() {
|
||||||
|
getClueFieldList().then((data) => {
|
||||||
|
const arr = useCrudSchemas(data).allSchemas.detailSchema
|
||||||
|
clueSchema.value = [
|
||||||
|
...arr,
|
||||||
|
{
|
||||||
|
field: 'requirement',
|
||||||
|
label: '诉求',
|
||||||
|
span: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
getOrderFieldList().then((data) => {
|
||||||
|
const arr = useCrudSchemas(data).allSchemas.detailSchema
|
||||||
|
orderSchema.value = [
|
||||||
|
...arr,
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: '备注',
|
||||||
|
span: 2,
|
||||||
|
isEditor: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
367
src/views/Clue/Order/Comp/OrderList.vue
Normal file
367
src/views/Clue/Order/Comp/OrderList.vue
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<div>
|
||||||
|
<el-form
|
||||||
|
:model="searchForm"
|
||||||
|
ref="moreSearchRef"
|
||||||
|
inline
|
||||||
|
label-width="0"
|
||||||
|
style="display: inline"
|
||||||
|
>
|
||||||
|
<template v-if="appStore.getAppInfo?.instanceType == 1">
|
||||||
|
<el-form-item style="margin-bottom: 10px">
|
||||||
|
<el-select
|
||||||
|
v-model="searchForm.signSchool"
|
||||||
|
placeholder="选择驾校"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
@change="changeSchool"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in schoolOptions"
|
||||||
|
:key="item.schoolId"
|
||||||
|
:label="item.schoolName"
|
||||||
|
:value="item.schoolId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="margin-bottom: 10px">
|
||||||
|
<el-select
|
||||||
|
v-model="searchForm.signPlace"
|
||||||
|
placeholder="选择场地"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
:disabled="!searchForm.signSchool"
|
||||||
|
@change="changePlace"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in placeOptions"
|
||||||
|
:key="item.placeId"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.placeId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="margin-bottom: 10px">
|
||||||
|
<el-select
|
||||||
|
v-model="searchForm.signClass"
|
||||||
|
:disabled="!searchForm.signPlace"
|
||||||
|
placeholder="选择班型"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in classOptions"
|
||||||
|
:key="item.typeId"
|
||||||
|
:label="item.typeName"
|
||||||
|
:value="item.typeId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="appStore.getAppInfo?.instanceType == 2">
|
||||||
|
<el-form-item>
|
||||||
|
<el-select
|
||||||
|
v-model="searchForm.signProduct"
|
||||||
|
placeholder="选择成交产品"
|
||||||
|
filterable
|
||||||
|
@change="searchForm.specsId = undefined"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in prodOptions"
|
||||||
|
:key="item.productId"
|
||||||
|
:label="item.productName"
|
||||||
|
:value="item.productId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select
|
||||||
|
v-model="searchForm.specsId"
|
||||||
|
placeholder="选择规格"
|
||||||
|
filterable
|
||||||
|
:disabled="!searchForm.signProduct"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in specsOptions(searchForm.signProduct)"
|
||||||
|
:key="item.specsId"
|
||||||
|
:label="item.specsName"
|
||||||
|
:value="item.specsId"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-form>
|
||||||
|
<Search
|
||||||
|
v-if="!loading"
|
||||||
|
ref="searchRef"
|
||||||
|
:schema="allSchemas.searchSchema"
|
||||||
|
inlineBlock
|
||||||
|
labelWidth="0"
|
||||||
|
>
|
||||||
|
<template #actionMore>
|
||||||
|
<el-button @click="getTableList" v-hasPermi="['clue:order:search']"> 搜索 </el-button>
|
||||||
|
<el-button @click="resetQuery" v-hasPermi="['clue:order:reset']"> 重置 </el-button>
|
||||||
|
</template>
|
||||||
|
</Search>
|
||||||
|
</div>
|
||||||
|
<!-- 列表 -->
|
||||||
|
<SSTable
|
||||||
|
v-if="!loading"
|
||||||
|
class="mt-10px"
|
||||||
|
v-model:tableObject="tableObject"
|
||||||
|
:tableColumns="allSchemas.tableColumns"
|
||||||
|
@get-list="getTableList"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
v-for="item in allSchemas.tableColumns"
|
||||||
|
:key="item.field"
|
||||||
|
:prop="item.field"
|
||||||
|
:label="item.label"
|
||||||
|
min-width="120px"
|
||||||
|
/>
|
||||||
|
<el-table-column label="操作" width="240px" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="mr-10px"
|
||||||
|
link
|
||||||
|
style="padding: 0; margin-left: 0"
|
||||||
|
v-hasPermi="['clue:order:detail']"
|
||||||
|
@click="handleDetail(scope.row)"
|
||||||
|
>
|
||||||
|
详情
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="mr-10px"
|
||||||
|
link
|
||||||
|
style="padding: 0; margin-left: 0"
|
||||||
|
v-hasPermi="['clue:order:after-sale']"
|
||||||
|
@click="sellAfter(scope.row)"
|
||||||
|
>
|
||||||
|
售后
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="mr-10px"
|
||||||
|
link
|
||||||
|
v-if="appStore.getAppInfo?.instanceType == 2"
|
||||||
|
style="padding: 0; margin-left: 0"
|
||||||
|
v-hasPermi="['clue:order:send']"
|
||||||
|
>
|
||||||
|
发货
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
class="mr-10px"
|
||||||
|
link
|
||||||
|
style="padding: 0; margin-left: 0"
|
||||||
|
v-if="scope.row.isPayoff == false"
|
||||||
|
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:pool:enroll']"
|
||||||
|
@click="cancelDeal(scope.row)"
|
||||||
|
>
|
||||||
|
取消登记
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</SSTable>
|
||||||
|
|
||||||
|
<!-- 详情 -->
|
||||||
|
<DialogOrder ref="orderDetailDialog" />
|
||||||
|
<DialogFeeback ref="feedbackDialog" />
|
||||||
|
<DialogAfterSale ref="afterSaleDialog" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ClueOrderList">
|
||||||
|
import { getSimpleFieldList } from '@/api/clue/orderField'
|
||||||
|
import * as SignApi from '@/api/clue/sign'
|
||||||
|
import { getSimpleUserList as getUserOption } from '@/api/system/user'
|
||||||
|
import { getPlaceList } from '@/api/school/place'
|
||||||
|
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'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const allSchemas = ref({})
|
||||||
|
|
||||||
|
const orderDetailDialog = ref()
|
||||||
|
const searchRef = ref()
|
||||||
|
const schoolOptions = ref([])
|
||||||
|
const allPlaceOptions = ref([])
|
||||||
|
const prodOptions = ref([])
|
||||||
|
|
||||||
|
const specsOptions = computed({
|
||||||
|
get() {
|
||||||
|
return (prodId) => {
|
||||||
|
if (prodId) {
|
||||||
|
return prodOptions.value.find((it) => it.productId == prodId).productSpecList
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const searchForm = ref({
|
||||||
|
signSchool: undefined,
|
||||||
|
signPlace: undefined,
|
||||||
|
signClass: undefined,
|
||||||
|
signProduct: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableObject = ref({
|
||||||
|
tableList: [],
|
||||||
|
loading: false,
|
||||||
|
total: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
currentPage: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
const placeOptions = computed(() => {
|
||||||
|
return allPlaceOptions.value.filter((it) => it.schoolId == searchForm.value.signSchool)
|
||||||
|
})
|
||||||
|
|
||||||
|
function resetQuery() {
|
||||||
|
searchForm.value = {
|
||||||
|
signSchool: undefined,
|
||||||
|
signPlace: undefined,
|
||||||
|
signClass: undefined,
|
||||||
|
signProduct: undefined
|
||||||
|
}
|
||||||
|
searchRef.value.reset()
|
||||||
|
tableObject.value.currentPage = 1
|
||||||
|
getTableList()
|
||||||
|
}
|
||||||
|
// 查询
|
||||||
|
async function getTableList() {
|
||||||
|
// 查询
|
||||||
|
tableObject.value.loading = true
|
||||||
|
try {
|
||||||
|
const queryParams = await searchRef.value.getFormModel()
|
||||||
|
const params = {
|
||||||
|
...queryParams,
|
||||||
|
...searchForm.value,
|
||||||
|
pageNo: tableObject.value.currentPage,
|
||||||
|
pageSize: tableObject.value.pageSize
|
||||||
|
}
|
||||||
|
const data = await SignApi.getSignPage(removeNullField(params))
|
||||||
|
tableObject.value.tableList = data.list.map((it) => ({ ...it, ...it.diyParams }))
|
||||||
|
tableObject.value.total = data.total
|
||||||
|
} finally {
|
||||||
|
tableObject.value.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
async function getCurdSchemas() {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await getSimpleFieldList()
|
||||||
|
data.forEach((elem) => {
|
||||||
|
if (elem.field == 'createUser') {
|
||||||
|
elem.search.options = userOptions.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
allSchemas.value = useCrudSchemas(data).allSchemas
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
nextTick(() => {
|
||||||
|
getTableList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情
|
||||||
|
function handleDetail(row) {
|
||||||
|
orderDetailDialog.value.open(row.clueId, row.signId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const feedbackDialog = ref()
|
||||||
|
const afterSaleDialog = ref()
|
||||||
|
// 售后
|
||||||
|
function sellAfter(row) {
|
||||||
|
afterSaleDialog.value.open(row.signId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回款
|
||||||
|
function feeBack(row) {
|
||||||
|
feedbackDialog.value.open(row.signId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消登记
|
||||||
|
async function cancelDeal(row) {
|
||||||
|
try {
|
||||||
|
// 二次确认
|
||||||
|
await message.confirm('是否确认取消登记该线索?')
|
||||||
|
// 发起删除
|
||||||
|
await SignApi.cancelDeal(row.signId)
|
||||||
|
message.success('取消登记成功!')
|
||||||
|
// 刷新列表
|
||||||
|
await getTableList()
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSchool() {
|
||||||
|
searchForm.value.signPlace = undefined
|
||||||
|
searchForm.value.signClass = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function changePlace() {
|
||||||
|
searchForm.value.signClass = undefined
|
||||||
|
getClassTypeOptions()
|
||||||
|
}
|
||||||
|
|
||||||
|
const classOptions = ref([])
|
||||||
|
async function getClassTypeOptions() {
|
||||||
|
const data = await getClassTypePage({ placeId: searchForm.value.signPlace })
|
||||||
|
classOptions.value = data.list
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOptions() {
|
||||||
|
if (appStore.getAppInfo?.instanceType == 1) {
|
||||||
|
// 驾校
|
||||||
|
getPlaceList().then((data) => {
|
||||||
|
schoolOptions.value = data.schoolList
|
||||||
|
allPlaceOptions.value = data.placeList
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 产品
|
||||||
|
getSimpleProductList().then((data) => {
|
||||||
|
prodOptions.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const userOptions = ref([])
|
||||||
|
onMounted(() => {
|
||||||
|
getUserOption().then((data) => {
|
||||||
|
userOptions.value = data
|
||||||
|
getCurdSchemas()
|
||||||
|
})
|
||||||
|
getOptions()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
236
src/views/Clue/Order/Comp/Reback.vue
Normal file
236
src/views/Clue/Order/Comp/Reback.vue
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-form :model="searchForm" label-width="0" inline>
|
||||||
|
<el-form-item>
|
||||||
|
<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>
|
||||||
|
<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"
|
||||||
|
: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="登记日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-select v-model="searchForm.applyUser" placeholder="申请人" clearable filterable>
|
||||||
|
<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="申请日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleSearch">查询</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
<el-button @click="batchAudit">批量审核</el-button>
|
||||||
|
</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 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
|
||||||
|
v-if="row.state == 1 && currentUserId == row.applyUser"
|
||||||
|
v-hasPermi="['clue:order:return']"
|
||||||
|
@click="handleCancel(row.id)"
|
||||||
|
>
|
||||||
|
撤销
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
style="padding: 0"
|
||||||
|
text
|
||||||
|
v-if="row.state == 1"
|
||||||
|
v-hasPermi="['clue:order:return-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"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DialogFeebackAudit ref="feebackDialog" @success="getList" />
|
||||||
|
<DialogFeebackDetail ref="feebackDetailDialog" />
|
||||||
|
<DialogBatchAudit ref="batchAuditDialog" @success="getList" />
|
||||||
|
</div>
|
||||||
|
</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'
|
||||||
|
|
||||||
|
import DialogFeebackAudit from './DialogFeebackAudit.vue'
|
||||||
|
import DialogFeebackDetail from './DialogFeebackDetail.vue'
|
||||||
|
import DialogBatchAudit from './DialogBatchAudit.vue'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const feebackDialog = ref()
|
||||||
|
|
||||||
|
const currentUserId = userStore.getUser.id
|
||||||
|
|
||||||
|
const searchForm = ref({
|
||||||
|
signId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
state: undefined,
|
||||||
|
dealDate: [],
|
||||||
|
signUser: undefined,
|
||||||
|
applyTime: [],
|
||||||
|
applyUser: 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,
|
||||||
|
dealDate: [],
|
||||||
|
state: undefined,
|
||||||
|
signUser: undefined,
|
||||||
|
applyTime: [],
|
||||||
|
applyUser: undefined,
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 feebackDetailDialog = ref()
|
||||||
|
function handleDetail(id) {
|
||||||
|
feebackDetailDialog.value.open(id)
|
||||||
|
}
|
||||||
|
async function handleCancel(id) {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.confirm('是否确认撤销申请?')
|
||||||
|
// 发起删除
|
||||||
|
await FeebackApi.cancelApplyPayment({ id })
|
||||||
|
message.success('撤销成功!')
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleAudit(row) {
|
||||||
|
feebackDialog.value.open(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOptions() {
|
||||||
|
getUserOption().then((data) => {
|
||||||
|
userOptions.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getOptions()
|
||||||
|
handleSearch()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@@ -1,104 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<el-tabs v-model="tabName">
|
||||||
<!-- 搜索工作栏 -->
|
<el-tab-pane label="成交列表" name="list">
|
||||||
<Search :schema="allSchemas.searchSchema" labelWidth="0">
|
<OrderList v-if="tabName == 'list'" />
|
||||||
<template #actionMore>
|
</el-tab-pane>
|
||||||
<el-button @click="getTableList" v-hasPermi="['clue:order:search']"> 搜索 </el-button>
|
<el-tab-pane label="回款申请" name="commission">
|
||||||
<el-button @click="resetQuery" v-hasPermi="['clue:order:reset']"> 重置 </el-button>
|
<Reback v-if="tabName == 'commission'" />
|
||||||
</template>
|
</el-tab-pane>
|
||||||
</Search>
|
<el-tab-pane label="售后申请" name="aftersale">
|
||||||
<!-- 列表 -->
|
<AfterSales v-if="tabName == 'aftersale'" />
|
||||||
<SSTable
|
</el-tab-pane>
|
||||||
class="mt-20px"
|
<el-tab-pane label="发货列表" name="delivery" v-if="appStore.getAppInfo?.instanceType == 2">
|
||||||
v-model:tableObject="tableObject"
|
<OrderList v-if="tabName == 'delivery'" />
|
||||||
:tableColumns="allSchemas.tableColumns"
|
</el-tab-pane>
|
||||||
@get-list="getTableList"
|
</el-tabs>
|
||||||
>
|
|
||||||
<el-table-column
|
|
||||||
v-for="item in allSchemas.tableColumns"
|
|
||||||
:key="item.field"
|
|
||||||
:prop="item.field"
|
|
||||||
:label="item.label"
|
|
||||||
min-width="120px"
|
|
||||||
/>
|
|
||||||
<el-table-column label="操作" width="200px" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
class="mr-10px"
|
|
||||||
link
|
|
||||||
style="padding: 0; margin-left: 0"
|
|
||||||
v-hasPermi="['clue:order:after-sale']"
|
|
||||||
@click="sellAfter(scope.row)"
|
|
||||||
>
|
|
||||||
售后
|
|
||||||
</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"
|
|
||||||
link
|
|
||||||
style="padding: 0; margin-left: 0"
|
|
||||||
v-hasPermi="['clue:order:send']"
|
|
||||||
>
|
|
||||||
发货(进销存)
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
class="mr-10px"
|
|
||||||
link
|
|
||||||
style="padding: 0; margin-left: 0"
|
|
||||||
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>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="ClueOrder">
|
<script setup name="ClueOrder">
|
||||||
import { allSchemas } from './order.data'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
import OrderList from './Comp/OrderList.vue'
|
||||||
|
import Reback from './Comp/Reback.vue'
|
||||||
|
import AfterSales from './Comp/AfterSales.vue'
|
||||||
|
|
||||||
const tableObject = ref({
|
const appStore = useAppStore()
|
||||||
tableList: [{ name: '测试', contact: '18888888888' }],
|
const tabName = ref('list')
|
||||||
loading: false,
|
|
||||||
total: 1,
|
|
||||||
pageSize: 20,
|
|
||||||
currentPage: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
function resetQuery() {
|
|
||||||
// 方法体
|
|
||||||
}
|
|
||||||
// 查询
|
|
||||||
function getTableList() {
|
|
||||||
// 方法体
|
|
||||||
}
|
|
||||||
|
|
||||||
// 售后
|
|
||||||
function sellAfter() {
|
|
||||||
// 方法体
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<Dialog title="成交登记" v-model="show" width="820px">
|
<Dialog title="成交登记" v-model="show" width="820px">
|
||||||
<Descriptions
|
<Descriptions
|
||||||
title="线索信息"
|
:title="`线索信息-${info.name}`"
|
||||||
:data="info"
|
:data="info"
|
||||||
:schema="showSchema"
|
:schema="showSchema"
|
||||||
:columns="2"
|
:columns="2"
|
||||||
labelWidth="130px"
|
labelWidth="130px"
|
||||||
|
:defaultShow="false"
|
||||||
/>
|
/>
|
||||||
<el-form :model="form" ref="formRef" :rules="rules" label-width="80px" class="mt-20px">
|
<el-form :model="form" ref="formRef" :rules="rules" label-width="80px" class="mt-20px">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@@ -128,11 +129,13 @@
|
|||||||
class="mb-5px"
|
class="mb-5px"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
@click="form.signProduct.push({ productId: undefined, specsId: undefined, signNum: 0 })"
|
@click="
|
||||||
|
form.signProducts.push({ productId: undefined, specsId: undefined, signNum: 0 })
|
||||||
|
"
|
||||||
>
|
>
|
||||||
添加成交产品
|
添加成交产品
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-table :data="form.signProduct" border size="small">
|
<el-table :data="form.signProducts" border size="small">
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<el-table-column prop="productId" label="产品">
|
<el-table-column prop="productId" label="产品">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -189,7 +192,7 @@
|
|||||||
<Icon
|
<Icon
|
||||||
icon="ep:remove-filled"
|
icon="ep:remove-filled"
|
||||||
class="text-red-500"
|
class="text-red-500"
|
||||||
@click="handleRemove('signProduct', $index)"
|
@click="handleRemove('signProducts', $index)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -255,7 +258,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span>
|
<span>
|
||||||
<el-button @click="show = false">取 消</el-button>
|
<el-button @click="show = false">取 消</el-button>
|
||||||
<el-button type="primary" @click="handleSave">保 存</el-button>
|
<el-button :disabled="formLoading" type="primary" @click="handleSave">保 存</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@@ -339,7 +342,7 @@ function resetForm(id) {
|
|||||||
payAmount: 0,
|
payAmount: 0,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
extraPay: [],
|
extraPay: [],
|
||||||
signProduct: []
|
signProducts: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +358,7 @@ async function handleSave() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (form.value.signProduct.some((it) => !it.schoolId || !item.specsId || !it.signNum)) {
|
if (form.value.signProducts.some((it) => !it.productId || !item.specsId || !it.signNum)) {
|
||||||
message.info('请将成交产品信息填写完整!')
|
message.info('请将成交产品信息填写完整!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -363,9 +366,19 @@ async function handleSave() {
|
|||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
await createSign(form.value)
|
const params = { ...form.value }
|
||||||
|
params.diyParams = {}
|
||||||
|
diyFieldList.value.map((it) => {
|
||||||
|
params.diyParams[it.field] = undefined
|
||||||
|
})
|
||||||
|
for (const key in params.diyParams) {
|
||||||
|
if (Object.hasOwnProperty.call(params, key)) {
|
||||||
|
params.diyParams[key] = params[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await createSign(params)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
dialogVisible.value = false
|
show.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
<!-- 基础信息 -->
|
<!-- 基础信息 -->
|
||||||
<el-skeleton :loading="loading" animated>
|
<el-skeleton :loading="loading" animated>
|
||||||
<el-table :data="followList" size="small" border class="mt-10px">
|
<el-table :data="followList" size="small" border class="mt-10px">
|
||||||
<el-table-column prop="name" label="跟进人" />
|
<el-table-column prop="userName" label="跟进人" />
|
||||||
<el-table-column prop="latestFollowTime" label="最新跟进时间" />
|
<el-table-column prop="followTime" label="最新跟进时间" :formatter="dateFormatter" />
|
||||||
<el-table-column prop="nextFollowTime" label="下次跟进时间" />
|
<el-table-column prop="nextFollowTime" label="下次跟进时间" />
|
||||||
<el-table-column prop="saleStatus" label="成交状态" />
|
<el-table-column prop="signSate" label="成交状态" />
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-skeleton>
|
</el-skeleton>
|
||||||
<el-divider direction="horizontal" />
|
<el-divider direction="horizontal" />
|
||||||
@@ -99,7 +99,8 @@
|
|||||||
<span>操作人:{{ item.operateUserName }}</span>
|
<span>操作人:{{ item.operateUserName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-5px pb-5px">
|
<div class="pt-5px pb-5px">
|
||||||
<span>{{ item.content }}</span>
|
<!-- <span>{{ item.content }}</span> -->
|
||||||
|
<span v-dompurify-html="item.content"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex" style="align-items: center">
|
<div class="flex" style="align-items: center">
|
||||||
<Icon icon="ep:clock" class="mr-5px" />
|
<Icon icon="ep:clock" class="mr-5px" />
|
||||||
@@ -124,7 +125,7 @@ import { getPlaceList } from '@/api/school/place'
|
|||||||
|
|
||||||
import DialogFollow from './DialogFollow.vue'
|
import DialogFollow from './DialogFollow.vue'
|
||||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate, dateFormatter } from '@/utils/formatTime'
|
||||||
|
|
||||||
import ImgPostion from '@/assets/imgs/flag/position_blue.png'
|
import ImgPostion from '@/assets/imgs/flag/position_blue.png'
|
||||||
import FlagRed from '@/assets/imgs/flag/flag_red.png'
|
import FlagRed from '@/assets/imgs/flag/flag_red.png'
|
||||||
@@ -165,20 +166,7 @@ const showSchema = computed(() => {
|
|||||||
return [...props.schema, ...arr]
|
return [...props.schema, ...arr]
|
||||||
})
|
})
|
||||||
|
|
||||||
const followList = ref([
|
const followList = ref([])
|
||||||
{
|
|
||||||
name: '李四',
|
|
||||||
latestFollowTime: '2024-02-01',
|
|
||||||
nextFollowTime: '2024-04-01',
|
|
||||||
saleStatus: '未成交'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '王二',
|
|
||||||
latestFollowTime: '2024-03-01',
|
|
||||||
nextFollowTime: '2024-04-11',
|
|
||||||
saleStatus: '已成交'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const followRecordList = ref([])
|
const followRecordList = ref([])
|
||||||
const operateRecordList = ref([])
|
const operateRecordList = ref([])
|
||||||
@@ -201,9 +189,16 @@ function getFollowList() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFollowUsers(id) {
|
||||||
|
ClueApi.getFollowUserList({ id }).then((data) => {
|
||||||
|
followList.value = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function open(id) {
|
async function open(id) {
|
||||||
clueId.value = id
|
clueId.value = id
|
||||||
try {
|
try {
|
||||||
|
getFollowUsers(id)
|
||||||
getFollowList()
|
getFollowList()
|
||||||
ClueApi.getOpearateRecord({ clueId: id }).then((data) => {
|
ClueApi.getOpearateRecord({ clueId: id }).then((data) => {
|
||||||
operateRecordList.value = data.map((item) => ({
|
operateRecordList.value = data.map((item) => ({
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
link
|
link
|
||||||
|
:disabled="scope.row.state"
|
||||||
@click="handleSuccess(scope.row)"
|
@click="handleSuccess(scope.row)"
|
||||||
v-hasPermi="['clue:pool:enroll']"
|
v-hasPermi="['clue:pool:enroll']"
|
||||||
>
|
>
|
||||||
@@ -147,11 +148,11 @@
|
|||||||
<DrawerClue
|
<DrawerClue
|
||||||
v-if="!loading"
|
v-if="!loading"
|
||||||
ref="drawerRef"
|
ref="drawerRef"
|
||||||
:schema="allSchemas.formSchema"
|
:schema="allSchemas.detailSchema"
|
||||||
@get-list="getTableList"
|
@get-list="getTableList"
|
||||||
@update="handleEdit"
|
@update="handleEdit"
|
||||||
/>
|
/>
|
||||||
<DialogSuccess ref="successRef" :schema="allSchemas.formSchema" @success="getTableList" />
|
<DialogSuccess ref="successRef" :schema="allSchemas.detailSchema" @success="getTableList" />
|
||||||
<DialogFollow ref="followRef" @success="getTableList" />
|
<DialogFollow ref="followRef" @success="getTableList" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -187,6 +188,11 @@ async function getCurdSchemas() {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await getSimpleFieldList()
|
const data = await getSimpleFieldList()
|
||||||
|
data.forEach((elem) => {
|
||||||
|
if (elem.field == 'followUser') {
|
||||||
|
elem.search.options = userOptions.value
|
||||||
|
}
|
||||||
|
})
|
||||||
allSchemas.value = useCrudSchemas(data).allSchemas
|
allSchemas.value = useCrudSchemas(data).allSchemas
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -314,8 +320,8 @@ const userOptions = ref([])
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getUserOption().then((data) => {
|
getUserOption().then((data) => {
|
||||||
userOptions.value = data
|
userOptions.value = data
|
||||||
|
getCurdSchemas()
|
||||||
})
|
})
|
||||||
getCurdSchemas()
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ const loading = ref(false)
|
|||||||
const userList = ref([])
|
const userList = ref([])
|
||||||
|
|
||||||
function setRowClass({ row }) {
|
function setRowClass({ row }) {
|
||||||
return row.field == currentRowId.value ? 'current-row' : ''
|
return row.id == currentRowId.value ? 'current-row' : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentRowId = ref('')
|
const currentRowId = ref('')
|
||||||
@@ -144,7 +144,7 @@ function resourceCheckedChange(val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleRowClick(row) {
|
function handleRowClick(row) {
|
||||||
currentRowId.value = row.ruleId
|
currentRowId.value = row.id
|
||||||
form.value = { ...row }
|
form.value = { ...row }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,57 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form :model="form" ref="formRef" label-width="auto">
|
<el-form :model="form" ref="formRef" label-width="auto">
|
||||||
<el-form-item label="售后申请自动通过">
|
<el-form-item v-if="getConfig('afterSalesAuditAutoCompleteConfig')">
|
||||||
<el-radio-group v-model="form.autoAudiAfterSale">
|
<template #label>
|
||||||
<el-radio :label="0"> 是 </el-radio>
|
<Tooltip
|
||||||
<el-radio :label="1"> 否 </el-radio>
|
v-if="getConfig('afterSalesAuditAutoCompleteConfig').remark"
|
||||||
|
:message="getConfig('afterSalesAuditAutoCompleteConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>售后申请自动通过</span>
|
||||||
|
</template>
|
||||||
|
<el-radio-group v-model="form.afterSalesAuditAutoCompleteConfig">
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in getConfig('afterSalesAuditAutoCompleteConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="发货自动发起采购">
|
<el-form-item v-if="getConfig('deliveryAutoStartPurchaseConfig')">
|
||||||
<el-radio-group v-model="form.autoSend">
|
<template #label>
|
||||||
<el-radio :label="0"> 是 </el-radio>
|
<Tooltip
|
||||||
<el-radio :label="1"> 否 </el-radio>
|
v-if="getConfig('deliveryAutoStartPurchaseConfig').remark"
|
||||||
|
:message="getConfig('deliveryAutoStartPurchaseConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>发货自动发起采购</span>
|
||||||
|
</template>
|
||||||
|
<el-radio-group v-model="form.deliveryAutoStartPurchaseConfig">
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in getConfig('deliveryAutoStartPurchaseConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="回款申请自动通过">
|
<el-form-item v-if="getConfig('repaymentAuditAutoCompleteConfig')">
|
||||||
<el-radio-group v-model="form.autoAuditReturn">
|
<template #label>
|
||||||
<el-radio :label="0"> 是 </el-radio>
|
<Tooltip
|
||||||
<el-radio :label="1"> 否 </el-radio>
|
v-if="getConfig('repaymentAuditAutoCompleteConfig').remark"
|
||||||
|
:message="getConfig('repaymentAuditAutoCompleteConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>回款申请自动通过</span>
|
||||||
|
</template>
|
||||||
|
<el-radio-group v-model="form.repaymentAuditAutoCompleteConfig">
|
||||||
|
<el-radio
|
||||||
|
v-for="(item, index) in getConfig('repaymentAuditAutoCompleteConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -26,25 +62,42 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="GeneralClue">
|
<script setup name="GeneralClue">
|
||||||
|
import * as ConfigApi from '@/api/system/set'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({})
|
||||||
autoAudiAfterSale: 0,
|
|
||||||
autoSend: 0,
|
const configList = ref([])
|
||||||
autoAuditReturn: 0
|
|
||||||
})
|
function getConfig(val) {
|
||||||
|
return configList.value.find((it) => it.configKey == val)
|
||||||
|
}
|
||||||
|
|
||||||
function getData() {
|
function getData() {
|
||||||
form.value = {
|
ConfigApi.getConfigList({ module: 1 }).then((data) => {
|
||||||
autoAudiAfterSale: 0,
|
configList.value = data
|
||||||
autoSend: 0,
|
// 获取所有配置项
|
||||||
autoAuditReturn: 0
|
data.map((it) => {
|
||||||
}
|
form.value[it.configKey] = it.configValue
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
message.success('保存成功')
|
const params = configList.value.map((it) => ({
|
||||||
|
configId: it.configId,
|
||||||
|
configKey: it.configKey,
|
||||||
|
configValue: form.value[it.configKey]
|
||||||
|
}))
|
||||||
|
ConfigApi.updateConfig(params).then(() => {
|
||||||
|
message.success('保存成功')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -10,20 +10,20 @@
|
|||||||
<el-tab-pane label="线索来源" :name="15" v-if="checkPermi(['clue:setting:clue-resource'])">
|
<el-tab-pane label="线索来源" :name="15" v-if="checkPermi(['clue:setting:clue-resource'])">
|
||||||
<ClueSource v-if="tabIndex == 15" />
|
<ClueSource v-if="tabIndex == 15" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- <el-tab-pane
|
<el-tab-pane
|
||||||
label="线索获取规则"
|
label="线索获取规则"
|
||||||
:name="20"
|
:name="20"
|
||||||
v-if="checkPermi(['clue:setting:clue-get-rules'])"
|
v-if="checkPermi(['clue:setting:clue-get-rules'])"
|
||||||
>
|
>
|
||||||
<ClueGet v-if="tabIndex == 20" />
|
<ClueGet v-if="tabIndex == 20" />
|
||||||
</el-tab-pane> -->
|
</el-tab-pane>
|
||||||
<!-- <el-tab-pane
|
<el-tab-pane
|
||||||
label="线索分配规则"
|
label="线索分配规则"
|
||||||
:name="30"
|
:name="30"
|
||||||
v-if="checkPermi(['clue:setting:clue-send-rules'])"
|
v-if="checkPermi(['clue:setting:clue-send-rules'])"
|
||||||
>
|
>
|
||||||
<ClueSend v-if="tabIndex == 30" />
|
<ClueSend v-if="tabIndex == 30" />
|
||||||
</el-tab-pane> -->
|
</el-tab-pane>
|
||||||
<el-tab-pane label="意向状态" :name="35" v-if="checkPermi(['clue:setting:intention-status'])">
|
<el-tab-pane label="意向状态" :name="35" v-if="checkPermi(['clue:setting:intention-status'])">
|
||||||
<IntentionStatus v-if="tabIndex == 35" />
|
<IntentionStatus v-if="tabIndex == 35" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
import FieldClue from './Comp/FieldClue.vue'
|
import FieldClue from './Comp/FieldClue.vue'
|
||||||
import FieldOrder from './Comp/FieldOrder.vue'
|
import FieldOrder from './Comp/FieldOrder.vue'
|
||||||
import ClueSource from './Comp/ClueSource.vue'
|
import ClueSource from './Comp/ClueSource.vue'
|
||||||
// import ClueGet from './Comp/ClueGet.vue'
|
import ClueGet from './Comp/ClueGet.vue'
|
||||||
// import ClueSend from './Comp/ClueSend.vue'
|
import ClueSend from './Comp/ClueSend.vue'
|
||||||
// import MsgSend from './Comp/MsgSend.vue'
|
// import MsgSend from './Comp/MsgSend.vue'
|
||||||
import IntentionStatus from './Comp/IntentionStatus.vue'
|
import IntentionStatus from './Comp/IntentionStatus.vue'
|
||||||
import ExtraFeeType from './Comp/ExtraFeeType.vue'
|
import ExtraFeeType from './Comp/ExtraFeeType.vue'
|
||||||
|
|||||||
@@ -11,9 +11,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleQuery" v-hasPermi="['clue:skill:search']">
|
<el-button @click="handleQuery" v-hasPermi="['clue:skill:search']">搜索</el-button>
|
||||||
搜索
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="resetQuery" v-hasPermi="['clue:skill:reset']">重置</el-button>
|
<el-button @click="resetQuery" v-hasPermi="['clue:skill:reset']">重置</el-button>
|
||||||
<el-button type="primary" plain @click="handleAdd" v-hasPermi="['clue:skill:add']">
|
<el-button type="primary" plain @click="handleAdd" v-hasPermi="['clue:skill:add']">
|
||||||
新增
|
新增
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ const getMonthlySaleRate = async () => {
|
|||||||
)
|
)
|
||||||
set(lineOptionsData, 'series', [
|
set(lineOptionsData, 'series', [
|
||||||
{
|
{
|
||||||
name: t('analysis.estimate'),
|
name: '个人成交率',
|
||||||
smooth: true,
|
smooth: true,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: data.map((v) => v.estimate),
|
data: data.map((v) => v.estimate),
|
||||||
@@ -211,7 +211,7 @@ const getMonthlySaleRate = async () => {
|
|||||||
animationEasing: 'cubicInOut'
|
animationEasing: 'cubicInOut'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: t('analysis.actual'),
|
name: '平均成交率',
|
||||||
smooth: true,
|
smooth: true,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
itemStyle: {},
|
itemStyle: {},
|
||||||
|
|||||||
@@ -1,9 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form :model="form" ref="formRef" label-width="auto">
|
<el-form :model="form" ref="formRef" label-width="auto">
|
||||||
<el-form-item label="采购申请自动通过">
|
<el-form-item v-if="getConfig('purchaseAuditAutoCompleteConfig')">
|
||||||
|
<template #label>
|
||||||
|
<Tooltip
|
||||||
|
v-if="getConfig('purchaseAuditAutoCompleteConfig').remark"
|
||||||
|
:message="getConfig('purchaseAuditAutoCompleteConfig').remark"
|
||||||
|
/>
|
||||||
|
<span>采购申请自动通过</span>
|
||||||
|
</template>
|
||||||
<el-radio-group v-model="form.purchaseAuditAutoCompleteConfig">
|
<el-radio-group v-model="form.purchaseAuditAutoCompleteConfig">
|
||||||
<el-radio label="true"> 是 </el-radio>
|
<el-radio
|
||||||
<el-radio label="false"> 否 </el-radio>
|
v-for="(item, index) in getConfig('purchaseAuditAutoCompleteConfig').options"
|
||||||
|
:key="index"
|
||||||
|
:label="item.id"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -17,27 +29,31 @@ import * as ConfigApi from '@/api/system/set'
|
|||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({})
|
||||||
purchaseAuditAutoCompleteConfig: 'true'
|
|
||||||
})
|
|
||||||
|
|
||||||
const info = ref({})
|
const configList = ref([])
|
||||||
|
|
||||||
|
function getConfig(val) {
|
||||||
|
return configList.value.find((it) => it.configKey == val)
|
||||||
|
}
|
||||||
|
|
||||||
function getData() {
|
function getData() {
|
||||||
ConfigApi.getConfigByConfigKey({ configKey: 'purchaseAuditAutoCompleteConfig' }).then((data) => {
|
ConfigApi.getConfigList({ module: 3 }).then((data) => {
|
||||||
info.value = data
|
configList.value = data
|
||||||
form.value = {
|
// 获取所有配置项
|
||||||
purchaseAuditAutoCompleteConfig: data.configValue
|
data.map((it) => {
|
||||||
}
|
form.value[it.configKey] = it.configValue
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
const data = {
|
const params = configList.value.map((it) => ({
|
||||||
...info,
|
configId: it.configId,
|
||||||
purchaseAuditAutoCompleteConfig: form.value.purchaseAuditAutoCompleteConfig
|
configKey: it.configKey,
|
||||||
}
|
configValue: form.value[it.configKey]
|
||||||
ConfigApi.updateConfig(data).then(() => {
|
}))
|
||||||
|
ConfigApi.updateConfig(params).then(() => {
|
||||||
message.success('保存成功')
|
message.success('保存成功')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user