|
|
@@ -1,9 +1,516 @@
|
|
|
-<script setup lang="ts">
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <PlusPage
|
|
|
+ ref="plusPageInstance"
|
|
|
+ :columns="tableConfig"
|
|
|
+ :request="getList"
|
|
|
+ :is-card="true"
|
|
|
+ :search="{
|
|
|
+ labelWidth: 100,
|
|
|
+ showNumber: 3
|
|
|
+ }"
|
|
|
+ :table="{
|
|
|
+ actionBar: { buttons, type: 'link', width: 180 },
|
|
|
+ adaptive: { offsetBottom: 50 },
|
|
|
+ isSelection: true,
|
|
|
+ rowKey: 'id',
|
|
|
+ onSelectionChange: handleSelectionChange
|
|
|
+ }"
|
|
|
+ :pageInfoMap="{ page: 'pageNum', pageSize: 'pageSize' }"
|
|
|
+ >
|
|
|
+ <template #table-title>
|
|
|
+ <el-row class="button-row">
|
|
|
+ <el-button type="danger" @click="handleReliveOrder">
|
|
|
+ 解除分配
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" @click="handleReset"> 重新分配 </el-button>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ </PlusPage>
|
|
|
+ <!-- 弹窗编辑 -->
|
|
|
+ <PlusDialogForm
|
|
|
+ ref="dialogForm"
|
|
|
+ v-model="form"
|
|
|
+ v-model:visible="dialogVisible"
|
|
|
+ :form="{
|
|
|
+ columns,
|
|
|
+ labelPosition: 'left',
|
|
|
+ labelWidth: 100,
|
|
|
+ rules
|
|
|
+ }"
|
|
|
+ :dialog="{ title: dialogTitle + '菜单', width: 600, confirmLoading }"
|
|
|
+ @confirm="handleSubmit"
|
|
|
+ @close="handleClose"
|
|
|
+ />
|
|
|
+ <plusDialog
|
|
|
+ v-model="detailsVisible"
|
|
|
+ :hasFooter="false"
|
|
|
+ title="跟进状态"
|
|
|
+ width="600"
|
|
|
+ >
|
|
|
+ <plus-descriptions
|
|
|
+ :column="4"
|
|
|
+ :data="detailForm"
|
|
|
+ :columns="detailsColumns"
|
|
|
+ :border="false"
|
|
|
+ />
|
|
|
+ <el-timeline>
|
|
|
+ <el-timeline-item
|
|
|
+ v-for="item in detailForm.list"
|
|
|
+ :key="item.id"
|
|
|
+ :timestamp="item.createTime"
|
|
|
+ >
|
|
|
+ <el-card>
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-rate v-model="item.starLevel" />
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16">
|
|
|
+ <el-tag>{{ item.remark }}</el-tag>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-timeline-item>
|
|
|
+ </el-timeline>
|
|
|
+ </plusDialog>
|
|
|
+ <PlusDialogForm
|
|
|
+ ref="resetForm"
|
|
|
+ v-model="resetForm"
|
|
|
+ v-model:visible="resetVisible"
|
|
|
+ :form="{ columns: resetColumns, confirmLoading, labelWidth: 100 }"
|
|
|
+ title="重新分配"
|
|
|
+ :dialog="{
|
|
|
+ width: 400
|
|
|
+ }"
|
|
|
+ @confirm="handleResetAccount"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ onMounted,
|
|
|
+ reactive,
|
|
|
+ ref,
|
|
|
+ resolveDirective,
|
|
|
+ toRefs
|
|
|
+} from "vue";
|
|
|
+import type { FormRules } from "element-plus";
|
|
|
+import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
+import {
|
|
|
+ type FieldValues,
|
|
|
+ type PlusColumn,
|
|
|
+ PlusDescriptions,
|
|
|
+ PlusDialog,
|
|
|
+ PlusDialogForm,
|
|
|
+ PlusPage,
|
|
|
+ PlusPageInstance,
|
|
|
+ useTable
|
|
|
+} from "plus-pro-components";
|
|
|
+import { useRouter } from "vue-router";
|
|
|
+import {
|
|
|
+ getMerchantOrderInfoAllList,
|
|
|
+ merchantFollowInfoList,
|
|
|
+ merchantFollowInfoReliveOrder,
|
|
|
+ updateStartLevel
|
|
|
+} from "@/api/order";
|
|
|
+import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
|
|
+import { isString } from "@pureadmin/utils";
|
|
|
+import { getChildAccount } from "@/api/childAccount";
|
|
|
+
|
|
|
defineOptions({
|
|
|
name: "OrderLoan"
|
|
|
});
|
|
|
-</script>
|
|
|
|
|
|
-<template></template>
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+const plusPageInstance = ref<PlusPageInstance | null>(null);
|
|
|
+
|
|
|
+const getList = async (query: Record<string, any>) => {
|
|
|
+ let res = await getMerchantOrderInfoAllList(query);
|
|
|
+ return {
|
|
|
+ data: res.data.list,
|
|
|
+ total: res.data.total
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getChildAccountList();
|
|
|
+});
|
|
|
+
|
|
|
+// 重新请求列表接口
|
|
|
+const refresh = () => {
|
|
|
+ plusPageInstance.value?.getList();
|
|
|
+};
|
|
|
+
|
|
|
+const dialogTitle = computed(() => (state.isCreate ? "新增" : "编辑"));
|
|
|
+
|
|
|
+const multipleSelection = ref([]);
|
|
|
+
|
|
|
+const handleSelectionChange = (val: any[]) => {
|
|
|
+ multipleSelection.value = val;
|
|
|
+};
|
|
|
+
|
|
|
+const handleReliveOrder = () => {
|
|
|
+ if (multipleSelection.value.length === 0) {
|
|
|
+ ElMessage.warning("请选择要解除分配的订单");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ElMessageBox.confirm("确认解除分配?", "提示").then(async () => {
|
|
|
+ try {
|
|
|
+ let res = await merchantFollowInfoReliveOrder({
|
|
|
+ orderIds: multipleSelection.value.map((item: any) => item.id)
|
|
|
+ });
|
|
|
+ if (res.code === 0) {
|
|
|
+ ElMessage.success("解除分配成功");
|
|
|
+ refresh();
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ ElMessage.error("删除失败");
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleReset = () => {
|
|
|
+ if (multipleSelection.value.length === 0) {
|
|
|
+ ElMessage.warning("请选择要重新分配的订单");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ resetForm.value.ids = multipleSelection.value.map((item: any) => item.id);
|
|
|
+ resetVisible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+// 表格数据
|
|
|
+const tableConfig: PlusColumn[] = [
|
|
|
+ {
|
|
|
+ label: "订单号",
|
|
|
+ tableColumnProps: {
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ width: 150,
|
|
|
+ prop: "orderNo"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "客户姓名",
|
|
|
+ prop: "userName"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "性别",
|
|
|
+ prop: "userSex",
|
|
|
+ width: 60,
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "客户星级",
|
|
|
+ prop: "star",
|
|
|
+ valueType: "rate",
|
|
|
+ editable: true,
|
|
|
+ width: 140,
|
|
|
+ fieldProps: {
|
|
|
+ disabled: true
|
|
|
+ },
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "电话",
|
|
|
+ prop: "maskPhone",
|
|
|
+ width: 100,
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "微信",
|
|
|
+ prop: "wxCode",
|
|
|
+ tableColumnProps: {
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "优先联系方式",
|
|
|
+ prop: "headContractType",
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "申请产品",
|
|
|
+ prop: "planName",
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "需求资金",
|
|
|
+ prop: "loanAmount",
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "贷款期限",
|
|
|
+ prop: "loanTerm",
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "申请时间",
|
|
|
+ prop: "applyTime",
|
|
|
+ width: 170,
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "分配子账号",
|
|
|
+ prop: "belongName",
|
|
|
+ width: 120,
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "状态",
|
|
|
+ prop: "followStatus",
|
|
|
+ valueType: "select",
|
|
|
+ options: [
|
|
|
+ { label: "未跟进", value: 0 },
|
|
|
+ { label: "跟进", value: 4 }
|
|
|
+ ],
|
|
|
+ hideInSearch: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "备注",
|
|
|
+ prop: "wechat",
|
|
|
+ hideInSearch: true
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+/*--------------------表单--------------------*/
|
|
|
+
|
|
|
+// 表单实例
|
|
|
+const dialogForm = ref(null);
|
|
|
|
|
|
-<style scoped lang="scss"></style>
|
|
|
+interface State {
|
|
|
+ dialogVisible: boolean;
|
|
|
+ detailsVisible: boolean;
|
|
|
+ resetVisible: boolean;
|
|
|
+ confirmLoading: boolean;
|
|
|
+ selectedIds: number[];
|
|
|
+ isCreate: boolean;
|
|
|
+ form: {};
|
|
|
+ detailForm: {
|
|
|
+ list: any[];
|
|
|
+ };
|
|
|
+ resetForm: {
|
|
|
+ ids: any[];
|
|
|
+ };
|
|
|
+ rules: FormRules;
|
|
|
+}
|
|
|
+
|
|
|
+const state = reactive<State>({
|
|
|
+ dialogVisible: false,
|
|
|
+ detailsVisible: false,
|
|
|
+ resetVisible: false,
|
|
|
+ confirmLoading: false,
|
|
|
+ selectedIds: [],
|
|
|
+ isCreate: false,
|
|
|
+ form: {},
|
|
|
+ detailForm: {
|
|
|
+ list: []
|
|
|
+ },
|
|
|
+ resetForm: {
|
|
|
+ ids: []
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ star: [{ required: true, message: "请选择客户星级", trigger: "blur" }]
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const columns: PlusColumn[] = [
|
|
|
+ {
|
|
|
+ label: "客户星级",
|
|
|
+ prop: "starLevel",
|
|
|
+ valueType: "select",
|
|
|
+ tooltip: {
|
|
|
+ content:
|
|
|
+ "<span>客户星级说明</span></br>" +
|
|
|
+ "<span>0星:未接通</span></br>" +
|
|
|
+ "<span>1星:接通但无办理意向</span></br>" +
|
|
|
+ "<span>2星:有意向但无可贷点</span></br>" +
|
|
|
+ "<span>3星:有可贷点但资质一般</span></br>" +
|
|
|
+ "<span>4星:有可贷点且条件较好</span></br>" +
|
|
|
+ "<span>5星:马上需要或条件优质</span></br>",
|
|
|
+ rawContent: true
|
|
|
+ },
|
|
|
+ options: [
|
|
|
+ { label: "1星", value: 1 },
|
|
|
+ { label: "2星", value: 2 },
|
|
|
+ { label: "3星", value: 3 },
|
|
|
+ { label: "4星", value: 4 },
|
|
|
+ { label: "5星", value: 5 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "备注",
|
|
|
+ prop: "remark",
|
|
|
+ valueType: "input",
|
|
|
+ fieldProps: {
|
|
|
+ type: "textarea",
|
|
|
+ rows: 4,
|
|
|
+ maxlength: 200,
|
|
|
+ showWordLimit: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const detailsColumns: PlusColumn[] = [
|
|
|
+ {
|
|
|
+ label: "姓名:",
|
|
|
+ prop: "userName"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "需求资金:",
|
|
|
+ prop: "loanAmount"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "年龄:",
|
|
|
+ prop: "age"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "需求周期:",
|
|
|
+ prop: "loanTerm"
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const childAccountList = ref<any[]>([]);
|
|
|
+
|
|
|
+const getChildAccountList = async () => {
|
|
|
+ let res = await getChildAccount();
|
|
|
+ childAccountList.value = res.data;
|
|
|
+};
|
|
|
+
|
|
|
+const resetColumns: PlusColumn[] = [
|
|
|
+ {
|
|
|
+ label: "分配子账号",
|
|
|
+ prop: "id",
|
|
|
+ valueType: "select",
|
|
|
+ options: computed(() => childAccountList.value),
|
|
|
+ optionsMap: {
|
|
|
+ label: "contractName",
|
|
|
+ value: "id"
|
|
|
+ }
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const handleSubmit = async (values: FieldValues) => {
|
|
|
+ console.log(values, "Submit");
|
|
|
+ confirmLoading.value = true;
|
|
|
+ try {
|
|
|
+ let params = form.value;
|
|
|
+ let res = await updateStartLevel(params);
|
|
|
+ if (res.code === 0) {
|
|
|
+ ElMessage.success("修改成功");
|
|
|
+ confirmLoading.value = false;
|
|
|
+ dialogVisible.value = false;
|
|
|
+ refresh();
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ confirmLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const handleResetAccount = async (values: FieldValues) => {
|
|
|
+ console.log(values, "Submit");
|
|
|
+ confirmLoading.value = true;
|
|
|
+ try {
|
|
|
+ let params = resetForm.value;
|
|
|
+ let res = await merchantFollowInfoReliveOrder(params);
|
|
|
+ if (res.code === 0) {
|
|
|
+ ElMessage.success("重新分配成功");
|
|
|
+ confirmLoading.value = false;
|
|
|
+ resetVisible.value = false;
|
|
|
+ refresh();
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ confirmLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ // 重置表单校验状态
|
|
|
+ console.log(dialogForm.value.formInstance);
|
|
|
+};
|
|
|
+
|
|
|
+const { buttons } = useTable();
|
|
|
+
|
|
|
+const perms = resolveDirective("perms");
|
|
|
+
|
|
|
+buttons.value = [
|
|
|
+ {
|
|
|
+ // 修改
|
|
|
+ text: "详情",
|
|
|
+ code: "edit",
|
|
|
+ // props v0.1.16 版本新增函数类型
|
|
|
+ props: {
|
|
|
+ type: "primary"
|
|
|
+ },
|
|
|
+ onClick(val) {
|
|
|
+ let params = {
|
|
|
+ id: val.row.id
|
|
|
+ };
|
|
|
+ Object.keys(params).forEach(param => {
|
|
|
+ if (!isString(params[param])) {
|
|
|
+ params[param] = params[param].toString();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 保存信息到标签页
|
|
|
+ useMultiTagsStoreHook().handleTags("push", {
|
|
|
+ path: `/order/order-loan/detail`,
|
|
|
+ name: "OrderLoanDetail",
|
|
|
+ query: params,
|
|
|
+ meta: {
|
|
|
+ title: `订单详情`,
|
|
|
+ // 如果使用的是非国际化精简版title可以像下面这么写
|
|
|
+ // title: `No.${index} - 详情信息`,
|
|
|
+ // 最大打开标签数
|
|
|
+ dynamicLevel: 1
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 路由跳转
|
|
|
+ router.push({ name: "OrderLoanDetail", query: params });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // 跟进
|
|
|
+ text: "跟进",
|
|
|
+ props: {
|
|
|
+ type: "primary"
|
|
|
+ },
|
|
|
+ onClick(val) {
|
|
|
+ form.value.orderId = val.row.orderNo;
|
|
|
+ dialogVisible.value = true;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // 修改
|
|
|
+ text: "跟进状态",
|
|
|
+ props: {
|
|
|
+ type: "primary"
|
|
|
+ },
|
|
|
+ onClick(val) {
|
|
|
+ console.log(val.row);
|
|
|
+ detailForm.value = val.row;
|
|
|
+ detailForm.value.list = [];
|
|
|
+ merchantFollowInfoList({ orderNo: val.row.orderNo }).then(res => {
|
|
|
+ detailForm.value.list = res.data;
|
|
|
+ });
|
|
|
+ detailsVisible.value = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+];
|
|
|
+
|
|
|
+const {
|
|
|
+ form,
|
|
|
+ detailForm,
|
|
|
+ resetForm,
|
|
|
+ confirmLoading,
|
|
|
+ rules,
|
|
|
+ dialogVisible,
|
|
|
+ detailsVisible,
|
|
|
+ resetVisible
|
|
|
+} = toRefs(state);
|
|
|
+</script>
|