perf: filter by condition

This commit is contained in:
zchengo
2023-02-03 19:55:45 +08:00
parent 20dd98ec35
commit 54c3653197
7 changed files with 321 additions and 121 deletions
+20 -13
View File
@@ -52,23 +52,30 @@ func (c *ContractDao) Delete(param *models.ContractDeleteParam) error {
func (c *ContractDao) GetList(param *models.ContractQueryParam) ([]*models.ContractList, int64, error) {
contractList := make([]*models.ContractList, 0)
s := "contract.id, contract.name, contract.amount, contract.begin_time, contract.over_time, customer.name as cname, contract.remarks, contract.status, contract.created, contract.updated"
j := "inner join customer on contract.cid = customer.id and contract.creator = ?"
field := "contract.id, contract.name, contract.amount, contract.begin_time, contract.over_time, customer.name as cname, contract.remarks, contract.status, contract.created, contract.updated"
where := "inner join customer on contract.cid = customer.id and contract.creator = ?"
raw := "select count(*) from contract where creator = ?"
// 分页查询
offset := (param.Page.PageNum - 1) * param.Page.PageSize
mdb := global.Db.Offset(offset).Limit(param.Page.PageSize).Table(CONTRACT).Select(s)
var err error
if param.Id != 0 {
err = mdb.Joins(j+" and contract.id = ?", param.Creator, param.Id).Scan(&contractList).Error
} else {
err = mdb.Joins(j, param.Creator).Scan(&contractList).Error
}
if err != nil {
return nil, 0, err
}
db := global.Db.Offset(offset).Limit(param.Page.PageSize).Table(CONTRACT).Select(field)
var rows int64
global.Db.Raw("select count(*) from contract where creator = ?", param.Creator).Scan(&rows)
if param.Id != NumberNull {
db.Joins(where+" and contract.id = ?", param.Creator, param.Id)
global.Db.Raw(raw + " and contract.id = ?", param.Creator, param.Creator).Scan(&rows)
} else {
if param.Status != NumberNull {
db.Joins(where+" and contract.status = ?", param.Creator, param.Status)
global.Db.Raw(raw + " and contract.status = ?", param.Creator, param.Status).Scan(&rows)
} else {
db.Joins(where, param.Creator)
global.Db.Raw(raw, param.Creator).Scan(&rows)
}
}
if err := db.Scan(&contractList).Error; err != nil {
return nil, NumberNull, nil
}
return contractList, rows, nil
}
+6 -2
View File
@@ -62,8 +62,12 @@ func (c *CustomerDao) IsExists(name string, uid int64) bool {
func (c *CustomerDao) GetList(param *models.CustomerQueryParam) ([]*models.CustomerList, int64, error) {
customer := models.Customer{
Name: param.Name,
Creator: param.Creator,
Name: param.Name,
Source: param.Source,
Industry: param.Industry,
Level: param.Level,
Status: param.Status,
Creator: param.Creator,
}
customerList := make([]*models.CustomerList, 0)
rows, err := restPage(param.Page, CUSTOMER, customer, &customerList, &[]*models.CustomerList{})
+1
View File
@@ -52,6 +52,7 @@ type ContractQueryParam struct {
Id int64 `form:"id" binding:"omitempty,gt=0"`
Pids []int64 `form:"pids" json:"pids" binding:"-"`
Name string `form:"name" binding:"-"`
Status int `form:"status" binding:"omitempty,oneof=1 2"`
Creator int64 `form:"creator,omitempty" binding:"-"`
Page Page
}
+8 -5
View File
@@ -58,11 +58,14 @@ type CustomerDeleteParam struct {
}
type CustomerQueryParam struct {
Id int64 `form:"id" binding:"omitempty,gt=0"`
Name string `form:"name" binding:"-"`
Phone string `form:"phone" binding:"omitempty,len=11"`
Creator int64 `form:"creator,omitempty" binding:"-"`
Page Page
Id int64 `form:"id" binding:"omitempty,gt=0"`
Name string `form:"name" binding:"omitempty,gt=0"`
Source string `form:"source" binding:"omitempty,gt=0"`
Industry string `form:"industry" binding:"omitempty,gt=0"`
Level string `form:"level" binding:"omitempty,gt=0"`
Status int `form:"status" binding:"omitempty,oneof=1 2"`
Creator int64 `form:"creator,omitempty" binding:"-"`
Page Page
}
type CustomerList struct {
+75 -24
View File
@@ -2,20 +2,24 @@
<div :style="{ padding: '20px 20px 12px 20px' }">
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
<a-space>
<a-input v-model:value="keyWord" placeholder="合同编号" style="width: 280px; margin-right: 50px;">
<a-input v-model:value="query.id" placeholder="合同编号" style="width: 250px; margin-right: 10px;">
<template #suffix>
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
</template>
</a-input>
<a-button type="primary" @click="onContracts">全部合同</a-button>
<a-button :type="buttonType.bt1" @click="onContractList">全部合同</a-button>
<a-button :type="buttonType.bt2" @click="onContractStatus(1)">已签约合同</a-button>
<a-button :type="buttonType.bt3" @click="onContractStatus(2)">未签约合同</a-button>
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
<a-button type="primary" @click="onCreate">新建</a-button>
</a-space>
<div>
<a-button type="primary" @click="onExport">
<template #icon>
<ExportOutlined />
</template>导出</a-button>
<a-space size="middle">
<a-button type="primary" @click="onCreate">新建</a-button>
<a-button type="primary" @click="onExport" ghost>
<template #icon>
<ExportOutlined />
</template>导出</a-button>
</a-space>
</div>
</div>
<a-table rowKey="id"
@@ -180,6 +184,62 @@ import { queryCustomerOption } from "../api/customer";
import { message, Modal } from 'ant-design-vue';
import Spot from '../components/Spot.vue';
// 条件筛选
const query = reactive({
id: undefined,
status: undefined
})
// 点击搜索合同
const onSearch = () => {
contractList()
}
// 点击全部合同
const onContractList = () => {
query.id = undefined
query.status = undefined
pagination.current = 1
setButtonType()
contractList()
}
// 点击已签约或未签约合同
const onContractStatus = (status) => {
query.status = status
pagination.current = 1
setButtonType(status)
contractList()
}
// 按钮默认类型
const buttonType = reactive({
bt1: 'primary',
bt2: 'default',
bt3: 'default',
})
// 设置按钮类型
const setButtonType = (status) => {
switch (status) {
case 1:
buttonType.bt1 = 'default'
buttonType.bt2 = 'primary'
buttonType.bt3 = 'default'
break;
case 2:
buttonType.bt1 = 'default'
buttonType.bt2 = 'default'
buttonType.bt3 = 'primary'
break;
default:
buttonType.bt1 = 'primary'
buttonType.bt2 = 'default'
buttonType.bt3 = 'default'
break;
}
}
// 合同表格字段
const columns = [{
title: '合同编号',
@@ -358,15 +418,11 @@ let pagination = reactive({
total: undefined,
})
// 点击搜索
const onSearch = () => { getContractList() };
const title = ref('');
const visible = ref(false);
const disabled = ref(true)
const operation = ref(0);
const contractFormRef = ref();
const keyWord = ref('')
const productListVisible = ref(false);
// 点击新建合同
@@ -419,7 +475,7 @@ const onSave = () => {
if (res.data.code == 0) {
message.success('保存成功')
data.defaultSelectedIds = []
getContractList()
contractList()
}
})
}
@@ -439,7 +495,7 @@ const onSave = () => {
if (res.data.code == 0) {
message.success('保存成功')
data.defaultSelectedIds = []
getContractList()
contractList()
}
})
}
@@ -462,7 +518,7 @@ const onDelete = () => {
onOk() {
deleteContract(param).then((res) => {
if (res.data.code == 0) {
getContractList()
contractList()
disabled.value = true
message.success('删除成功')
}
@@ -475,22 +531,17 @@ const onDelete = () => {
}
// 初始化数据
onMounted(() => { getContractList() })
// 点击全部合同
const onContracts = () => {
keyWord.value = ''
getContractList()
}
onMounted(() => { contractList() })
// 分页查询合同列表
const onPagination = (page) => {
pagination.current = page
getContractList()
contractList(query.status)
}
const getContractList = () => {
const contractList = () => {
let param = {
id: parseInt(keyWord.value == '' ? '0' : keyWord.value),
id: parseInt(query.id == undefined || query.id == '' ? '0' : query.id),
status: query.status,
pageNum: pagination.current,
pageSize: pagination.pageSize
}
+169 -56
View File
@@ -2,21 +2,48 @@
<div :style="{ padding: '20px 20px 12px 20px' }">
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
<a-space>
<a-input v-model:value="keyWord" placeholder="客户名称" style="width: 280px; margin-right: 50px;">
<a-input v-model:value="query.name" placeholder="客户名称" style="width: 250px; margin-right: 10px;">
<template #suffix>
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="customerList()" />
</template>
</a-input>
<a-button type="primary" @click="onCustomers">全部客户</a-button>
<a-button :type="buttonType.bt1" @click="onCustomers">全部客户</a-button>
<a-button :type="buttonType.bt2" @click="onFilter">
<template #icon>
<FilterOutlined />
</template>高级筛选</a-button>
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
<a-button type="primary" @click="onCreate">新建</a-button>
</a-space>
<div>
<a-button type="primary" @click="onExport">
<template #icon>
<ExportOutlined />
</template>导出</a-button>
<a-space size="middle">
<a-button type="primary" @click="onCreate">新建</a-button>
<a-button type="primary" @click="onExport" ghost>
<template #icon>
<ExportOutlined />
</template>导出</a-button>
</a-space>
</div>
<a-modal v-model:visible="visibleFilter" title="高级筛选" @ok="confirmFilter" @cancel="cancelFilter"
cancelText="取消" okText="确定" width="800px" style="top: 150px;">
<a-row :gutter="20">
<a-col :span="6">
<a-select v-model:value="query.source" :options="options.source" placeholder="客户来源"
style="width: 100%;" :allowClear="true" />
</a-col>
<a-col :span="6">
<a-select v-model:value="query.industry" :options="options.industry" placeholder="客户行业"
style="width: 100%;" :allowClear="true" />
</a-col>
<a-col :span="6">
<a-select v-model:value="query.level" :options="options.level" placeholder="客户级别"
style="width: 100%;" :allowClear="true" />
</a-col>
<a-col :span="6">
<a-select v-model:value="query.status" :options="options.status" placeholder="成交状态"
style="width: 100%;" :allowClear="true" />
</a-col>
</a-row>
</a-modal>
</div>
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
:columns="columns" :data-source="data.customerList"
@@ -58,15 +85,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="客户来源" name="source">
<a-select v-model:value="customer.source" placeholder="请选择">
<a-select-option value="促销">促销</a-select-option>
<a-select-option value="搜索引擎">搜索引擎</a-select-option>
<a-select-option value="广告">广告</a-select-option>
<a-select-option value="转介绍">转介绍</a-select-option>
<a-select-option value="线上注册">线上注册</a-select-option>
<a-select-option value="电话咨询">电话咨询</a-select-option>
<a-select-option value="邮件咨询">邮件咨询</a-select-option>
</a-select>
<a-select v-model:value="customer.source" :options="options.source" placeholder="请选择" />
</a-form-item>
</a-col>
</a-row>
@@ -85,32 +104,21 @@
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="客户行业" name="industry">
<a-select v-model:value="customer.industry" placeholder="请选择">
<a-select-option value="互联网">互联网</a-select-option>
<a-select-option value="金融业">金融业</a-select-option>
<a-select-option value="政府">政府</a-select-option>
<a-select-option value="房地产">房地产</a-select-option>
<a-select-option value="文化传媒">文化传媒</a-select-option>
<a-select-option value="生产">生产</a-select-option>
<a-select-option value="物流运输">物流运输</a-select-option>
</a-select>
<a-select v-model:value="customer.industry" :options="options.industry"
placeholder="请选择" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="客户级别" name="level">
<a-select v-model:value="customer.level" placeholder="请选择">
<a-select-option value="重点客户">重点客户</a-select-option>
<a-select-option value="普通客户">普通客户</a-select-option>
<a-select-option value="非优先客户">非优先客户</a-select-option>
</a-select>
<a-select v-model:value="customer.level" :options="options.level" placeholder="请选择" />
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="所在地区" name="region">
<a-cascader v-model:value="customer.region" @change="selectedOptions" :options="options"
placeholder="请选择" style="width: 100%" />
<a-cascader v-model:value="customer.region" @change="selectedOptions"
:options="options.regionData" placeholder="请选择" style="width: 100%" />
</a-form-item>
</a-col>
<a-col :span="12">
@@ -177,7 +185,7 @@
<script setup>
import { ref, reactive, onMounted, createVNode } from 'vue';
import { SearchOutlined, ExclamationCircleOutlined, ExportOutlined, PhoneTwoTone, MailTwoTone, InboxOutlined } from '@ant-design/icons-vue';
import { SearchOutlined, ExclamationCircleOutlined, FilterOutlined, ExportOutlined, PhoneTwoTone, MailTwoTone, InboxOutlined } from '@ant-design/icons-vue';
import moment from 'moment'
import { createCustomer, updateCustomer, sendMailToCustomer, queryCustomerList, queryCustomerInfo, deleteCustomer, customerExport } from '../api/customer';
import { message, Modal } from 'ant-design-vue';
@@ -185,6 +193,121 @@ import Spot from '../components/Spot.vue';
import { fileRemove } from '../api/common';
import regionData from '../assets/region';
// 条件筛选
const query = reactive({
name: undefined,
source: undefined,
industry: undefined,
level: undefined,
status: undefined,
})
// 按钮类型
const buttonType = reactive({
bt1: 'primary',
bt2: 'default',
})
// 点击全部客户
const onCustomers = () => {
buttonType.bt1 = 'primary'
buttonType.bt2 = 'default'
for (const key in query) {
query[key] = undefined
}
customerList()
}
const visibleFilter = ref(false)
// 点击高级筛选
const onFilter = () => {
buttonType.bt1 = 'default'
buttonType.bt2 = 'primary'
visibleFilter.value = true
}
// 确认筛选
const confirmFilter = () => {
customerList()
visibleFilter.value = false
}
// 取消筛选
const cancelFilter = () => {
buttonType.bt1 = 'primary'
buttonType.bt2 = 'default'
for (const key in query) {
query[key] = undefined
}
}
// 表单选项
const options = reactive({
source: [{
value: '促销',
label: '促销',
}, {
value: '搜索引擎',
label: '搜索引擎',
}, {
value: '广告',
label: '广告',
}, {
value: '转介绍',
label: '转介绍',
}, {
value: '线上注册',
label: '线上注册',
}, {
value: '电话咨询',
label: '电话咨询',
}, {
value: '邮件咨询',
label: '邮件咨询',
}],
industry: [{
value: '互联网',
label: '互联网',
}, {
value: '金融业',
label: '金融业',
}, {
value: '政府',
label: '政府',
}, {
value: '房地产',
label: '房地产',
}, {
value: '文化传媒',
label: '文化传媒',
}, {
value: '生产',
label: '生产',
}, {
value: '物流运输',
label: '物流运输',
}],
level: [{
value: '重点客户',
label: '重点客户',
}, {
value: '普通客户',
label: '普通客户',
}, {
value: '非优先客户',
label: '非优先客户',
}],
status: [{
value: 1,
label: '已成交',
}, {
value: 2,
label: '未成交',
}],
regionData
})
// 表格字段
const columns = [{
title: '客户名称',
@@ -278,17 +401,6 @@ const onSelectChange = selectedRowKeys => {
}
};
// 点击搜索
const onSearch = () => {
getCustomerList()
};
// 点击全部客户
const onCustomers = () => {
keyWord.value = ''
getCustomerList()
}
// 客户属性
let customer = reactive({
id: undefined,
@@ -316,7 +428,6 @@ const visible = ref(false);
const disabled = ref(true)
const operation = ref(0);
const customerFormRef = ref();
const keyWord = ref('')
const visibleMail = ref(false)
// 点击新建客户
@@ -363,7 +474,7 @@ const onSave = () => {
message.success('保存成功')
customerFormRef.value.resetFields()
visible.value = false;
getCustomerList()
customerList()
}
if (res.data.code == 20001) {
message.error('客户名称已经存在')
@@ -376,7 +487,7 @@ const onSave = () => {
message.success('保存成功')
customerFormRef.value.resetFields()
visible.value = false;
getCustomerList()
customerList()
}
})
}
@@ -397,7 +508,7 @@ const onDelete = () => {
onOk() {
deleteCustomer(param).then((res) => {
if (res.data.code == 0) {
getCustomerList()
customerList()
disabled.value = true
message.success('删除成功')
}
@@ -412,15 +523,19 @@ const onDelete = () => {
// 分页查询客户列表
const onPagination = (page) => {
pagination.current = page
getCustomerList()
customerList()
}
// 初始化数据
onMounted(() => { getCustomerList() })
onMounted(() => { customerList() })
const getCustomerList = () => {
const customerList = () => {
let param = {
name: keyWord.value,
name: query.name,
source: query.source,
industry: query.industry,
level: query.level,
status: query.status,
pageNum: pagination.current,
pageSize: pagination.pageSize,
}
@@ -533,9 +648,7 @@ const onSend = () => {
const onCancel = () => {
customerFormRef.value.resetFields()
visible.value = false
};
const options = regionData
}
const selectedOptions = (value) => {
customer.region = value
+42 -21
View File
@@ -2,20 +2,24 @@
<div :style="{ padding: '20px 20px 12px 20px' }">
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
<a-space>
<a-input v-model:value="keyWord" placeholder="产品名称" style="width: 280px; margin-right: 50px;">
<a-input v-model:value="keyWord" placeholder="产品名称" style="width: 280px; margin-right: 10px;">
<template #suffix>
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="productList(0)" />
</template>
</a-input>
<a-button type="primary" @click="onProducts">全部产品</a-button>
<a-button :type="buttonType.bt1" @click="productList(0)">全部产品</a-button>
<a-button :type="buttonType.bt2" @click="productList(1)">上架的产品</a-button>
<a-button :type="buttonType.bt3" @click="productList(2)">下架的产品</a-button>
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
<a-button type="primary" @click="onCreate">新建</a-button>
</a-space>
<div>
<a-button type="primary" @click="onExport">
<a-space size="middle">
<a-button type="primary" @click="onCreate">新建</a-button>
<a-button type="primary" @click="onExport" ghost>
<template #icon>
<ExportOutlined />
</template>导出</a-button>
</a-space>
</div>
</div>
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
@@ -208,8 +212,32 @@ const operation = ref(0);
const productFormRef = ref();
const keyWord = ref('')
// 按钮状态
const buttonType = reactive({
bt1: 'primary',
bt2: 'default',
bt3: 'default',
})
const setButtonType = (status) => {
if (status == 0) {
buttonType.bt1 = 'primary'
buttonType.bt2 = 'default'
buttonType.bt3 = 'default'
}
if (status == 1) {
buttonType.bt1 = 'default'
buttonType.bt2 = 'primary'
buttonType.bt3 = 'default'
}
if (status == 2) {
buttonType.bt1 = 'default'
buttonType.bt2 = 'default'
buttonType.bt3 = 'primary'
}
}
// 初始化数据
onMounted(() => { getProductList() })
onMounted(() => { productList() })
// 表格记录多选
const onSelectChange = selectedRowKeys => {
@@ -221,15 +249,6 @@ const onSelectChange = selectedRowKeys => {
}
};
// 点击搜索
const onSearch = () => { getProductList() };
// 点击全部产品
const onProducts = () => {
keyWord.value = ''
getProductList()
}
// 点击新建产品
const onCreate = () => {
title.value = '新建产品'
@@ -267,7 +286,7 @@ const onSave = () => {
message.success('保存成功')
productFormRef.value.resetFields()
visible.value = false;
getProductList()
productList()
}
if (res.data.code == 40001) {
message.error('产品名称已经存在')
@@ -280,7 +299,7 @@ const onSave = () => {
productFormRef.value.resetFields()
visible.value = false;
message.success('保存成功')
getProductList()
productList()
}
})
}
@@ -298,7 +317,7 @@ const onDelete = () => {
onOk() {
deleteProduct({ ids: data.selectedIds }).then((res) => {
if (res.data.code == 0) {
getProductList()
productList()
disabled.value = true
message.success('删除成功')
}
@@ -313,13 +332,15 @@ const onDelete = () => {
// 分页查询产品列表
const onPagination = (page) => {
pagination.current = page
getProductList()
productList()
}
// 查询产列表
const getProductList = () => {
// 获取产品列表
const productList = (status) => {
setButtonType(status)
let param = {
name: keyWord.value,
status: status,
pageNum: pagination.current,
pageSize: pagination.pageSize,
}