Browse Source

✨ CRM:完善商机的列表

YunaiV 1 year ago
parent
commit
a2443e48f7

+ 5 - 0
src/api/crm/product/index.ts

@@ -23,6 +23,11 @@ export const getProductPage = async (params) => {
   return await request.get({ url: `/crm/product/page`, params })
   return await request.get({ url: `/crm/product/page`, params })
 }
 }
 
 
+// 获得产品精简列表
+export const getProductSimpleList = async () => {
+  return await request.get({ url: `/crm/product/simple-list` })
+}
+
 // 查询产品详情
 // 查询产品详情
 export const getProduct = async (id: number) => {
 export const getProduct = async (id: number) => {
   return await request.get({ url: `/crm/product/get?id=` + id })
   return await request.get({ url: `/crm/product/get?id=` + id })

+ 173 - 183
src/views/crm/business/BusinessForm.vue

@@ -1,113 +1,127 @@
 <template>
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible">
+  <Dialog :title="dialogTitle" v-model="dialogVisible" width="1280">
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
-      label-width="100px"
+      label-width="120px"
       v-loading="formLoading"
       v-loading="formLoading"
     >
     >
-      <el-form-item label="商机名称" prop="name">
-        <el-input v-model="formData.name" placeholder="请输入商机名称" />
-      </el-form-item>
-      <!-- TODO 芋艿:客户列表的组件 -->
-      <el-form-item label="客户名称" prop="customerName">
-        <el-popover
-          placement="bottom"
-          :width="600"
-          trigger="click"
-          :teleported="false"
-          :visible="showCustomer"
-          :offset="10"
-        >
-          <template #reference>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="商机名称" prop="name">
+            <el-input v-model="formData.name" placeholder="请输入商机名称" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="负责人" prop="ownerUserId">
+            <el-select
+              v-model="formData.ownerUserId"
+              :disabled="formType !== 'create'"
+              class="w-1/1"
+            >
+              <el-option
+                v-for="item in userOptions"
+                :key="item.id"
+                :label="item.nickname"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="客户名称" prop="customerId">
+            <el-select v-model="formData.customerId" placeholder="请选择客户" class="w-1/1">
+              <el-option
+                v-for="item in customerList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="商机状态组" prop="statusTypeId">
+            <el-select
+              v-model="formData.statusTypeId"
+              placeholder="请选择商机状态组"
+              clearable
+              class="w-1/1"
+            >
+              <el-option
+                v-for="item in statusTypeList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="预计成交日期" prop="dealTime">
+            <el-date-picker
+              v-model="formData.dealTime"
+              type="date"
+              value-format="x"
+              placeholder="选择预计成交日期"
+              class="!w-1/1"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="备注" prop="remark">
+            <el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <!-- 子表的表单 -->
+      <ContentWrap>
+        <el-tabs v-model="subTabsName" class="-mt-15px -mb-10px">
+          <el-tab-pane label="产品清单" name="product">
+            <BusinessProductForm
+              ref="productFormRef"
+              :products="formData.products"
+              :disabled="disabled"
+            />
+          </el-tab-pane>
+        </el-tabs>
+      </ContentWrap>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="产品总金额" prop="totalProductPrice">
             <el-input
             <el-input
-              placeholder="请选择客户"
-              @click="openCustomerSelect"
-              v-model="formData.customerName"
+              disabled
+              v-model="formData.totalProductPrice"
+              :formatter="erpPriceInputFormatter"
             />
             />
-          </template>
-          <el-table :data="customerList" ref="multipleTableRef" @select="handleSelectionChange">
-            <el-table-column width="55" label="选择" type="selection" />
-            <el-table-column width="100" label="编号" property="id" />
-            <el-table-column width="150" label="客户名称" property="name" />
-            <el-table-column width="100" label="客户来源" prop="source" align="center">
-              <template #default="scope">
-                <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_SOURCE" :value="scope.row.source" />
-              </template>
-            </el-table-column>
-            <el-table-column label="客户级别" align="center" prop="level" width="120">
-              <template #default="scope">
-                <dict-tag :type="DICT_TYPE.CRM_CUSTOMER_LEVEL" :value="scope.row.level" />
-              </template>
-            </el-table-column>
-          </el-table>
-          <!-- 分页 -->
-          <el-row :gutter="20">
-            <el-col>
-              <Pagination
-                :total="total"
-                v-model:page="queryParams.pageNo"
-                v-model:limit="queryParams.pageSize"
-                @pagination="getCustomerList"
-                layout="sizes, prev, pager, next"
-              />
-            </el-col>
-          </el-row>
-          <el-row :gutter="20">
-            <el-col :span="10" :offset="13">
-              <el-button @click="selectCustomer">确认</el-button>
-              <el-button @click="showCustomer = false">取消</el-button>
-            </el-col>
-          </el-row>
-        </el-popover>
-      </el-form-item>
-      <!-- TODO @ljlleo:idea 红色的报错,可以解决下 -->
-      <el-form-item label="商机状态类型" prop="statusTypeId">
-        <el-select
-          v-model="formData.statusTypeId"
-          placeholder="请选择商机状态类型"
-          clearable
-          @change="changeBusinessStatusType"
-        >
-          <el-option
-            v-for="item in businessStatusTypeList"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="商机状态" prop="statusId">
-        <el-select v-model="formData.statusId" placeholder="请选择商机状态" clearable>
-          <el-option
-            v-for="item in businessStatusList"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="预计成交日期" prop="dealTime">
-        <el-date-picker
-          v-model="formData.dealTime"
-          type="date"
-          value-format="x"
-          placeholder="选择预计成交日期"
-        />
-      </el-form-item>
-      <el-form-item label="商机金额" prop="price">
-        <el-input v-model="formData.price" placeholder="请输入商机金额" />
-      </el-form-item>
-      <el-form-item label="整单折扣" prop="discountPercent">
-        <el-input v-model="formData.discountPercent" placeholder="请输入整单折扣" />
-      </el-form-item>
-      <el-form-item label="产品总金额" prop="productPrice">
-        <el-input v-model="formData.productPrice" placeholder="请输入产品总金额" />
-      </el-form-item>
-      <el-form-item label="备注" prop="remark">
-        <el-input v-model="formData.remark" placeholder="请输入备注" />
-      </el-form-item>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="整单折扣(%)" prop="discountPercent">
+            <el-input-number
+              v-model="formData.discountPercent"
+              placeholder="请输入整单折扣"
+              controls-position="right"
+              :min="0"
+              :precision="2"
+              class="!w-1/1"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="折扣后金额" prop="price">
+            <el-input
+              disabled
+              v-model="formData.totalPrice"
+              placeholder="请输入商机金额"
+              :formatter="erpPriceInputFormatter"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
     </el-form>
     </el-form>
     <template #footer>
     <template #footer>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
@@ -119,8 +133,10 @@
 import * as BusinessApi from '@/api/crm/business'
 import * as BusinessApi from '@/api/crm/business'
 import * as BusinessStatusTypeApi from '@/api/crm/businessStatusType'
 import * as BusinessStatusTypeApi from '@/api/crm/businessStatusType'
 import * as CustomerApi from '@/api/crm/customer'
 import * as CustomerApi from '@/api/crm/customer'
-import { DICT_TYPE } from '@/utils/dict'
-import { ElTable } from 'element-plus'
+import * as UserApi from '@/api/system/user'
+import { useUserStore } from '@/store/modules/user'
+import BusinessProductForm from './components/BusinessProductForm.vue'
+import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
 
 
 const { t } = useI18n() // 国际化
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
 const message = useMessage() // 消息弹窗
@@ -132,33 +148,53 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const formData = ref({
 const formData = ref({
   id: undefined,
   id: undefined,
   name: undefined,
   name: undefined,
-  statusTypeId: undefined,
-  statusId: undefined,
-  contactNextTime: undefined,
   customerId: undefined,
   customerId: undefined,
+  contactNextTime: undefined,
+  ownerUserId: undefined,
+  statusTypeId: undefined,
   dealTime: undefined,
   dealTime: undefined,
-  price: undefined,
-  discountPercent: undefined,
-  productPrice: undefined,
+  discountPercent: 0,
+  totalProductPrice: undefined,
+  totalPrice: undefined,
   remark: undefined,
   remark: undefined,
-  ownerUserId: undefined,
-  roUserIds: undefined,
-  rwUserIds: undefined,
-  endStatus: undefined,
-  endRemark: undefined,
-  contactLastTime: undefined,
-  followUpStatus: undefined
+  products: []
 })
 })
 const formRules = reactive({
 const formRules = reactive({
-  name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }]
+  name: [{ required: true, message: '商机名称不能为空', trigger: 'blur' }],
+  customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
+  ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
+  statusTypeId: [{ required: true, message: '商机状态组不能为空', trigger: 'blur' }]
 })
 })
 const formRef = ref() // 表单 Ref
 const formRef = ref() // 表单 Ref
