Prechádzať zdrojové kódy

refactor(lead): 将业务逻辑提取到mixin中以提高代码复用性

yz 3 týždňov pred
rodič
commit
cc2c7e044c
2 zmenil súbory, kde vykonal 1152 pridanie a 1136 odobranie
  1. 2 1136
      src/views/lead/index.vue
  2. 1150 0
      src/views/lead/mixins/leadIndex.js

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 1136
src/views/lead/index.vue


+ 1150 - 0
src/views/lead/mixins/leadIndex.js

@@ -0,0 +1,1150 @@
+import { getList, add, update, getDetail } from '@/api/order/lead'
+import { getList as getDetailList, add as addDetail, update as updateDetail, remove as removeDetail, getDetail as getDetailDetail } from '@/api/order/lead-detail'
+import { getCustomerList } from '@/api/common/index'
+import { mapGetters } from 'vuex'
+
+/**
+ * 销售线索记录类型定义
+ * @typedef {Object} LeadRecord
+ * @property {string} id - 线索ID
+ * @property {string} createUser - 创建用户ID
+ * @property {string} createDept - 创建部门ID
+ * @property {string} createTime - 创建时间
+ * @property {string} updateUser - 更新用户ID
+ * @property {string} updateTime - 更新时间
+ * @property {number} status - 状态 1-新建 2-跟进中 3-已关闭
+ * @property {number} isDeleted - 是否删除
+ * @property {string} leadCode - 线索编码
+ * @property {number} customerId - 客户ID
+ * @property {string} customerCode - 客户编码
+ * @property {string} customerName - 客户名称
+ * @property {string} contactName - 联系人姓名
+ * @property {string} contactPhone - 联系人电话
+ * @property {string} title - 线索标题
+ * @property {string} endTime - 截止时间
+ * @property {number} priority - 优先级
+ * @property {string} source - 线索来源
+ * @property {string} groupName - 分组名称
+ * @property {string|null} closeReason - 关闭原因
+ */
+
+/**
+ * 销售线索查询参数类型定义
+ * @typedef {Object} LeadQueryParams
+ * @property {string} [leadCode] - 线索编码
+ * @property {string} [customerCode] - 客户编码
+ * @property {string} [customerName] - 客户名称
+ * @property {string} [contactName] - 联系人姓名
+ * @property {string} [contactPhone] - 联系人电话
+ * @property {string} [title] - 线索标题
+ * @property {number} [status] - 状态
+ * @property {number} [priority] - 优先级
+ * @property {string} [source] - 线索来源
+ * @property {string} [groupName] - 分组名称
+ * @property {string[]} [endTime] - 截止时间范围
+ */
+
+/**
+ * 销售线索详细信息记录类型定义
+ * @typedef {Object} LeadDetailRecord
+ * @property {string} id - 详细信息ID
+ * @property {string} leadId - 线索ID
+ * @property {string} detailText - 详细信息内容
+ * @property {string} createTime - 创建时间
+ * @property {string} updateTime - 更新时间
+ */
+
+export default {
+    computed: {
+        ...mapGetters(['permission', 'userInfo']),
+        
+        /**
+         * 权限列表
+         * @returns {Object} 权限配置
+         */
+        permissionList() {
+            return {
+                addBtn: this.vaildData(this.permission.order_lead_add, false),
+                viewBtn: this.vaildData(this.permission.order_lead_view, false),
+                delBtn: this.vaildData(this.permission.order_lead_delete, false),
+                editBtn: this.vaildData(this.permission.order_lead_edit, false)
+            }
+        },
+        
+        /**
+         * 选中数据的ID列表
+         * @returns {string[]} ID列表
+         */
+        ids() {
+            return this.selectionList.map(ele => ele.id)
+        },
+        
+        /**
+         * 详细信息选中数据的ID列表
+         * @returns {string[]} ID列表
+         */
+        detailIds() {
+            return this.detailSelectionList.map(ele => ele.id)
+        }
+    },
+    
+    data() {
+        return {
+            /**
+             * 详细信息表格配置
+             */
+            detailOption: {
+                height: 'auto',
+                calcHeight: 30,
+                tip: false,
+                searchShow: false,
+                border: true,
+                index: true,
+                viewBtn: true,
+                selection: true,
+                dialogClickModal: false,
+                column: [
+                    {
+                        label: '详细信息内容',
+                        prop: 'detailText',
+                        type: 'textarea',
+                        span: 24,
+                        minRows: 4,
+                        maxRows: 8,
+                        rules: [{
+                            required: true,
+                            message: '请输入详细信息内容',
+                            trigger: 'blur'
+                        }, {
+                            min: 10,
+                            message: '详细信息内容至少10个字符',
+                            trigger: 'blur'
+                        }],
+                        overHidden: true,
+                        width: 400
+                    },
+                    {
+                        label: '创建时间',
+                        prop: 'createTime',
+                        type: 'datetime',
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        addDisplay: false,
+                        editDisplay: false,
+                        viewDisplay: true,
+                        width: 180
+                    },
+                    {
+                        label: '更新时间',
+                        prop: 'updateTime',
+                        type: 'datetime',
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        addDisplay: false,
+                        editDisplay: false,
+                        viewDisplay: true,
+                        width: 180
+                    }
+                ]
+            },
+            
+            /**
+             * 详细信息权限列表
+             */
+            detailPermissionList: {
+                addBtn: true,
+                viewBtn: true,
+                delBtn: false,
+                editBtn: true,
+            },
+
+            /**
+             * 详细信息分页信息
+             * @type {{total: number, currentPage: number, pageSize: number}}
+             */
+            detailPage: {
+                total: 0,
+                currentPage: 1,
+                pageSize: 10
+            },
+            
+            /**
+             * 详细信息加载状态
+             * @type {boolean}
+             */
+            detailLoading: false,
+            /**
+             * 详细信息弹窗显示状态
+             * @type {boolean}
+             */
+            detailDialogVisible: false,
+            
+            /**
+             * 当前选中的线索
+             * @type {LeadRecord|null}
+             */
+            currentLead: null,
+            
+            /**
+             * 详细信息表格数据
+             * @type {LeadDetailRecord[]}
+             */
+            detailData: [],
+            
+            /**
+             * 详细信息表单数据
+             * @type {LeadDetailRecord}
+             */
+            detailForm: {},
+            
+            /**
+             * 详细信息选中的数据列表
+             * @type {LeadDetailRecord[]}
+             */
+            detailSelectionList: [],
+            /**
+             * 表格数据
+             * @type {LeadRecord[]}
+             */
+            data: [],
+            /**
+             * 查询参数
+             * @type {LeadQueryParams}
+             */
+            query: {},
+            /**
+             * 加载状态
+             * @type {boolean}
+             */
+            loading: true,
+            /**
+             * 表单数据
+             * @type {LeadRecord}
+             */
+            form: {},
+            /**
+             * 选中的数据列表
+             * @type {LeadRecord[]}
+             */
+            selectionList: [],
+            /**
+             * 分页信息
+             * @type {{total: number, currentPage: number, pageSize: number}}
+             */
+            page: {
+                total: 0,
+                currentPage: 1,
+                pageSize: 10
+            },
+            /**
+             * 客户选项列表
+             * @type {{label: string, value: string, customerCode: string, customerName: string, customerId: string}[]}
+             */
+            customerOptions: [],
+
+            /**
+             * 客户选项加载状态
+             * @type {boolean}
+             */
+            customerLoading: false,
+
+            /**
+             * 客户搜索关键词
+             * @type {string}
+             */
+            customerSearchKeyword: '',
+
+            /**
+             * 客户搜索定时器
+             * @type {number|null}
+             */
+            customerSearchTimer: null,
+            /**
+             * 表格配置
+             */
+            option: {
+                height: 'auto',
+                calcHeight: 30,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 6,
+                border: true,
+                index: true,
+                viewBtn: true,
+                selection: true,
+                dialogClickModal: false,
+                column: [
+                    {
+                        label: '线索编码',
+                        prop: 'leadCode',
+                        rules: [{
+                            required: true,
+                            message: '请输入线索编码',
+                            trigger: 'blur'
+                        }],
+                        search: true
+                    },
+                    {
+                        label: '客户',
+                        prop: 'customerId',
+                        type: 'select',
+                        search: false,
+                        width: 200,
+                        filterable: true,
+                        remote: false,
+                        reserveKeyword: true,
+                        placeholder: '请选择客户',
+                        dicData: [],
+                        props: {
+                            label: 'label',
+                            value: 'value'
+                        },
+                        rules: [{
+                            required: true,
+                            message: '请选择客户',
+                            trigger: 'change'
+                        }],
+                        /**
+                         * 客户选择变更事件
+                         * @param {Object} param - 事件参数
+                         * @param {string} param.value - 选中的客户ID
+                         * @param {Object} param.column - 列配置
+                         * @returns {void}
+                         */
+                        change: ({ value, column }) => {
+                            if (value) {
+                                const selectedCustomer = this.customerOptions.find(option => option.value === value)
+                                if (selectedCustomer) {
+                                    // 自动填充客户信息
+                                    this.form.customerId = selectedCustomer.customerId
+                                    this.form.customerCode = selectedCustomer.customerCode
+                                    this.form.customerName = selectedCustomer.customerName
+                                } else {
+                                    this.clearCustomerData()
+                                }
+                            } else {
+                                this.clearCustomerData()
+                            }
+                        },
+                        /**
+                         * 远程搜索方法
+                         * @param {string} query - 搜索关键词
+                         * @returns {void}
+                         */
+                        remoteMethod: (query) => {
+                            this.searchCustomers(query)
+                        }
+                    },
+                    {
+                        label: '客户编码',
+                        prop: 'customerCode',
+                        search: true,
+                        addDisplay: false,
+                        editDisplay: false,
+                        width: 120
+                    },
+                    {
+                        label: '客户名称',
+                        prop: 'customerName',
+                        search: true,
+                        addDisplay: false,
+                        editDisplay: false,
+                        width: 150
+                    },
+                    {
+                        label: '联系人',
+                        prop: 'contactName',
+                        rules: [{
+                            required: true,
+                            message: '请输入联系人姓名',
+                            trigger: 'blur'
+                        }],
+                        search: true
+                    },
+                    {
+                        label: '联系电话',
+                        prop: 'contactPhone',
+                        rules: [{
+                            required: true,
+                            message: '请输入联系电话',
+                            trigger: 'blur'
+                        }, {
+                            pattern: /^1[3-9]\d{9}$/,
+                            message: '请输入正确的手机号码',
+                            trigger: 'blur'
+                        }],
+                        search: true
+                    },
+                    {
+                        label: '线索标题',
+                        prop: 'title',
+                        rules: [{
+                            required: true,
+                            message: '请输入线索标题',
+                            trigger: 'blur'
+                        }],
+                        search: true,
+                        overHidden: true
+                    },
+                    {
+                        label: '截止时间',
+                        prop: 'endTime',
+                        type: 'datetime',
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        rules: [{
+                            required: true,
+                            message: '请选择截止时间',
+                            trigger: 'blur'
+                        }],
+                        search: true,
+                        searchRange: true,
+                        slot: true
+                    },
+                    {
+                        label: '优先级',
+                        prop: 'priority',
+                        type: 'select',
+                        dicData: [
+                            { label: '高', value: 1 },
+                            { label: '中', value: 2 },
+                            { label: '低', value: 3 }
+                        ],
+                        rules: [{
+                            required: true,
+                            message: '请选择优先级',
+                            trigger: 'blur'
+                        }],
+                        search: true,
+                        slot: true
+                    },
+                    {
+                        label: '线索来源',
+                        prop: 'source',
+                        rules: [{
+                            required: true,
+                            message: '请输入线索来源',
+                            trigger: 'blur'
+                        }],
+                        search: true
+                    },
+                    {
+                        label: '分组名称',
+                        prop: 'groupName',
+                        rules: [{
+                            required: true,
+                            message: '请输入分组名称',
+                            trigger: 'blur'
+                        }],
+                        search: true
+                    },
+                    {
+                        label: '状态',
+                        prop: 'status',
+                        type: 'select',
+                        dicData: [
+                            { label: '新建', value: 1 },
+                            { label: '跟进中', value: 2 },
+                            { label: '已关闭', value: 3 }
+                        ],
+                        rules: [{
+                            required: true,
+                            message: '请选择状态',
+                            trigger: 'blur'
+                        }],
+                        search: true,
+                        slot: true
+                    },
+                    {
+                        label: '关闭原因',
+                        prop: 'closeReason',
+                        type: 'textarea',
+                        span: 24,
+                        hide: true,
+                        viewDisplay: true
+                    },
+                    {
+                        label: '创建时间',
+                        prop: 'createTime',
+                        type: 'datetime',
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        addDisplay: false,
+                        editDisplay: false,
+                        viewDisplay: true,
+                        width: 180
+                    },
+                    {
+                        label: '更新时间',
+                        prop: 'updateTime',
+                        type: 'datetime',
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        addDisplay: false,
+                        editDisplay: false,
+                        viewDisplay: true,
+                        width: 180
+                    }
+                ]
+            }
+        }
+    },
+    
+    methods: {
+        /**
+         * 加载客户选项列表
+         * @param {string} [keyword=''] - 搜索关键词
+         * @returns {Promise<void>}
+         */
+        async loadCustomerOptions(keyword = '') {
+            try {
+                this.customerLoading = true
+                const params = {}
+
+                // 如果有搜索关键词,添加到查询参数中
+                if (keyword.trim()) {
+                    params.Customer_CODE = keyword
+                    params.Customer_NAME = keyword
+                }
+
+                const response = await getCustomerList(1, 50, params)
+
+                if (response.data && response.data.success) {
+                    const customers = response.data.data.records || []
+                    this.customerOptions = customers.map(customer => ({
+                        value: customer.Customer_ID,
+                        label: `${customer.Customer_CODE} - ${customer.Customer_NAME}`,
+                        customerCode: customer.Customer_CODE,
+                        customerName: customer.Customer_NAME,
+                        customerId: customer.Customer_ID
+                    }))
+
+                    // 更新表格配置中的选项数据
+                    this.updateCustomerOptionsInColumn()
+                } else {
+                    this.customerOptions = []
+                    this.$message.warning('获取客户列表失败')
+                }
+            } catch (error) {
+                this.customerOptions = []
+                console.error('加载客户选项失败:', error)
+                this.$message.error('加载客户选项失败,请稍后重试')
+            } finally {
+                this.customerLoading = false
+            }
+        },
+
+        /**
+         * 搜索客户(防抖处理)
+         * @param {string} query - 搜索关键词
+         * @returns {void}
+         */
+        searchCustomers(query) {
+            // 清除之前的定时器
+            if (this.customerSearchTimer) {
+                clearTimeout(this.customerSearchTimer)
+            }
+
+            // 设置新的定时器,300ms后执行搜索
+            this.customerSearchTimer = setTimeout(() => {
+                this.loadCustomerOptions(query)
+            }, 300)
+        },
+
+        /**
+         * 更新表格配置中的客户选项数据
+         * @returns {void}
+         */
+        updateCustomerOptionsInColumn() {
+            const customerColumn = this.option.column.find(col => col.prop === 'customerId')
+            if (customerColumn) {
+                customerColumn.dicData = this.customerOptions
+            }
+        },
+
+        /**
+         * 清除客户相关数据
+         * @returns {void}
+         */
+        clearCustomerData() {
+            this.form.customerName = ''
+            this.form.customerCode = ''
+            this.form.customerId = ''
+        },
+
+        /**
+         * 新增前的回调
+         * @param {Function} done - 完成回调
+         * @param {string} type - 操作类型
+         */
+        async beforeOpen(done, type) {
+            // 确保客户选项已加载
+            if (this.customerOptions.length === 0) {
+                await this.loadCustomerOptions()
+            }
+
+            if (['edit', 'view'].includes(type)) {
+                try {
+                    const res = await getDetail(this.form.id)
+                    this.form = res.data.data
+
+                    // 处理客户数据回显
+                    if (this.form.customerId) {
+                        // 检查当前客户是否在选项列表中
+                        const existingCustomer = this.customerOptions.find(option =>
+                            option.value === this.form.customerId ||
+                            option.customerId === this.form.customerId.toString()
+                        )
+
+                        // 如果客户不在选项列表中,添加当前客户到选项列表
+                        if (!existingCustomer && this.form.customerCode && this.form.customerName) {
+                            const currentCustomerOption = {
+                                value: this.form.customerId,
+                                label: `${this.form.customerCode} - ${this.form.customerName}`,
+                                customerCode: this.form.customerCode,
+                                customerName: this.form.customerName,
+                                customerId: this.form.customerId.toString()
+                            }
+
+                            // 将当前客户添加到选项列表开头
+                            // this.customerOptions.unshift(currentCustomerOption)
+
+                            // 更新表格配置中的选项数据
+                            await this.updateCustomerOptionsInColumn()
+                        }
+                        // 选中当前客户
+                        this.form.customerId = existingCustomer ? existingCustomer.value : this.form.customerId
+                        this.form.customerCode = existingCustomer ? existingCustomer.customerCode : this.form.customerCode
+                        this.form.customerName = existingCustomer ? existingCustomer.customerName : this.form.customerName
+                    }
+                } catch (error) {
+                    console.error('获取详情失败:', error)
+                }
+            } else if (type === 'add') {
+                // 新增时清除客户相关数据
+                this.clearCustomerData()
+            }
+
+            done()
+        },
+        
+        /**
+         * 获取状态文本
+         * @param {number} status - 状态值
+         * @returns {string} 状态文本
+         */
+        getStatusText(status) {
+            const statusMap = {
+                1: '新建',
+                2: '跟进中',
+                3: '已关闭'
+            }
+            return statusMap[status] || '未知状态'
+        },
+
+        /**
+         * 获取状态标签类型
+         * @param {number} status - 状态值
+         * @returns {string} 标签类型
+         */
+        getStatusType(status) {
+            const typeMap = {
+                1: 'info',
+                2: 'warning',
+                3: 'success'
+            }
+            return typeMap[status] || 'info'
+        },
+
+        /**
+         * 获取优先级文本
+         * @param {number} priority - 优先级值
+         * @returns {string} 优先级文本
+         */
+        getPriorityText(priority) {
+            const priorityMap = {
+                1: '高',
+                2: '中',
+                3: '低'
+            }
+            return priorityMap[priority] || '未知优先级'
+        },
+
+        /**
+         * 获取优先级标签类型
+         * @param {number} priority - 优先级值
+         * @returns {string} 标签类型
+         */
+        getPriorityType(priority) {
+            const typeMap = {
+                1: 'danger',
+                2: 'warning',
+                3: 'success'
+            }
+            return typeMap[priority] || 'info'
+        },
+
+        /**
+         * 判断是否逾期
+         * @param {string} endTime - 截止时间
+         * @param {number} status - 状态
+         * @returns {boolean} 是否逾期
+         */
+        isOverdue(endTime, status) {
+            if (status === 3) return false // 已关闭的不显示逾期
+            const now = new Date()
+            const end = new Date(endTime)
+            return end < now
+        },
+
+        /**
+         * 批量删除
+         * @returns {Promise<void>}
+         */
+        async handleDelete() {
+            if (this.selectionList.length === 0) {
+                this.$message.warning('请选择至少一条数据')
+                return
+            }
+            try {
+                await this.$confirm('确定将选择数据删除?', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                })
+                // await remove(this.ids)
+                await this.onLoad(this.page)
+                this.$message({
+                    type: 'success',
+                    message: '操作成功!'
+                })
+                this.$refs.crud.toggleSelection()
+            } catch (error) {
+                console.error('批量删除失败:', error)
+            }
+        },
+
+        /**
+         * 更新操作
+         * @param {LeadRecord} row - 行数据
+         * @param {number} index - 行索引
+         * @param {Function} done - 完成回调
+         * @param {Function} loading - 加载回调
+         * @returns {Promise<void>}
+         */
+        async rowUpdate(row, index, done, loading) {
+            try {
+                await update(row)
+                await this.onLoad(this.page)
+                this.$message({
+                    type: 'success',
+                    message: '操作成功!'
+                })
+                done()
+            } catch (error) {
+                console.error('更新失败:', error)
+                loading()
+            }
+        },
+
+        /**
+         * 新增操作
+         * @param {LeadRecord} row - 行数据
+         * @param {Function} done - 完成回调
+         * @param {Function} loading - 加载回调
+         * @returns {Promise<void>}
+         */
+        async rowSave(row, done, loading) {
+            try {
+                await add(row)
+                await this.onLoad(this.page)
+                this.$message({
+                    type: 'success',
+                    message: '操作成功!'
+                })
+                done()
+            } catch (error) {
+                console.error('新增失败:', error)
+                loading()
+            }
+        },
+
+        /**
+         * 获取数据
+         * @param {Object} page - 分页信息
+         * @param {LeadQueryParams} [params] - 查询参数
+         * @returns {Promise<void>}
+         */
+        async onLoad(page, params = {}) {
+            this.loading = true
+            try {
+                // 处理时间范围查询
+                const queryParams = { ...params }
+                if (queryParams.endTime && Array.isArray(queryParams.endTime)) {
+                    queryParams.endTimeStart = queryParams.endTime[0]
+                    queryParams.endTimeEnd = queryParams.endTime[1]
+                    delete queryParams.endTime
+                }
+
+                const res = await getList(page.currentPage, page.pageSize, queryParams)
+                const data = res.data.data
+                this.data = data.records || []
+                this.page.total = data.total || 0
+            } catch (error) {
+                console.error('获取数据失败:', error)
+                this.$message.error('获取数据失败')
+            } finally {
+                this.loading = false
+            }
+        },
+
+        /**
+         * 搜索变更
+         * @param {LeadQueryParams} params - 查询参数
+         * @param {Function} done - 完成回调
+         */
+        searchChange(params, done) {
+            this.query = params
+            this.onLoad(this.page, params)
+            done()
+        },
+
+        /**
+         * 搜索重置
+         * @param {Function} done - 完成回调
+         */
+        searchReset(done) {
+            this.query = {}
+            this.onLoad(this.page)
+            done()
+        },
+
+        /**
+         * 选择变更
+         * @param {LeadRecord[]} list - 选中的数据
+         */
+        selectionChange(list) {
+            this.selectionList = list
+        },
+
+        /**
+         * 清空选择
+         */
+        selectionClear() {
+            this.selectionList = []
+        },
+
+        /**
+         * 当前页变更
+         * @param {number} currentPage - 当前页
+         */
+        currentChange(currentPage) {
+            this.page.currentPage = currentPage
+        },
+
+        /**
+         * 页大小变更
+         * @param {number} pageSize - 页大小
+         */
+        sizeChange(pageSize) {
+            this.page.pageSize = pageSize
+        },
+
+        /**
+         * 刷新变更
+         */
+        refreshChange() {
+            this.onLoad(this.page, this.query)
+        },
+
+        /**
+         * 查看线索详细信息
+         * @param {LeadRecord} row - 行数据
+         * @returns {Promise<void>}
+         */
+        async handleViewDetail(row) {
+            this.currentLead = row
+            this.detailDialogVisible = true
+            this.detailPage.currentPage = 1
+            await this.detailOnLoad(this.detailPage)
+        },
+        
+        /**
+         * 查看详情
+         * @param {LeadRecord} row - 行数据
+         * @returns {void}
+         */
+        handleView(row) {
+            this.form = { ...row }
+            this.$refs.crud.rowView(row)
+        },
+        
+        /**
+         * 编辑
+         * @param {LeadRecord} row - 行数据
+         * @returns {void}
+         */
+        handleEdit(row) {
+            this.form = { ...row }
+            this.$refs.crud.rowEdit(row)
+        },
+        
+        /**
+         * 删除单行
+         * @param {LeadRecord} row - 行数据
+         * @returns {Promise<void>}
+         */
+        async handleRowDelete(row) {
+            try {
+                await this.$confirm(`确定删除线索 "${row.title}" 吗?`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                })
+        
+                // const res = await remove(row.id)
+                // if (res.data && res.data.success) {
+                //     this.$message.success('删除成功')
+                //     this.onLoad(this.page)
+                // } else {
+                //     this.$message.error(res.data ? res.data.msg : '删除失败')
+                // }
+            } catch (error) {
+                if (error !== 'cancel') {
+                    console.error('删除失败:', error)
+                    this.$message.error('删除失败,请稍后重试')
+                }
+            }
+        },
+        
+        // ========== 详细信息相关方法 ==========
+        
+        /**
+         * 详细信息数据加载
+         * @param {Object} page - 分页参数
+         * @param {Object} params - 查询参数
+         * @returns {Promise<void>}
+         */
+        async detailOnLoad(page, params = {}) {
+            if (!this.currentLead) return
+            
+            this.detailLoading = true
+            try {
+                const queryParams = {
+                    ...params,
+                    leadId: this.currentLead.id
+                }
+        
+                const res = await getDetailList(page.currentPage, page.pageSize, queryParams)
+                if (res.data && res.data.success) {
+                    const data = res.data.data
+                    this.detailData = data.records || []
+                    this.detailPage.total = data.total || 0
+                } else {
+                    this.detailData = []
+                    this.detailPage.total = 0
+                    this.$message.error(res.data ? res.data.msg : '获取详细信息失败')
+                }
+            } catch (error) {
+                this.detailData = []
+                this.detailPage.total = 0
+                console.error('获取详细信息失败:', error)
+                this.$message.error('获取详细信息失败,请稍后重试')
+            } finally {
+                this.detailLoading = false
+            }
+        },
+        
+        /**
+         * 详细信息新增前的回调
+         * @param {Function} done - 完成回调
+         * @param {string} type - 操作类型
+         * @returns {Promise<void>}
+         */
+        async detailBeforeOpen(done, type) {
+            if (['edit', 'view'].includes(type)) {
+                try {
+                    const res = await getDetailDetail(this.detailForm.id)
+                    if (res.data && res.data.success) {
+                        this.detailForm = res.data.data
+                    } else {
+                        this.$message.error('获取详情失败')
+                        return
+                    }
+                } catch (error) {
+                    console.error('获取详情失败:', error)
+                    this.$message.error('获取详情失败')
+                    return
+                }
+            } else if (type === 'add') {
+                // 新增时设置线索ID
+                this.detailForm.leadId = this.currentLead.id
+            }
+            done()
+        },
+        
+        /**
+         * 详细信息新增
+         * @param {LeadDetailRecord} row - 表单数据
+         * @param {Function} done - 完成回调
+         * @param {Function} loading - 加载状态回调
+         * @returns {Promise<void>}
+         */
+        async detailRowSave(row, done, loading) {
+            try {
+                loading()
+                const params = {
+                    leadId: this.currentLead.id,
+                    detailText: row.detailText
+                }
+                const res = await addDetail(params)
+                if (res.data && res.data.success) {
+                    this.$message.success('添加成功')
+                    this.detailOnLoad(this.detailPage)
+                    done()
+                } else {
+                    this.$message.error(res.data ? res.data.msg : '添加失败')
+                    loading()
+                }
+            } catch (error) {
+                console.error('添加失败:', error)
+                this.$message.error('添加失败,请稍后重试')
+                loading()
+            }
+        },
+        
+        /**
+         * 详细信息修改
+         * @param {LeadDetailRecord} row - 表单数据
+         * @param {number} index - 行索引
+         * @param {Function} done - 完成回调
+         * @param {Function} loading - 加载状态回调
+         * @returns {Promise<void>}
+         */
+        async detailRowUpdate(row, index, done, loading) {
+            try {
+                loading()
+                const params = {
+                    id: row.id,
+                    leadId: this.currentLead.id,
+                    detailText: row.detailText
+                }
+                const res = await updateDetail(params)
+                if (res.data && res.data.success) {
+                    this.$message.success('修改成功')
+                    this.detailOnLoad(this.detailPage)
+                    done()
+                } else {
+                    this.$message.error(res.data ? res.data.msg : '修改失败')
+                    loading()
+                }
+            } catch (error) {
+                console.error('修改失败:', error)
+                this.$message.error('修改失败,请稍后重试')
+                loading()
+            }
+        },
+        
+        /**
+         * 详细信息删除
+         * @param {LeadDetailRecord} row - 行数据
+         * @param {number} index - 行索引
+         * @returns {Promise<void>}
+         */
+        async detailRowDel(row, index) {
+            try {
+                const res = await removeDetail(row.id)
+                if (res.data && res.data.success) {
+                    this.$message.success('删除成功')
+                    this.detailOnLoad(this.detailPage)
+                } else {
+                    this.$message.error(res.data ? res.data.msg : '删除失败')
+                }
+            } catch (error) {
+                console.error('删除失败:', error)
+                this.$message.error('删除失败,请稍后重试')
+            }
+        },
+        
+        /**
+         * 详细信息选择变更
+         * @param {LeadDetailRecord[]} list - 选中的数据列表
+         * @returns {void}
+         */
+        detailSelectionChange(list) {
+            this.detailSelectionList = list
+        },
+        
+        /**
+         * 详细信息当前页变更
+         * @param {number} currentPage - 当前页码
+         * @returns {void}
+         */
+        detailCurrentChange(currentPage) {
+            this.detailPage.currentPage = currentPage
+        },
+        
+        /**
+         * 详细信息页大小变更
+         * @param {number} pageSize - 页大小
+         * @returns {void}
+         */
+        detailSizeChange(pageSize) {
+            this.detailPage.pageSize = pageSize
+        },
+        
+        /**
+         * 详细信息刷新变更
+         * @param {Object} page - 分页参数
+         * @returns {void}
+         */
+        detailRefreshChange(page) {
+            this.detailOnLoad(page)
+        },
+        
+        /**
+         * 批量删除详细信息
+         * @returns {Promise<void>}
+         */
+        async handleDetailDelete() {
+            if (this.detailSelectionList.length === 0) {
+                this.$message.warning('请选择要删除的数据')
+                return
+            }
+        
+            try {
+                await this.$confirm('确定删除选中的详细信息吗?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                })
+        
+                const res = await removeDetail(this.detailIds)
+                if (res.data && res.data.success) {
+                    this.$message.success('删除成功')
+                    this.detailOnLoad(this.detailPage)
+                    this.$refs.detailCrud.toggleSelection()
+                } else {
+                    this.$message.error(res.data ? res.data.msg : '删除失败')
+                }
+            } catch (error) {
+                if (error !== 'cancel') {
+                    console.error('删除失败:', error)
+                    this.$message.error('删除失败,请稍后重试')
+                }
+            }
+        }
+    },
+    
+    mounted() {
+        // 初始化加载客户选项
+        this.loadCustomerOptions()
+    },
+
+    beforeDestroy() {
+        // 清理定时器
+        if (this.customerSearchTimer) {
+            clearTimeout(this.customerSearchTimer)
+        }
+    }
+}

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov