Browse Source

收入分析

2545307760@qq.com 2 months ago
parent
commit
07cfe5b017

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module server
+
+go 1.22.5

+ 2 - 0
server/api/v1/crm/customer.go

@@ -1,6 +1,7 @@
 package crm
 
 import (
+	"fmt"
 	"github.com/gin-gonic/gin"
 	"server/dao/crm"
 	"server/global"
@@ -30,6 +31,7 @@ func (ca *CustomerApi) QueryCustomerList(c *gin.Context) {
 		return
 	}
 	list, total, err := customerService.QueryCustomerList(info)
+	fmt.Print(list, total, err)
 	if err != nil {
 		response.FailWithMessage("查询失败", c)
 		global.GVA_LOG.Error("QueryCustomerList ====== " + err.Error())

+ 1 - 1
server/config.yaml

@@ -125,7 +125,7 @@ mysql:
     config: charset=utf8mb4&parseTime=True&loc=Local
     db-name: lc_finance
     username: root
-    password: root
+    password: 123456
     path: 127.0.0.1
     engine: ""
     log-mode: error

+ 6 - 1
server/dao/crm/customer.go

@@ -26,8 +26,13 @@ func QueryAllCustomers() (customers []Customer, err error) {
 	return customers, err
 }
 
-func QueryCustomerList(limit, offset int) (customers []Customer, total int64, err error) {
+func QueryCustomerList(limit, offset int, name string) (customers []Customer, total int64, err error) {
 	db := global.GVA_DB.Model(&Customer{})
+
+	if name != "" {
+		db = db.Where("name LIKE ?", "%"+name+"%")
+	}
+
 	err = db.Count(&total).Error
 	if err != nil {
 		return

+ 5 - 0
server/initialize/gorm.go

@@ -3,6 +3,7 @@ package initialize
 import (
 	"os"
 	"server/dao"
+	"server/dao/crm"
 	"server/dao/system"
 
 	"go.uber.org/zap"
@@ -84,6 +85,10 @@ func RegisterTables() {
 		dao.Place{},
 		dao.StorageArea{},
 		dao.StorageAreaGenre{},
+
+		crm.Customer{},
+		crm.CustomerGenre{},
+		crm.Progress{},
 	)
 	if err != nil {
 		global.GVA_LOG.Error("register table failed", zap.Error(err))

+ 1 - 1
server/service/crm/customer.go

@@ -14,7 +14,7 @@ func (cs *CustomerService) QueryAllCustomers() ([]crm.Customer, error) {
 func (cs *CustomerService) QueryCustomerList(info request.SearchCustomer) (customers []crm.Customer, total int64, err error) {
 	limit := info.PageInfo.PageSize
 	offset := info.PageInfo.PageSize * (info.PageInfo.Page - 1)
-	return crm.QueryCustomerList(limit, offset)
+	return crm.QueryCustomerList(limit, offset, info.Name)
 }
 
 func (cs *CustomerService) CreateCustomer(customer crm.Customer) error {

+ 2 - 2
web/.env.development

@@ -2,9 +2,9 @@ ENV = 'development'
 
 VITE_CLI_PORT = 8080
 VITE_SERVER_PORT = 8220
-VITE_BASE_API = /ap
+VITE_BASE_API = /api
 VITE_FILE_API = /api
-VITE_BASE_PATH = http://192.168.110.218
+VITE_BASE_PATH = http://127.0.0.1
 VITE_POSITION = close
 VITE_EDITOR = webstorm
 

+ 78 - 0
web/src/api/customer.js

@@ -0,0 +1,78 @@
+import service from '@/utils/request'
+
+// 查询所有客户
+export const getAllCustomers = () => {
+  return service({
+    url: '/customer/queryAllCustomers',
+    method: 'get',
+  })
+}
+
+// 查询客户列表
+export const getCustomerList = (data) => {
+  return service({
+    url: '/customer/queryCustomerList',
+    method: 'post',
+    data
+  })
+}
+
+// 新增用户
+export const postCustomer = (data) => {
+  return service({
+    url: '/customer/createCustomer',
+    method: 'post',
+    data
+  })
+}
+
+// 修改用户
+export const putCustomer = (data) => {
+  return service({
+    url: '/customer/updateCustomer',
+    method: 'put',
+    data
+  })
+}
+
+// 删除用户
+export const delCustomer = (id) => {
+  return service({
+    url: '/customer/deleteCustomer?id=' + id,
+    method: 'delete'
+  })
+}
+
+// 查询所有客户类型
+export const getCustomerType = () => {
+  return service({
+    url: '/customerGenre/queryAllCustomerGenres',
+    method: 'get'
+  })
+}
+
+// 新增客户类型
+export const postCustomerType = (data) => {
+  return service({
+    url: '/customerGenre/createCustomerGenre',
+    method: 'post',
+    data
+  })
+}
+
+// 修改客户类型
+export const putCustomerType = (data) => {
+  return service({
+    url: '/customerGenre/updateCustomerGenre',
+    method: 'put',
+    data
+  })
+}
+
+// 删除客户类型
+export const delCustomerType = (id) => {
+  return service({
+    url: '/customerGenre/deleteCustomerGenre?id=' + id,
+    method: 'delete',
+  })
+}

+ 446 - 0
web/src/view/customer/customer.vue

@@ -0,0 +1,446 @@
+<template>
+  <div>
+    <el-row style="height: 700px">
+      <el-col :span="24">
+        <el-card header="客户列表">
+          <div class="customerSearch">
+            <div>
+              <el-select
+                v-model="searchData.customerType"
+                placeholder="类型"
+                style="width: 120px"
+                clearable
+              >
+                <el-option
+                  v-for="item in userTypeList"
+                  :key="item.ID"
+                  :label="item.name"
+                  :value="item.ID"
+                />
+              </el-select>
+            </div>
+            <div style="margin-left: 40px">
+              <el-input
+                v-model="userJson.name"
+                style="max-width: 600px"
+                placeholder="联系人"
+                class="input-with-select"
+              >
+                <template #append>
+                  <el-button icon="Search" />
+                </template>
+              </el-input>
+            </div>
+            <div style="margin-left: 40px">
+              <el-button
+                icon="plus"
+                @click="addCustomerShow = true"
+              >
+                新增客户
+              </el-button>
+            </div>
+            <div style="margin-left: 40px">
+              <el-button
+                @click="userTypeShow = true"
+              >
+                客户类型
+              </el-button>
+            </div>
+          </div>
+          <el-table
+            height="605px"
+            border
+            stripe
+            :data="customerList"
+            size="small"
+          >
+            <el-table-column
+              label="客户名称"
+              prop="name"
+              align="center"
+            />
+            <el-table-column
+              label="客户电话"
+              prop="phone"
+              align="center"
+            />
+            <el-table-column
+              label="客户邮箱"
+              prop="email"
+              align="center"
+            />
+            <el-table-column
+              label="公司"
+              prop="company"
+              align="center"
+            />
+            <el-table-column
+              label="职位"
+              prop="posts"
+              align="center"
+            />
+            <el-table-column
+              label="客户类型"
+              prop="customerGenre.name"
+              align="center"
+            />
+            <el-table-column
+              label="直系上司"
+              prop="genre"
+              align="center"
+            />
+            <el-table-column
+              label="操作"
+              align="center"
+            >
+              <template #default="scope">
+                <el-button
+                  size="small"
+                  type="primary"
+                  text
+                  icon="Edit"
+                  @click="customerEdit(scope.row)"
+                >
+                  编辑
+                </el-button>
+                <el-button
+                  size="small"
+                  type="primary"
+                  text
+                  icon="delete"
+                  @click="deleteCustomer(scope.row)"
+                >
+                  删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-pagination
+            :current-page="pageSet.page"
+            :page-size="pageSet.pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="pageSet.total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+          />
+        </el-card>
+      </el-col>
+    </el-row>
+    <el-dialog
+      v-model="addCustomerShow"
+      width="35%"
+      title="新增客户"
+    >
+      <el-form
+        label-width="100px"
+        label-position="left"
+        size="large"
+      >
+        <el-form-item label="客户名称:">
+          <el-input
+            v-model="addCustomerJson.name"
+            placeholder="请输入客户名称"
+          />
+        </el-form-item>
+        <el-form-item label="客户电话:">
+          <el-input
+            v-model="addCustomerJson.phone"
+            placeholder="请输入客户电话"
+          />
+        </el-form-item>
+        <el-form-item label="客户邮箱:">
+          <el-input
+            v-model="addCustomerJson.email"
+            placeholder="请输入客户邮箱"
+          />
+        </el-form-item>
+        <el-form-item label="公司:">
+          <el-input
+            v-model="addCustomerJson.company"
+            placeholder="请输入公司名称"
+          />
+        </el-form-item>
+        <el-form-item label="职位:">
+          <el-input
+            v-model="addCustomerJson.posts"
+            placeholder="请输入公司职位"
+          />
+        </el-form-item>
+        <el-form-item label="客户类型:">
+          <el-select
+            v-model="addCustomerJson.genre"
+            placeholder="类型"
+            clearable
+            @clear="addCustomerJson.genre = 0"
+          >
+            <el-option
+              v-for="item in userTypeList"
+              :key="item.ID"
+              :label="item.name"
+              :value="item.ID"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="直系上司:">
+          <el-input
+            v-model="addCustomerJson.supervisorId"
+            placeholder="选填"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button
+          size="large"
+          type="primary"
+          @click="addCustomer"
+        >
+          确认
+        </el-button>
+      </template>
+    </el-dialog>
+    <el-dialog
+      v-model="userTypeShow"
+      title="费用类型"
+      width="40%"
+    >
+      <el-form>
+        <el-form-item
+          label="客户类型:"
+          size="large"
+        >
+          <el-input
+            v-model="changeUserValue"
+            style="width: 550px"
+            placeholder="请输入客户类型"
+          >
+            <template #prepend>
+              <el-select
+                v-model="userTypeSelect"
+                placeholder="请选择类型"
+                clearable
+                style="width: 140px"
+                @clear="clearUserType"
+              >
+                <el-option
+                  v-for="item in userTypeList"
+                  :key="item.ID"
+                  :label="item.name"
+                  :value="item.ID"
+                />
+              </el-select>
+            </template>
+            <template #append>
+              <el-button @click="delUserType">删除</el-button>
+            </template>
+          </el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button
+          type="primary"
+          size="large"
+          @click="editUserType"
+        >确定</el-button>
+      </template>
+    </el-dialog>
+    <el-drawer
+      v-model="editUserShow"
+      title="编辑客户"
+      width="40%"
+    >
+      <el-tabs>
+        <el-tab-pane label="基本信息"></el-tab-pane>
+        <el-tab-pane label="进度信息"></el-tab-pane>
+        <el-tab-pane label="需求信息"></el-tab-pane>
+      </el-tabs>
+    </el-drawer>
+  </div>
+</template>
+
+<script setup>
+import { reactive, onMounted, ref } from 'vue'
+import { getCustomerList, postCustomer, delCustomer, getCustomerType, postCustomerType, putCustomerType, delCustomerType } from '@/api/customer'
+import { ElMessage, ElMessageBox } from 'element-plus'
+defineOptions({
+  name: 'Customer'
+})
+
+const searchData = reactive({
+  contacts: '',
+  customerType: ''
+})
+
+const customerEdit = (scope) => {
+  editUserShow.value = true
+  console.log(scope)
+}
+
+const pageSet = reactive({
+  page: 1,
+  pageSize: 10,
+  total: 100
+})
+
+const handleCurrentChange = () => {}
+
+const handleSizeChange = () => {}
+
+// 客户类型
+const userTypeList = reactive([])
+
+// 查询客户类型
+const queryUserTypeList = () => {
+  getCustomerType().then(res => {
+    if (res.code === 0) {
+      userTypeList.length = 0
+      userTypeList.push(...res.data)
+    }
+  })
+}
+
+// 编辑客户类型
+const userTypeShow = ref(false)
+const userTypeSelect = ref(0)
+const changeUserValue = ref('')
+const clearUserType = () => {
+  userTypeSelect.value = 0
+}
+const editUserType = () => {
+  if (changeUserValue.value.length === 0) {
+    ElMessage.error('请输入需要编辑的客户类型')
+    return
+  }
+  if (userTypeSelect.value === 0) {
+    const postData = { name: changeUserValue.value }
+    postCustomerType(postData).then(res => {
+      if (res.code === 0) {
+        ElMessage.success('新增客户类型成功')
+        changeUserValue.value = ''
+        queryUserTypeList()
+      }
+    })
+  } else {
+    const putData = {
+      id: userTypeSelect.value,
+      name: changeUserValue.value
+    }
+    putCustomerType(putData).then(res => {
+      if (res.code === 0) {
+        ElMessage.success('修改客户类型成功')
+        userTypeSelect.value = 0
+        changeUserValue.value = ''
+        queryUserTypeList()
+      }
+    })
+  }
+}
+
+// 删除客户类型
+const delUserType = () => {
+  if (userTypeSelect.value === 0) {
+    ElMessage.error('请选择需要删除的客户类型')
+    return
+  }
+  delCustomerType(userTypeSelect.value).then(res => {
+    if (res.code === 0) {
+      userTypeSelect.value = 0
+      changeUserValue.value = ''
+      ElMessage.success('删除客户类型成功')
+      queryUserTypeList()
+    }
+  })
+}
+
+// 客户列表
+const userJson = reactive({
+  pageInfo: {
+    page: 1,
+    pageSize: 10
+  },
+  name: ''
+})
+const customerList = reactive([])
+const queryCustomerList = () => {
+  getCustomerList(userJson).then(res => {
+    if (res.code === 0) {
+      const list = res.data.list
+      customerList.length = 0
+      customerList.push(...list)
+    }
+  })
+}
+
+// 新增客户
+const addCustomerShow = ref(false)
+const addCustomerJson = reactive({
+  name: '刘总',
+  phone: '1823697451',
+  email: '405071532@qq.com',
+  company: '无',
+  posts: '总裁',
+  genre: 1,
+  supervisorId: 0
+})
+const addCustomer = () => {
+  for (const key in addCustomerJson) {
+    if (key === 'supervisorId') {
+      continue
+    }
+    if (addCustomerJson[key] === '' || addCustomerJson[key] === 0) {
+      ElMessage.error('请将除直系上司id以外的所有信心填写完整')
+      return
+    }
+  }
+  postCustomer(addCustomerJson).then(res => {
+    if (res.code === 0) {
+      queryCustomerList()
+      addCustomerShow.value = false
+      ElMessage.success('添加客户成功')
+    }
+  })
+}
+
+// 删除客户
+const deleteCustomer = (row) => {
+  ElMessageBox.confirm(
+    '确定删除此客户吗?',
+    '删除',
+    {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    }
+  )
+    .then(() => {
+      delCustomer(row.ID).then(res => {
+        if (res.code === 0) {
+          ElMessage.success('删除客户成功')
+          queryCustomerList()
+        }
+      })
+    })
+    .catch(() => {
+      ElMessage({
+        type: 'info',
+        message: '取消删除',
+      })
+    })
+}
+
+// 编辑客户信息
+const editUserShow = ref(false)
+
+onMounted(() => {
+  queryUserTypeList()
+  queryCustomerList()
+})
+</script>
+
+<style scoped lang="scss">
+  .customerSearch {
+    width: 100%;
+    height: 50px;
+    display: flex;
+  }
+</style>

+ 1 - 1
web/src/view/finance/firmPay/components/detailList.vue

@@ -458,7 +458,7 @@ const deleteCostType = () => {
     return
   }
   ElMessageBox.confirm(
-    '确定进行删除该费用类型吗?',
+    '确定删除此费用类型吗?',
     '删除',
     {
       confirmButtonText: '确定',