-const businessStatusList = ref([]) // 商机状态列表
-const businessStatusTypeList = ref([]) //商机状态类型列表
-const loading = ref(true) // 列表的加载中
-const total = ref(0) // 列表的总页数
+const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
+const statusTypeList = ref([]) // 商机状态类型列表
+// TODO 芋艿:统一的客户选择面板
 const customerList = ref([]) // 客户列表的数据
 const customerList = ref([]) // 客户列表的数据
 
 
+/** 子表的表单 */
+const subTabsName = ref('product')
+const productFormRef = ref()
+
+/** 计算 discountPrice、totalPrice 价格 */
+watch(
+  () => formData.value,
+  (val) => {
+    if (!val) {
+      return
+    }
+    const totalProductPrice = val.products.reduce((prev, curr) => prev + curr.totalPrice, 0)
+    const discountPrice =
+      val.discountPercent != null
+        ? erpPriceMultiply(totalProductPrice, val.discountPercent / 100.0)
+        : 0
+    const totalPrice = totalProductPrice - discountPrice
+    // 赋值
+    formData.value.totalProductPrice = totalProductPrice
+    formData.value.totalPrice = totalPrice
+  },
+  { deep: true }
+)
+
 /** 打开弹窗 */
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
   dialogVisible.value = true
@@ -174,8 +210,15 @@ const open = async (type: string, id?: number) => {
       formLoading.value = false
       formLoading.value = false
     }
     }
   }
   }
