diff --git a/src/api/crm/customer/index.ts b/src/api/crm/customer/index.ts index d149d4e78..6dbfc49d6 100644 --- a/src/api/crm/customer/index.ts +++ b/src/api/crm/customer/index.ts @@ -101,6 +101,11 @@ export const getCustomerSimpleList = async () => { return await request.get({ url: `/crm/customer/simple-list` }) } +// 模糊查询公司 +export const getCompanyList = async (params) => { + return await request.get({ url: `/crm/customer/fuzzyQueryCompany`, params }) +} + // ======================= 业务操作 ======================= // 客户转移 diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index 58b98ea14..16b0425ee 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -116,8 +116,8 @@ - {{ t('login.otherLogin') }} - + + diff --git a/src/views/crm/billtemplate/BillTemplateForm.vue b/src/views/crm/billtemplate/BillTemplateForm.vue index 09461b382..e6871a232 100644 --- a/src/views/crm/billtemplate/BillTemplateForm.vue +++ b/src/views/crm/billtemplate/BillTemplateForm.vue @@ -120,7 +120,19 @@ const open = async (id?: number, customerId?: number) => { formLoading.value = true try { formData.value = await BillTemplateApi.getBillTemplate(id) - formData.value.products = formData.value.productItems + formData.value.products = formData.value.productItems.map(v => { + return { + category: v.category, + detailType: v.detailType, + productName: v.name, + productId: v.productId, + productInvoice: v.productInvoice, + productInvoiceItems: v.productInvoiceItems, + serviceFeeInvoice: v.serviceFeeInvoice, + serviceFeeInvoiceItems: v.serviceFeeInvoiceItems, + productUnit: v.unit + } + }) } finally { formLoading.value = false } diff --git a/src/views/crm/billtemplate/components/index.vue b/src/views/crm/billtemplate/components/index.vue index 99e03cd28..fe3184e8a 100644 --- a/src/views/crm/billtemplate/components/index.vue +++ b/src/views/crm/billtemplate/components/index.vue @@ -92,7 +92,7 @@ - + 添加产品 + + 添加产品 @@ -130,7 +130,6 @@ watch( const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 const getList = (val: []) => { - console.log('%csrc/views/crm/billtemplate/components/index.vue:133 object', 'color: #007acc;', formData.value); for(let i = formData.value.length - 1; i >= 0; i--) { let obj = formData.value[i] if(!val.some(v => v.id === obj.productId)) formData.value.splice(i, 1) diff --git a/src/views/crm/billtemplate/index.vue b/src/views/crm/billtemplate/index.vue index 44d387dd5..e089d4739 100644 --- a/src/views/crm/billtemplate/index.vue +++ b/src/views/crm/billtemplate/index.vue @@ -77,7 +77,7 @@ - + - + @@ -34,6 +34,7 @@ @@ -72,6 +74,7 @@ :data="deptTree" :props="defaultProps" filterable + clearable check-strictly node-key="id" placeholder="请选择归属部门" @@ -109,7 +112,7 @@ - + + - - + + - - + + - + - + @@ -282,7 +286,12 @@ const formRules = reactive({ name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }], customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }], - statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }] + statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }], + saleStage: [{ required: true, message: '销售阶段不能为空', trigger: 'change' }], + paymentTerm: [{ required: true, message: '账期不能为空', trigger: 'change' }], + creditMethod: [{ required: true, message: '授信方式不能为空', trigger: 'change' }], + techSupport: [{ required: true, message: '技术需求支持不能为空', trigger: 'change' }], + }); const formRef = ref(); const userOptions = ref([]); @@ -323,8 +332,7 @@ watch( watch( () => formData.value.totalPrice, (newProducts) => { - console.log('%csrc/views/crm/business/BusinessForm.vue:326 111', 'color: #007acc;', 111); - formData.value.creditLimit = parseInt(newProducts / 365 * formData.value.creditCalcCycle) + formData.value.creditLimit = parseInt(newProducts / 365 * formData.value.creditCalcCycle) || '' }, { deep: true } @@ -349,9 +357,6 @@ const open = async (id?: number, customerId?: number) => { } } - if (!formType.value) { - formData.value.ownerUserId = useUserStore().getUser.id; - } }; const setList = (newProducts) => { @@ -370,8 +375,9 @@ const daysInMonth = new Date(currentDate.getFullYear(), currentMonth, 0).getDate const { push } = useRouter() const submitForm = async () => { - if (!productFormRef.value) return; - const valid = await productFormRef.value.validate(); + const productFormRef1 = await productFormRef.value.validate(); + if (!productFormRef1) return; + const valid = await formRef.value.validate(); if (!valid) return; formLoading.value = true; @@ -414,8 +420,9 @@ const resetForm = () => { const route = useRoute(); onMounted(async () => { - console.log('%csrc/views/crm/business/BusinessForm.vue:406 getStrDictOptions(DICT_TYPE.PAYMENT_TERM)', 'color: #007acc;', getStrDictOptions(DICT_TYPE.PAYMENT_TERM)); const customerId = route.query.customerId; + console.log('%csrc/views/crm/business/BusinessForm.vue:422 useUserStore().getUser.id', 'color: #007acc;', useUserStore().getUser.id); + formData.value.ownerUserId = customerId ? '' : useUserStore().getUser.id; formType.value = route.query.id; if (formType.value) open(formType.value, customerId) customerList.value = await CustomerApi.getCustomerSimpleList(); diff --git a/src/views/crm/business/components/BusinessProductForm.vue b/src/views/crm/business/components/BusinessProductForm.vue index 175149169..9bf435fad 100644 --- a/src/views/crm/business/components/BusinessProductForm.vue +++ b/src/views/crm/business/components/BusinessProductForm.vue @@ -68,7 +68,7 @@ - + 添加产品 + + 添加产品 diff --git a/src/views/crm/contact/ContactForm.vue b/src/views/crm/contact/ContactForm.vue index 8b81a8a24..72b501983 100644 --- a/src/views/crm/contact/ContactForm.vue +++ b/src/views/crm/contact/ContactForm.vue @@ -74,13 +74,6 @@ - - - - - - - @@ -99,8 +92,6 @@ - - @@ -113,7 +104,7 @@ - + diff --git a/src/views/crm/contract/detail/index.vue b/src/views/crm/contract/detail/index.vue index 788ba070f..8d57b1aa4 100644 --- a/src/views/crm/contract/detail/index.vue +++ b/src/views/crm/contract/detail/index.vue @@ -12,7 +12,7 @@ - + + 编辑 - 合同变更 - - - 进度 - + --> 详情 - - 删除 - + + 进度 + + + + 删除 + + handleCommand(command, scope.row)" + v-hasPermi="[ + 'crm:contract:update', + 'crm:contract:delete' + ]" + > + 更多 + + + + 提交审核 + + + 合同变更 + + + 删除 + + + + + @@ -271,6 +307,7 @@ import * as ContractApi from '@/api/crm/contract' import { DICT_TYPE } from '@/utils/dict' import { erpPriceInputFormatter, erpPriceTableColumnFormatter } from '@/utils' import * as CustomerApi from '@/api/crm/customer' +import { checkPermi } from '@/utils/permission' import { TabsPaneContext } from 'element-plus' defineOptions({ name: 'CrmContract' }) @@ -345,6 +382,22 @@ const handleChange = (row) => { router.push({ name: 'CrmContractChange', query: { id: row.id } }) } +/** 操作分发 */ +const handleCommand = (command: string, row: UserApi.UserVO) => { + switch (command) { + case 'handleSubmit': + handleSubmit(row) + break + case 'handleChange': + handleChange(row) + break + case 'handleDelete': + handleDelete(row.id) + break + default: + break + } +} /** 删除按钮操作 */ const handleDelete = async (id: number) => { diff --git a/src/views/crm/customer/CustomerForm.vue b/src/views/crm/customer/CustomerForm.vue index af53fd37a..190936b00 100644 --- a/src/views/crm/customer/CustomerForm.vue +++ b/src/views/crm/customer/CustomerForm.vue @@ -10,7 +10,20 @@ - + + + {{ item.name }} + {{ item.link }} + + @@ -126,7 +139,7 @@ --> - + @@ -163,6 +176,55 @@ --> + + + + + + + + { } finally { formLoading.value = false } - } + } + restaurants.value = await CustomerApi.getCompanyList({companyName: '小米科技有限责任公司'}) // 获得地区列表 areaList.value = await AreaApi.getAreaTree() // 获得用户列表 @@ -310,6 +380,49 @@ const submitForm = async () => { } } +// const loadAll = async (val) => { +// restaurants.value = await CustomerApi.getCompanyList({ +// companyName: val +// }) +// } + +interface RestaurantItem { + value: string + link: string +} +let timeout: ReturnType +const restaurants = ref([]) +const querySearchAsync = async (queryString: string, cb: (arg: any) => void) => { + let data = await CustomerApi.getCompanyList({ + companyName: queryString + }) + restaurants.value = data.list.map(v => { + return { + name: v.name, + value: v.name, + } + }) + console.log('%csrc/views/crm/customer/CustomerForm.vue:400 restaurants.value', 'color: #007acc;', restaurants.value); + const results = queryString + ? restaurants.value.filter(createFilter(queryString)) + : restaurants.value + + clearTimeout(timeout) + timeout = setTimeout(() => { + cb(results) + }, 3000 * Math.random()) +} +const createFilter = (queryString: string) => { + return (restaurant: RestaurantItem) => { + return ( + restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0 + ) + } +} + +const handleSelect = (item: Record) => { + console.log(item) +} /** 重置表单 */ const resetForm = () => { formData.value = { diff --git a/src/views/crm/customer/detail/CustomerDetailsInfo.vue b/src/views/crm/customer/detail/CustomerDetailsInfo.vue index fe240b9ba..c82b5c9f9 100644 --- a/src/views/crm/customer/detail/CustomerDetailsInfo.vue +++ b/src/views/crm/customer/detail/CustomerDetailsInfo.vue @@ -21,6 +21,9 @@ {{ customer.clueDeveloperName }} {{ customer.assistName }} {{ customer.industryId }} + {{ customer.maintainerName }} + {{ customer.contractorName }} + {{ customer.creditNo }} {{ customer.mobile }} {{ customer.telephone }} {{ customer.email }} diff --git a/src/views/crm/customer/detail/index.vue b/src/views/crm/customer/detail/index.vue index c3c9b3709..638e089ca 100644 --- a/src/views/crm/customer/detail/index.vue +++ b/src/views/crm/customer/detail/index.vue @@ -63,7 +63,7 @@ - + diff --git a/src/views/crm/customer/index.vue b/src/views/crm/customer/index.vue index 86bddc0e8..6e93345c1 100644 --- a/src/views/crm/customer/index.vue +++ b/src/views/crm/customer/index.vue @@ -125,14 +125,41 @@ - - - + + + + + {{scope.row.developerName || '暂无'}} + + + + + {{scope.row.contractorName || '暂无'}} + + + + + {{scope.row.ownerUserDeptName || '暂无'}} + + + + + {{scope.row.maintainerName || '暂无'}} + + + + + {{scope.row.assistName || '暂无'}} + + + + diff --git a/src/views/crm/quotation/QuotationDetail.vue b/src/views/crm/quotation/QuotationDetail.vue index 791b03525..49d00a80b 100644 --- a/src/views/crm/quotation/QuotationDetail.vue +++ b/src/views/crm/quotation/QuotationDetail.vue @@ -43,7 +43,14 @@ - + + + @@ -593,7 +600,6 @@ const resetForm = () => { const route = useRoute(); onMounted(async () => { - console.log('%csrc/views/crm/quotation/QuotationDetail.vue:596 props.id', 'color: #007acc;', props.id); formType.value = props.id || route.query.id if (formType.value) open(formType.value) diff --git a/src/views/crm/quotation/QuotationForm.vue b/src/views/crm/quotation/QuotationForm.vue index 771ee5ef0..593aa6d4c 100644 --- a/src/views/crm/quotation/QuotationForm.vue +++ b/src/views/crm/quotation/QuotationForm.vue @@ -28,7 +28,7 @@ - + 风控信息 @@ -59,52 +59,59 @@ - + + + - + - + - + - + - + - + - + - + - + 是 否 @@ -112,7 +119,7 @@ - + 是 否 @@ -120,7 +127,7 @@ - + 是 否 @@ -128,7 +135,7 @@ - + 是 否 @@ -136,7 +143,7 @@ - + 是 否 @@ -144,13 +151,14 @@ - + 是 否 + 需求信息 @@ -159,7 +167,7 @@ @@ -257,7 +265,7 @@ - + @@ -316,7 +324,7 @@ - + - + - + @@ -225,7 +225,24 @@ watch( }, { immediate: true } ) - +// 监听合同产品变化,计算合同产品总价 +watch( + () => formData.value, + (val) => { + if (!val || val.length === 0) { + return; + } + // 循环处理 + val.forEach((item) => { + if (item.offlinePrice != null && item.onlinePrice != null) { + item.totalPrice = Number((Number(item.offlinePrice) + Number(item.onlinePrice)).toFixed(2)); + } else { + item.totalPrice = 0; + } + }); + }, + { deep: true } +); /** 新增按钮操作 */ const handleAdd = () => { const row = { diff --git a/src/views/crm/quotation/index.vue b/src/views/crm/quotation/index.vue index 03af1f40a..043dba216 100644 --- a/src/views/crm/quotation/index.vue +++ b/src/views/crm/quotation/index.vue @@ -139,7 +139,8 @@ /> - + 编辑 - handleCommand(command, scope.row)" + v-hasPermi="[ + 'crm:quotation:delete', + 'crm:customer-suggestion:query', + 'system:permission:assign-user-role' + ]" > - 进度 - - - 删除 - + 更多 + + + + 进度 + + + 删除 + + + + + + @@ -192,6 +205,7 @@ import { QuotationApi, QuotationVO } from '@/api/crm/quotation' import * as CustomerApi from '@/api/crm/customer' import * as UserApi from '@/api/system/user' import * as DeptApi from '@/api/system/dept' +import { checkPermi } from '@/utils/permission' /** CRM 方案报价 列表 */ defineOptions({ name: 'Quotation' }) @@ -256,6 +270,19 @@ const openFormDetail = (row: Object) => { router.push({ name: 'QuotationDetail', query: { id: row.id } }) } +/** 操作分发 */ +const handleCommand = (command: string, row: UserApi.UserVO) => { + switch (command) { + case 'handleDelete': + handleDelete(row.id) + break + case 'handleProcessDetail': + handleProcessDetail(row) + break + default: + break + } +} /** 删除按钮操作 */ const handleDelete = async (id: number) => {