+  customerList.value = await CustomerApi.getCustomerSimpleList()
   // 加载商机状态类型列表
   // 加载商机状态类型列表
-  businessStatusTypeList.value = await BusinessStatusTypeApi.getBusinessStatusTypeList()
+  statusTypeList.value = await BusinessStatusTypeApi.getBusinessStatusTypeList()
+  // 获得用户列表
+  userOptions.value = await UserApi.getSimpleUserList()
+  // 默认新建时选中自己
+  if (formType.value === 'create') {
+    formData.value.ownerUserId = useUserStore().getUser.id
+  }
 }
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
 
@@ -186,6 +229,7 @@ const submitForm = async () => {
   if (!formRef) return
   if (!formRef) return
   const valid = await formRef.value.validate()
   const valid = await formRef.value.validate()
   if (!valid) return
   if (!valid) return
+  await productFormRef.value.validate()
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
@@ -210,71 +254,17 @@ const resetForm = () => {
   formData.value = {
   formData.value = {
     id: undefined,
     id: undefined,
     name: undefined,
     name: undefined,
-    statusTypeId: undefined,
-    statusId: undefined,
-    contactNextTime: undefined,
     customerId: undefined,
     customerId: undefined,
+    contactNextTime: undefined,
+    ownerUserId: undefined,
+    statusTypeId: undefined,
     dealTime: undefined,
     dealTime: undefined,
-    price: undefined,
-    discountPercent: undefined,
-    productPrice: undefined,
+    discountPercent: 0,
+    totalProductPrice: undefined,
+    totalPrice: undefined,
     remark: undefined,
     remark: undefined,
-    ownerUserId: undefined,
-    roUserIds: undefined,
-    rwUserIds: undefined,
-    endStatus: undefined,
-    endRemark: undefined,
-    contactLastTime: undefined,
-    followUpStatus: undefined
+    products: []
   }
   }
   formRef.value?.resetFields()
   formRef.value?.resetFields()
 }
 }
-
-/** 加载商机状态列表 */
-const changeBusinessStatusType = async (typeId: number) => {
-  businessStatusList.value = await BusinessStatusTypeApi.getBusinessStatusListByTypeId(typeId)
-}
-
-const queryParams = reactive({
-  pageNo: 1,
-  pageSize: 10,
-  name: null,
-  mobile: null,
-  industryId: null,
-  level: null,
-  source: null,
-  pool: false
-})
-// 选择客户
-const showCustomer = ref(false)
-const openCustomerSelect = () => {
-  showCustomer.value = !showCustomer.value
-  queryParams.pageNo = 1
-  getCustomerList()
-}
-
-/** 查询客户列表 */
-const getCustomerList = async () => {
-  loading.value = true
-  try {
-    const data = await CustomerApi.getCustomerPage(queryParams)
-    customerList.value = data.list
-    total.value = data.total
-  } finally {
-    loading.value = false
-  }
-}
-const multipleTableRef = ref<InstanceType<typeof ElTable>>()
-const multipleSelection = ref()
-const handleSelectionChange = ({}, row) => {
-  multipleSelection.value = row
-  multipleTableRef.value!.clearSelection()
-  multipleTableRef.value!.toggleRowSelection(row, undefined)
-}
-
-const selectCustomer = () => {
-  formData.value.customerId = multipleSelection.value.id
-  formData.value.customerName = multipleSelection.value.name
-  showCustomer.value = !showCustomer.value
-}
 </script>
 </script>

+ 183 - 0
src/views/crm/business/components/BusinessProductForm.vue

@@ -0,0 +1,183 @@
+<template>
+  <el-form
+    ref="formRef"
+    :model="formData"
+    :rules="formRules"
+    v-loading="formLoading"
+    label-width="0px"
+    :inline-message="true"
+    :disabled="disabled"
+  >
+    <el-table :data="formData" class="-mt-10px">
+      <el-table-column label="序号" type="index" align="center" width="60" />
+      <el-table-column label="产品名称" min-width="180">
+        <template #default="{ row, $index }">
+          <el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!">
+            <el-select
+              v-model="row.productId"
+              clearable
+              filterable
+              @change="onChangeProduct($event, row)"
+              placeholder="请选择产品"
+            >
+              <el-option
+                v-for="item in productList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column label="条码" min-width="150">
+        <template #default="{ row }">
+          <el-form-item class="mb-0px!">
+            <el-input disabled v-model="row.productNo" />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column label="单位" min-width="80">
+        <template #default="{ row }">
+          <dict-tag :type="DICT_TYPE.CRM_PRODUCT_UNIT" :value="row.productUnit" />
+        </template>
+      </el-table-column>
+      <el-table-column label="价格(元)" min-width="120">
+        <template #default="{ row }">
+          <el-form-item class="mb-0px!">
+            <el-input disabled v-model="row.productPrice" :formatter="erpPriceInputFormatter" />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column label="售价(元)" fixed="right" min-width="140">
+        <template #default="{ row, $index }">
+          <el-form-item :prop="`${$index}.businessPrice`" class="mb-0px!">
+            <el-input-number
+              v-model="row.businessPrice"
+              controls-position="right"
+              :min="0.001"
+              :precision="2"
+              class="!w-100%"
+            />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column label="数量" prop="count" fixed="right" min-width="120">
+        <template #default="{ row, $index }">
+          <el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
+            <el-input-number
+              v-model="row.count"
+              controls-position="right"
+              :min="0.001"
+              :precision="3"
+              class="!w-100%"
+            />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column label="合计" prop="totalPrice" fixed="right" min-width="140">
+        <template #default="{ row, $index }">
+          <el-form-item :prop="`${$index}.totalPrice`" class="mb-0px!">
+            <el-input disabled v-model="row.totalPrice" :formatter="erpPriceInputFormatter" />
+          </el-form-item>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" fixed="right" label="操作" width="60">
+        <template #default="{ $index }">
+          <el-button @click="handleDelete($index)" link>—</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-form>
+  <el-row justify="center" class="mt-3" v-if="!disabled">
+    <el-button @click="handleAdd" round>+ 添加产品</el-button>
+  </el-row>
+</template>
+<script setup lang="ts">
+import * as ProductApi from '@/api/crm/product'
+import { erpCountInputFormatter, erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
+import { DICT_TYPE } from '@/utils/dict'
+
+const props = defineProps<{
+  products: undefined
+  disabled: false
+}>()
+const formLoading = ref(false) // 表单的加载中
+const formData = ref([])
+const formRules = reactive({
+  productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
+  businessPrice: [{ required: true, message: '合同价格不能为空', trigger: 'blur' }],
+  count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
+})
+const formRef = ref([]) // 表单 Ref
+const productList = ref<ProductApi.ProductVO[]>([]) // 产品列表
+
+/** 初始化设置产品项 */
+watch(
+  () => props.products,
+  async (val) => {
+    formData.value = val
+  },
+  { immediate: true }
+)
+
+/** 监听合同产品变化,计算合同产品总价 */
+watch(
+  () => formData.value,
+  (val) => {
+    if (!val || val.length === 0) {
+      return
+    }
+    // 循环处理
+    val.forEach((item) => {
+      if (item.businessPrice != null && item.count != null) {
+        item.totalPrice = erpPriceMultiply(item.businessPrice, item.count)
+      } else {
+        item.totalPrice = undefined
+      }
+    })
+  },
+  { deep: true }
+)
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  const row = {
+    id: undefined,
+    productId: undefined,
+    productUnit: undefined, // 产品单位
+    productNo: undefined, // 产品条码
+    productPrice: undefined, // 产品价格
+    businessPrice: undefined,
+    count: 1
+  }
+  formData.value.push(row)
+}
+
+/** 删除按钮操作 */
+const handleDelete = (index: number) => {
+  formData.value.splice(index, 1)
+}
+
+/** 处理产品变更 */
+const onChangeProduct = (productId, row) => {
+  const product = productList.value.find((item) => item.id === productId)
+  if (product) {
+    row.productUnit = product.unit
+    row.productNo = product.no
+    row.productPrice = product.price
+    row.businessPrice = product.price
+  }
+}
+
+/** 表单校验 */
+const validate = () => {
+  return formRef.value.validate()
+}
+defineExpose({ validate })
+
+/** 初始化 */
+onMounted(async () => {
+  productList.value = await ProductApi.getProductSimpleList()
+})
+</script>

+ 69 - 9
src/views/crm/business/index.vue

@@ -39,9 +39,31 @@
   <!-- 列表 -->
   <!-- 列表 -->
   <ContentWrap>
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-      <el-table-column label="商机名称" align="center" prop="name" />
-      <el-table-column label="客户名称" align="center" prop="customerName" />
-      <el-table-column label="商机金额" align="center" prop="price" />
+      <el-table-column align="center" label="商机名称" fixed="left" prop="name" width="160">
+        <template #default="scope">
+          <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
+            {{ scope.row.name }}
+          </el-link>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" fixed="left" label="客户名称" prop="customerName" width="120">
+        <template #default="scope">
+          <el-link
+            :underline="false"
+            type="primary"
+            @click="openCustomerDetail(scope.row.customerId)"
+          >
+            {{ scope.row.customerName }}
+          </el-link>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="商机金额(元)"
+        align="center"
+        prop="totalPrice"
+        width="140"
+        :formatter="erpPriceTableColumnFormatter"
+      />
       <el-table-column
       <el-table-column
         label="预计成交日期"
         label="预计成交日期"
         align="center"
         align="center"
@@ -49,9 +71,23 @@
         :formatter="dateFormatter"
         :formatter="dateFormatter"
         width="180px"
         width="180px"
       />
       />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="商机状态类型" align="center" prop="statusTypeName" />
-      <el-table-column label="商机状态" align="center" prop="statusName" />
+      <el-table-column align="center" label="备注" prop="remark" width="200" />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="下次联系时间"
+        prop="contactNextTime"
+        width="180px"
+      />
+      <el-table-column align="center" label="负责人" prop="ownerUserName" width="100px" />
+      <el-table-column align="center" label="所属部门" prop="ownerUserDeptName" width="100px" />
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="最后跟进时间"
+        prop="contactLastTime"
+        width="180px"
+      />
       <el-table-column
       <el-table-column
         label="更新时间"
         label="更新时间"
         align="center"
         align="center"
@@ -66,9 +102,21 @@
         :formatter="dateFormatter"
         :formatter="dateFormatter"
         width="180px"
         width="180px"
       />
       />
-      <el-table-column label="负责人" align="center" prop="ownerUserId" />
-      <el-table-column label="创建人" align="center" prop="creator" />
-      <el-table-column label="跟进状态" align="center" prop="followUpStatus" />
+      <el-table-column align="center" label="创建人" prop="creatorName" width="100px" />
+      <el-table-column
+        label="商机状态组"
+        align="center"
+        prop="statusTypeName"
+        fixed="right"
+        width="140"
+      />
+      <el-table-column
+        label="商机阶段"
+        align="center"
+        prop="statusName"
+        fixed="right"
+        width="120"
+      />
       <el-table-column label="操作" align="center" fixed="right" width="130px">
       <el-table-column label="操作" align="center" fixed="right" width="130px">
         <template #default="scope">
         <template #default="scope">
           <el-button
           <el-button
@@ -108,6 +156,7 @@ import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import download from '@/utils/download'
 import * as BusinessApi from '@/api/crm/business'
 import * as BusinessApi from '@/api/crm/business'
 import BusinessForm from './BusinessForm.vue'
 import BusinessForm from './BusinessForm.vue'
+import { erpPriceTableColumnFormatter } from '@/utils'
 
 
 defineOptions({ name: 'CrmBusiness' })
 defineOptions({ name: 'CrmBusiness' })
 
 
@@ -166,6 +215,17 @@ const resetQuery = () => {
   handleQuery()
   handleQuery()
 }
 }
 
 
+/** 打开客户详情 */
+const { currentRoute, push } = useRouter()
+const openDetail = (id: number) => {
+  push({ name: 'CrmBusinessDetail', params: { id } })
+}
+
+/** 打开客户详情 */
+const openCustomerDetail = (id: number) => {
+  push({ name: 'CrmCustomerDetail', params: { id } })
+}
+
 /** 添加/修改操作 */
 /** 添加/修改操作 */
 const formRef = ref()
 const formRef = ref()
 const openForm = (type: string, id?: number) => {
 const openForm = (type: string, id?: number) => {

+ 0 - 2
src/views/crm/contact/ContactForm.vue

@@ -206,7 +206,6 @@ const formRules = reactive({
   ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }]
   ownerUserId: [{ required: true, message: '负责人不能为空', trigger: 'blur' }]
 })
 })
 const formRef = ref() // 表单 Ref
 const formRef = ref() // 表单 Ref
-const ownerUserList = ref<any[]>([])
 const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
 const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
 // TODO 芋艿:统一的客户选择面板
 // TODO 芋艿:统一的客户选择面板
 const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
 const customerList = ref<CustomerApi.CustomerVO[]>([]) // 客户列表
@@ -288,6 +287,5 @@ const resetForm = () => {
     remark: undefined
     remark: undefined
   }
   }
   formRef.value?.resetFields()
   formRef.value?.resetFields()
-  ownerUserList.value = []
 }
 }
 </script>
 </script>

+ 1 - 6
src/views/crm/product/ProductForm.vue

@@ -104,7 +104,6 @@ import * as ProductCategoryApi from '@/api/crm/product/productCategory'
 import { defaultProps, handleTree } from '@/utils/tree'
 import { defaultProps, handleTree } from '@/utils/tree'
 import { getSimpleUserList, UserVO } from '@/api/system/user'
 import { getSimpleUserList, UserVO } from '@/api/system/user'
 import { useUserStore } from '@/store/modules/user'
 import { useUserStore } from '@/store/modules/user'
-import { fenToYuan, yuanToFen } from '@/utils'
 
 
 defineOptions({ name: 'CrmProductForm' })
 defineOptions({ name: 'CrmProductForm' })
 
 
@@ -149,7 +148,6 @@ const open = async (type: string, id?: number) => {
     formLoading.value = true
     formLoading.value = true
     try {
     try {
       formData.value = await ProductApi.getProduct(id)
       formData.value = await ProductApi.getProduct(id)
-      formData.value.price = Number(fenToYuan(formData.value.price))
     } finally {
     } finally {
       formLoading.value = false
       formLoading.value = false
     }
     }
@@ -169,10 +167,7 @@ const submitForm = async () => {
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
-    const data = {
-      ...formData.value,
-      price: yuanToFen(formData.value.price)
-    } as unknown as ProductApi.ProductVO
+    const data = formData.value as unknown as ProductApi.ProductVO
     if (formType.value === 'create') {
     if (formType.value === 'create') {
       await ProductApi.createProduct(data)
       await ProductApi.createProduct(data)
       message.success(t('common.createSuccess'))
       message.success(t('common.createSuccess'))

+ 2 - 1
src/views/crm/product/index.vue

@@ -68,7 +68,7 @@
         label="价格(元)"
         label="价格(元)"
         align="center"
         align="center"
         prop="price"
         prop="price"
-        :formatter="fenToYuanFormat"
+        :formatter="erpPriceTableColumnFormatter"
         width="100"
         width="100"
       />
       />
       <el-table-column label="产品描述" align="center" prop="description" width="150" />
       <el-table-column label="产品描述" align="center" prop="description" width="150" />
@@ -134,6 +134,7 @@ import download from '@/utils/download'
 import * as ProductApi from '@/api/crm/product'
 import * as ProductApi from '@/api/crm/product'
 import ProductForm from './ProductForm.vue'
 import ProductForm from './ProductForm.vue'
 import { fenToYuanFormat } from '@/utils/formatter'
 import { fenToYuanFormat } from '@/utils/formatter'
+import { erpPriceTableColumnFormatter } from '@/utils'
 
 
 defineOptions({ name: 'CrmProduct' })
 defineOptions({ name: 'CrmProduct' })