feat: export excel file
This commit is contained in:
@@ -91,3 +91,18 @@ func (p *ContractApi) QueryPlist(context *gin.Context) {
|
|||||||
productList, errCode := p.contractService.QueryPlist(¶m)
|
productList, errCode := p.contractService.QueryPlist(¶m)
|
||||||
response.Result(errCode, productList, context)
|
response.Result(errCode, productList, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (c *ContractApi) Export(context *gin.Context) {
|
||||||
|
uid, _ := strconv.Atoi(context.Request.Header.Get("uid"))
|
||||||
|
if uid <= 0 {
|
||||||
|
response.Result(response.ErrCodeParamInvalid, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, errCode := c.contractService.Export(int64(uid))
|
||||||
|
if len(file) >= 0 && errCode != 0 {
|
||||||
|
response.Result(errCode, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.File(file)
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,3 +91,18 @@ func (c *CustomerApi) QueryOption(context *gin.Context) {
|
|||||||
customerOption, errCode := c.customerService.QueryOption(int64(uid))
|
customerOption, errCode := c.customerService.QueryOption(int64(uid))
|
||||||
response.Result(errCode, customerOption, context)
|
response.Result(errCode, customerOption, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (c *CustomerApi) Export(context *gin.Context) {
|
||||||
|
uid, _ := strconv.Atoi(context.Request.Header.Get("uid"))
|
||||||
|
if uid <= 0 {
|
||||||
|
response.Result(response.ErrCodeParamInvalid, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, errCode := c.customerService.Export(int64(uid))
|
||||||
|
if len(file) >= 0 && errCode != 0 {
|
||||||
|
response.Result(errCode, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.File(file)
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,3 +80,18 @@ func (p *ProductApi) QueryInfo(context *gin.Context) {
|
|||||||
productInfo, errCode := p.productService.QueryInfo(¶m)
|
productInfo, errCode := p.productService.QueryInfo(¶m)
|
||||||
response.Result(errCode, productInfo, context)
|
response.Result(errCode, productInfo, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (p *ProductApi) Export(context *gin.Context) {
|
||||||
|
uid, _ := strconv.Atoi(context.Request.Header.Get("uid"))
|
||||||
|
if uid <= 0 {
|
||||||
|
response.Result(response.ErrCodeParamInvalid, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, errCode := p.productService.Export(int64(uid))
|
||||||
|
if len(file) >= 0 && errCode != 0 {
|
||||||
|
response.Result(errCode, nil, context)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.File(file)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crm/global"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/xuri/excelize/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenExcelFile[T any](sheet string, columns []string, rowValue []T, filename string) (string, error) {
|
||||||
|
f := excelize.NewFile()
|
||||||
|
index := f.NewSheet(sheet)
|
||||||
|
for i := 0; i < len(columns); i++ {
|
||||||
|
axis := string(letter[i]) + strconv.Itoa(1)
|
||||||
|
f.SetCellValue(sheet, axis, columns[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
num := 2
|
||||||
|
for r := 0; r < len(rowValue); r++ {
|
||||||
|
v := reflect.ValueOf(rowValue[r])
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
axis := string(letter[i]) + strconv.Itoa(num)
|
||||||
|
f.SetCellValue(sheet, axis, v.Field(i))
|
||||||
|
}
|
||||||
|
num++
|
||||||
|
}
|
||||||
|
f.SetActiveSheet(index)
|
||||||
|
path := global.Config.File.Path + filename + ".xlsx"
|
||||||
|
|
||||||
|
if err := f.SaveAs(path); err != nil {
|
||||||
|
log.Printf("[ERROR] file save error: %s", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ func Router() {
|
|||||||
|
|
||||||
route := engine.Group("/api")
|
route := engine.Group("/api")
|
||||||
|
|
||||||
{
|
{
|
||||||
// 用户模块,订阅模块
|
// 用户模块,订阅模块
|
||||||
route.GET("/user/verifycode", api.NewUserApi().GetVerifyCode)
|
route.GET("/user/verifycode", api.NewUserApi().GetVerifyCode)
|
||||||
route.GET("/user/info", api.NewUserApi().GetInfo)
|
route.GET("/user/info", api.NewUserApi().GetInfo)
|
||||||
@@ -37,6 +37,7 @@ func Router() {
|
|||||||
route.GET("/customer/list", api.NewCustomerApi().QueryList)
|
route.GET("/customer/list", api.NewCustomerApi().QueryList)
|
||||||
route.GET("/customer/info", api.NewCustomerApi().QueryInfo)
|
route.GET("/customer/info", api.NewCustomerApi().QueryInfo)
|
||||||
route.GET("/customer/option", api.NewCustomerApi().QueryOption)
|
route.GET("/customer/option", api.NewCustomerApi().QueryOption)
|
||||||
|
route.GET("/customer/export", api.NewCustomerApi().Export)
|
||||||
route.POST("/customer/create", api.NewCustomerApi().Create)
|
route.POST("/customer/create", api.NewCustomerApi().Create)
|
||||||
route.PUT("/customer/update", api.NewCustomerApi().Update)
|
route.PUT("/customer/update", api.NewCustomerApi().Update)
|
||||||
route.DELETE("/customer/delete", api.NewCustomerApi().Delete)
|
route.DELETE("/customer/delete", api.NewCustomerApi().Delete)
|
||||||
@@ -44,6 +45,7 @@ func Router() {
|
|||||||
// 合同模块
|
// 合同模块
|
||||||
route.GET("/contract/list", api.NewContractApi().QueryList)
|
route.GET("/contract/list", api.NewContractApi().QueryList)
|
||||||
route.GET("/contract/info", api.NewContractApi().QueryInfo)
|
route.GET("/contract/info", api.NewContractApi().QueryInfo)
|
||||||
|
route.GET("/contract/export", api.NewContractApi().Export)
|
||||||
route.POST("/contract/plist", api.NewContractApi().QueryPlist)
|
route.POST("/contract/plist", api.NewContractApi().QueryPlist)
|
||||||
route.PUT("/contract/update", api.NewContractApi().Update)
|
route.PUT("/contract/update", api.NewContractApi().Update)
|
||||||
route.POST("/contract/create", api.NewContractApi().Create)
|
route.POST("/contract/create", api.NewContractApi().Create)
|
||||||
@@ -52,6 +54,7 @@ func Router() {
|
|||||||
// 产品模块
|
// 产品模块
|
||||||
route.GET("/product/list", api.NewProductApi().QueryList)
|
route.GET("/product/list", api.NewProductApi().QueryList)
|
||||||
route.GET("/product/info", api.NewProductApi().QueryInfo)
|
route.GET("/product/info", api.NewProductApi().QueryInfo)
|
||||||
|
route.GET("/product/export", api.NewProductApi().Export)
|
||||||
route.POST("/product/create", api.NewProductApi().Create)
|
route.POST("/product/create", api.NewProductApi().Create)
|
||||||
route.PUT("/product/update", api.NewProductApi().Update)
|
route.PUT("/product/update", api.NewProductApi().Update)
|
||||||
route.DELETE("/product/delete", api.NewProductApi().Delete)
|
route.DELETE("/product/delete", api.NewProductApi().Delete)
|
||||||
@@ -62,7 +65,7 @@ func Router() {
|
|||||||
// 订阅模块
|
// 订阅模块
|
||||||
route.GET("/subscribe/info", api.NewSubscribeApi().GetInfo)
|
route.GET("/subscribe/info", api.NewSubscribeApi().GetInfo)
|
||||||
route.POST("/subscribe/pay", api.NewSubscribeApi().Pay)
|
route.POST("/subscribe/pay", api.NewSubscribeApi().Pay)
|
||||||
route.POST("/subscribe/notify", api.NewSubscribeApi().Notify)
|
route.POST("/subscribe/notify", api.NewSubscribeApi().Notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动、监听端口
|
// 启动、监听端口
|
||||||
|
|||||||
@@ -91,6 +91,18 @@ type Products struct {
|
|||||||
Total float64 `json:"total"`
|
Total float64 `json:"total"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContractExcelRow struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Cname string `json:"cname"`
|
||||||
|
Amount float64 `json:"amount"`
|
||||||
|
BeginTime string `json:"beginTime"`
|
||||||
|
OverTime string `json:"overTime"`
|
||||||
|
Remarks string `json:"remarks"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Updated string `json:"updated"`
|
||||||
|
}
|
||||||
|
|
||||||
type Productlist []*Products
|
type Productlist []*Products
|
||||||
|
|
||||||
func (p *Productlist) Value() (driver.Value, error) {
|
func (p *Productlist) Value() (driver.Value, error) {
|
||||||
|
|||||||
@@ -91,3 +91,19 @@ type CustomerOption struct {
|
|||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CustomerExcelRow struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Industry string `json:"industry"`
|
||||||
|
Level string `json:"level"`
|
||||||
|
Remarks string `json:"remarks"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Creator int64 `json:"creator"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Updated string `json:"updated"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -73,3 +73,15 @@ type ProductInfo struct {
|
|||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProductExcelRow struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Updated string `json:"updated"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const (
|
|||||||
ErrCodeUserPassResetFailed = 10009 // 用户密码重置失败
|
ErrCodeUserPassResetFailed = 10009 // 用户密码重置失败
|
||||||
|
|
||||||
ErrCodePayFailed = 20001 // 支付宝支付失败
|
ErrCodePayFailed = 20001 // 支付宝支付失败
|
||||||
|
|
||||||
|
ErrCodeFileExportFailed = 30001 // 文件导出失败
|
||||||
)
|
)
|
||||||
|
|
||||||
var msg = map[int]string{
|
var msg = map[int]string{
|
||||||
@@ -39,4 +41,5 @@ var msg = map[int]string{
|
|||||||
ErrCodeCompanyCreateFailed: "company create failed",
|
ErrCodeCompanyCreateFailed: "company create failed",
|
||||||
ErrCodeEmailFormatInvalid: "email format invalid",
|
ErrCodeEmailFormatInvalid: "email format invalid",
|
||||||
ErrCodeUserPassResetFailed: "user password reset failed",
|
ErrCodeUserPassResetFailed: "user password reset failed",
|
||||||
|
ErrCodeFileExportFailed: "file export failed",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crm/common"
|
||||||
"crm/global"
|
"crm/global"
|
||||||
"crm/models"
|
"crm/models"
|
||||||
"crm/response"
|
"crm/response"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -97,7 +99,7 @@ func (c *ContractService) QueryInfo(param *models.ContractQueryParam) (*models.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 在编辑合同中,添加产品后,返回已添加的产品列表
|
// 在编辑合同中,添加产品后,返回已添加的产品列表
|
||||||
func (p *ContractService) QueryPlist(param *models.ContractQueryParam) ([]*models.Products, int) {
|
func (c *ContractService) QueryPlist(param *models.ContractQueryParam) ([]*models.Products, int) {
|
||||||
if param.Id == 0 {
|
if param.Id == 0 {
|
||||||
products := make([]*models.Products, 0)
|
products := make([]*models.Products, 0)
|
||||||
if err := global.Db.Table(PRODUCT).Find(&products, param.Pids).Error; err != nil {
|
if err := global.Db.Table(PRODUCT).Find(&products, param.Pids).Error; err != nil {
|
||||||
@@ -141,3 +143,43 @@ func (p *ContractService) QueryPlist(param *models.ContractQueryParam) ([]*model
|
|||||||
addedProductList = append(addedProductList, products...)
|
addedProductList = append(addedProductList, products...)
|
||||||
return addedProductList, response.ErrCodeSuccess
|
return addedProductList, response.ErrCodeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (c *ContractService) Export(uid int64) (string, int) {
|
||||||
|
contracts := 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 := "left join customer on contract.cid = customer.id and contract.creator = ?"
|
||||||
|
err := global.Db.Table(CONTRACT).Select(s).Joins(j, uid).Scan(&contracts).Error
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFailed
|
||||||
|
}
|
||||||
|
excelRows := make([]models.ContractExcelRow, 0)
|
||||||
|
var row models.ContractExcelRow
|
||||||
|
for _, c := range contracts {
|
||||||
|
row.Name = c.Name
|
||||||
|
row.Cname = c.Cname
|
||||||
|
row.Amount = c.Amount
|
||||||
|
row.BeginTime = c.BeginTime
|
||||||
|
row.OverTime = c.OverTime
|
||||||
|
row.Remarks = c.Remarks
|
||||||
|
if c.Status == 1 {
|
||||||
|
row.Status = "已签约"
|
||||||
|
}
|
||||||
|
if c.Status == 2 {
|
||||||
|
row.Status = "未签约"
|
||||||
|
}
|
||||||
|
row.Created = time.Unix(c.Created, 0).Format("2006-01-02")
|
||||||
|
if c.Updated != 0 {
|
||||||
|
row.Updated = time.Unix(c.Updated, 0).Format("2006-01-02")
|
||||||
|
}
|
||||||
|
excelRows = append(excelRows, row)
|
||||||
|
}
|
||||||
|
sheet := "合同信息"
|
||||||
|
columns := []string{"合同名称", "客户名称", "合同金额", "合同开始时间", "合同结束时间", "备注", "签约状态", "创建时间", "更新时间"}
|
||||||
|
fileName := "contract_" + strconv.FormatInt(uid, 10)
|
||||||
|
file, err := common.GenExcelFile(sheet, columns, excelRows, fileName)
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFailed
|
||||||
|
}
|
||||||
|
return file, response.ErrCodeSuccess
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crm/common"
|
||||||
"crm/global"
|
"crm/global"
|
||||||
"crm/models"
|
"crm/models"
|
||||||
"crm/response"
|
"crm/response"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -102,3 +104,44 @@ func (c *CustomerService) QueryOption(uid int64) ([]*models.CustomerOption, int)
|
|||||||
}
|
}
|
||||||
return option, response.ErrCodeSuccess
|
return option, response.ErrCodeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (c *CustomerService) Export(uid int64) (string, int) {
|
||||||
|
customers := make([]models.Customer, 0)
|
||||||
|
err := global.Db.Where("creator = ?", uid).Find(&customers).Error
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFailed
|
||||||
|
}
|
||||||
|
excelRows := make([]models.CustomerExcelRow, 0)
|
||||||
|
var row models.CustomerExcelRow
|
||||||
|
for _, c := range customers {
|
||||||
|
row.Name = c.Name
|
||||||
|
row.Source = c.Source
|
||||||
|
row.Phone = c.Phone
|
||||||
|
row.Email = c.Email
|
||||||
|
row.Industry = c.Industry
|
||||||
|
row.Level = c.Level
|
||||||
|
row.Remarks = c.Remarks
|
||||||
|
row.Region = c.Region
|
||||||
|
row.Address = c.Address
|
||||||
|
if c.Status == 1 {
|
||||||
|
row.Status = "已签约"
|
||||||
|
}
|
||||||
|
if c.Status == 2 {
|
||||||
|
row.Status = "未签约"
|
||||||
|
}
|
||||||
|
row.Created = time.Unix(c.Created, 0).Format("2006-01-02")
|
||||||
|
if c.Updated != 0 {
|
||||||
|
row.Updated = time.Unix(c.Updated, 0).Format("2006-01-02")
|
||||||
|
}
|
||||||
|
excelRows = append(excelRows, row)
|
||||||
|
}
|
||||||
|
sheet := "客户信息"
|
||||||
|
columns := []string{"名称", "客户来源", "手机号", "邮箱", "客户行业", "客户级别", "备注", "地区", "详细地址", "成交状态", "创建时间", "更新时间"}
|
||||||
|
fileName := "customer_" + strconv.FormatInt(uid, 10)
|
||||||
|
file, err := common.GenExcelFile(sheet, columns, excelRows, fileName)
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFailed
|
||||||
|
}
|
||||||
|
return file, response.ErrCodeSuccess
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crm/common"
|
||||||
"crm/global"
|
"crm/global"
|
||||||
"crm/models"
|
"crm/models"
|
||||||
"crm/response"
|
"crm/response"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,3 +87,43 @@ func (p *ProductService) QueryInfo(param *models.ProductQueryParam) (*models.Pro
|
|||||||
}
|
}
|
||||||
return &productInfo, response.ErrCodeSuccess
|
return &productInfo, response.ErrCodeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出Excel文件
|
||||||
|
func (p *ProductService) Export(uid int64) (string, int) {
|
||||||
|
products := make([]models.Product, 0)
|
||||||
|
err := global.Db.Where("creator = ?", uid).Find(&products).Error
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFileExportFailed
|
||||||
|
}
|
||||||
|
excelRows := make([]models.ProductExcelRow, 0)
|
||||||
|
var row models.ProductExcelRow
|
||||||
|
for _, p := range products {
|
||||||
|
row.Name = p.Name
|
||||||
|
if p.Status == 1 {
|
||||||
|
row.Status = "已上架"
|
||||||
|
}
|
||||||
|
if p.Status == 2 {
|
||||||
|
row.Status = "已下架"
|
||||||
|
}
|
||||||
|
if p.Type == 1 {
|
||||||
|
row.Type = "默认"
|
||||||
|
}
|
||||||
|
row.Unit = p.Unit
|
||||||
|
row.Code = p.Code
|
||||||
|
row.Price = p.Price
|
||||||
|
row.Description = p.Description
|
||||||
|
row.Created = time.Unix(p.Created, 0).Format("2006-01-02")
|
||||||
|
if p.Updated != 0 {
|
||||||
|
row.Updated = time.Unix(p.Updated, 0).Format("2006-01-02")
|
||||||
|
}
|
||||||
|
excelRows = append(excelRows, row)
|
||||||
|
}
|
||||||
|
sheet := "产品信息"
|
||||||
|
columns := []string{"名称", "是否上下架", "类型", "单位", "编码", "价格", "描述", "创建时间", "更新时间"}
|
||||||
|
fileName := "product_" + strconv.FormatInt(uid, 10)
|
||||||
|
file, err := common.GenExcelFile(sheet, columns, excelRows, fileName)
|
||||||
|
if err != nil {
|
||||||
|
return StringNull, response.ErrCodeFileExportFailed
|
||||||
|
}
|
||||||
|
return file, response.ErrCodeSuccess
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,4 +52,14 @@ export function queryContractPlist(param) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: param,
|
data: param,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出Excel表格
|
||||||
|
export function contractExport(param) {
|
||||||
|
return request({
|
||||||
|
url: '/contract/export',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob',
|
||||||
|
params: param,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -52,4 +52,14 @@ export function queryCustomerOption(param) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params: param,
|
params: param,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出Excel表格
|
||||||
|
export function customerExport(param) {
|
||||||
|
return request({
|
||||||
|
url: '/customer/export',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob',
|
||||||
|
params: param,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -43,4 +43,14 @@ export function queryProductList(param) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params: param,
|
params: param,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出Excel表格
|
||||||
|
export function productExport(param) {
|
||||||
|
return request({
|
||||||
|
url: '/product/export',
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob',
|
||||||
|
params: param,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
+45
-17
@@ -1,15 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-space style="margin-bottom: 20px; width: 100%;">
|
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
|
||||||
<a-input v-model:value="keyWord" placeholder="合同编号" style="width: 280px; margin-right: 50px;">
|
<a-space>
|
||||||
<template #suffix>
|
<a-input v-model:value="keyWord" placeholder="合同编号" style="width: 280px; margin-right: 50px;">
|
||||||
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
<template #suffix>
|
||||||
</template>
|
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
||||||
</a-input>
|
</template>
|
||||||
<a-button type="primary" @click="onContracts">全部合同</a-button>
|
</a-input>
|
||||||
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
<a-button type="primary" @click="onContracts">全部合同</a-button>
|
||||||
<a-button type="primary" @click="onCreate">新建</a-button>
|
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
||||||
</a-space>
|
<a-button type="primary" @click="onCreate">新建</a-button>
|
||||||
|
</a-space>
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" @click="onExport">
|
||||||
|
<template #icon>
|
||||||
|
<DownloadOutlined />
|
||||||
|
</template>导出</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<a-table rowKey="id"
|
<a-table rowKey="id"
|
||||||
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectedConteactIds, getCheckboxProps: defaultSelected }"
|
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectedConteactIds, getCheckboxProps: defaultSelected }"
|
||||||
:columns="columns" :data-source="data.contractList"
|
:columns="columns" :data-source="data.contractList"
|
||||||
@@ -63,14 +71,14 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="合同开始时间" name="beginTime">
|
<a-form-item label="合同开始时间" name="beginTime">
|
||||||
<a-date-picker v-model:value="contract.beginTime" placeholder="选择日期"
|
<a-date-picker v-model:value="contract.beginTime" placeholder="选择日期" style="width: 100%"
|
||||||
style="width: 100%" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/>
|
format="YYYY-MM-DD" valueFormat="YYYY-MM-DD" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="合同结束时间" name="overTime">
|
<a-form-item label="合同结束时间" name="overTime">
|
||||||
<a-date-picker v-model:value="contract.overTime" placeholder="选择日期"
|
<a-date-picker v-model:value="contract.overTime" placeholder="选择日期" style="width: 100%"
|
||||||
style="width: 100%" format="YYYY-MM-DD" valueFormat="YYYY-MM-DD"/>
|
format="YYYY-MM-DD" valueFormat="YYYY-MM-DD" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -164,9 +172,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, onMounted, createVNode } from 'vue';
|
import { ref, reactive, onMounted, createVNode } from 'vue';
|
||||||
import { SearchOutlined, ExclamationCircleOutlined, UpCircleOutlined, DownCircleOutlined } from '@ant-design/icons-vue';
|
import { SearchOutlined, ExclamationCircleOutlined, UpCircleOutlined, DownCircleOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { createContract, updateContract, queryContractList, queryContractInfo, deleteContract, queryContractPlist } from '../api/contract';
|
import { createContract, updateContract, queryContractList, queryContractInfo, deleteContract, queryContractPlist, contractExport } from '../api/contract';
|
||||||
import { queryProductList } from "../api/product";
|
import { queryProductList } from "../api/product";
|
||||||
import { queryCustomerOption } from "../api/customer";
|
import { queryCustomerOption } from "../api/customer";
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
@@ -175,7 +183,8 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
UpCircleOutlined,
|
UpCircleOutlined,
|
||||||
DownCircleOutlined
|
DownCircleOutlined,
|
||||||
|
DownloadOutlined
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
@@ -612,6 +621,24 @@ export default {
|
|||||||
visible.value = false
|
visible.value = false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 导出表格
|
||||||
|
const onExport = () => {
|
||||||
|
contractExport().then((res) => {
|
||||||
|
if (res.data.type == 'application/json'){
|
||||||
|
message.error('导出错误!')
|
||||||
|
} else {
|
||||||
|
let blob = new Blob([res.data], {
|
||||||
|
type: "application/vnd.ms-excel"
|
||||||
|
})
|
||||||
|
let a = document.createElement('a')
|
||||||
|
a.setAttribute("download", "合同信息.xlsx");
|
||||||
|
a.href = window.URL.createObjectURL(blob)
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(a.href)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 点击取消产品列表
|
// 点击取消产品列表
|
||||||
const onCancelProductList = () => {
|
const onCancelProductList = () => {
|
||||||
productListVisible.value = false
|
productListVisible.value = false
|
||||||
@@ -652,6 +679,7 @@ export default {
|
|||||||
delProduct,
|
delProduct,
|
||||||
pagination,
|
pagination,
|
||||||
onPagination,
|
onPagination,
|
||||||
|
onExport,
|
||||||
onContracts,
|
onContracts,
|
||||||
onPaginationProduct,
|
onPaginationProduct,
|
||||||
};
|
};
|
||||||
|
|||||||
+41
-14
@@ -1,16 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-space style="margin-bottom: 20px; width: 100%;">
|
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
|
||||||
<a-input v-model:value="keyWord" placeholder="客户名称" style="width: 280px; margin-right: 50px;">
|
<a-space>
|
||||||
<template #suffix>
|
<a-input v-model:value="keyWord" placeholder="客户名称" style="width: 280px; margin-right: 50px;">
|
||||||
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
<template #suffix>
|
||||||
</template>
|
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
||||||
</a-input>
|
</template>
|
||||||
<a-button type="primary" @click="onCustomers">全部客户</a-button>
|
</a-input>
|
||||||
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
<a-button type="primary" @click="onCustomers">全部客户</a-button>
|
||||||
<a-button type="primary" @click="onCreate">新建</a-button>
|
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
||||||
</a-space>
|
<a-button type="primary" @click="onCreate">新建</a-button>
|
||||||
|
</a-space>
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" @click="onExport">
|
||||||
|
<template #icon>
|
||||||
|
<DownloadOutlined />
|
||||||
|
</template>导出</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
|
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
|
||||||
:columns="columns" :data-source="data.customerList"
|
:columns="columns" :data-source="data.customerList"
|
||||||
:pagination="{ current: pagination.current, pageSize: pagination.pageSize, total: pagination.total, onChange: onPagination }"
|
:pagination="{ current: pagination.current, pageSize: pagination.pageSize, total: pagination.total, onChange: onPagination }"
|
||||||
@@ -119,15 +126,16 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, onMounted, createVNode } from 'vue';
|
import { ref, reactive, onMounted, createVNode } from 'vue';
|
||||||
import { SearchOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
import { SearchOutlined, ExclamationCircleOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { createCustomer, updateCustomer, queryCustomerList, queryCustomerInfo, deleteCustomer } from '../api/customer';
|
import { createCustomer, updateCustomer, queryCustomerList, queryCustomerInfo, deleteCustomer, customerExport } from '../api/customer';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
import regionData from '../assets/region';
|
import regionData from '../assets/region';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SearchOutlined
|
SearchOutlined,
|
||||||
|
DownloadOutlined
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const columns = [{
|
const columns = [{
|
||||||
@@ -366,6 +374,24 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出表格
|
||||||
|
const onExport = () => {
|
||||||
|
customerExport().then((res) => {
|
||||||
|
if (res.data.type == 'application/json'){
|
||||||
|
message.error('导出错误!')
|
||||||
|
} else {
|
||||||
|
let blob = new Blob([res.data], {
|
||||||
|
type: "application/vnd.ms-excel"
|
||||||
|
})
|
||||||
|
let a = document.createElement('a')
|
||||||
|
a.setAttribute("download", "客户信息.xlsx");
|
||||||
|
a.href = window.URL.createObjectURL(blob)
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(a.href)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 点击取消按钮
|
// 点击取消按钮
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
customerFormRef.value.resetFields()
|
customerFormRef.value.resetFields()
|
||||||
@@ -399,6 +425,7 @@ export default {
|
|||||||
onCancel,
|
onCancel,
|
||||||
onDelete,
|
onDelete,
|
||||||
getCustomerList,
|
getCustomerList,
|
||||||
|
onExport,
|
||||||
keyWord,
|
keyWord,
|
||||||
options,
|
options,
|
||||||
onPagination,
|
onPagination,
|
||||||
|
|||||||
+40
-12
@@ -1,15 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-space style="margin-bottom: 20px; width: 100%;">
|
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;">
|
||||||
<a-input v-model:value="keyWord" placeholder="产品名称" style="width: 280px; margin-right: 50px;">
|
<a-space>
|
||||||
<template #suffix>
|
<a-input v-model:value="keyWord" placeholder="产品名称" style="width: 280px; margin-right: 50px;">
|
||||||
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
<template #suffix>
|
||||||
</template>
|
<search-outlined style="color: rgba(0, 0, 0, 0.45)" @click="onSearch" />
|
||||||
</a-input>
|
</template>
|
||||||
<a-button type="primary" @click="onProducts">全部产品</a-button>
|
</a-input>
|
||||||
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
<a-button type="primary" @click="onProducts">全部产品</a-button>
|
||||||
<a-button type="primary" @click="onCreate">新建</a-button>
|
<a-button type="primary" @click="onDelete" :disabled="disabled" danger>删除</a-button>
|
||||||
</a-space>
|
<a-button type="primary" @click="onCreate">新建</a-button>
|
||||||
|
</a-space>
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" @click="onExport">
|
||||||
|
<template #icon>
|
||||||
|
<DownloadOutlined />
|
||||||
|
</template>导出</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
|
<a-table rowKey="id" :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
|
||||||
:columns="columns" :data-source="data.productList"
|
:columns="columns" :data-source="data.productList"
|
||||||
:pagination="{ current: pagination.current, pageSize: pagination.pageSize, total: pagination.total, onChange: onPagination }"
|
:pagination="{ current: pagination.current, pageSize: pagination.pageSize, total: pagination.total, onChange: onPagination }"
|
||||||
@@ -99,14 +107,15 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, onMounted, createVNode } from 'vue';
|
import { ref, reactive, onMounted, createVNode } from 'vue';
|
||||||
import { SearchOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
import { SearchOutlined, ExclamationCircleOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { createProduct, updateProduct, queryProductList, deleteProduct, queryProductInfo } from '../api/product';
|
import { createProduct, updateProduct, queryProductList, deleteProduct, queryProductInfo, productExport } from '../api/product';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
|
DownloadOutlined
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
// 表格字段
|
// 表格字段
|
||||||
@@ -318,6 +327,24 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出表格
|
||||||
|
const onExport = () => {
|
||||||
|
productExport().then((res) => {
|
||||||
|
if (res.data.type == 'application/json'){
|
||||||
|
message.error('导出错误!')
|
||||||
|
} else {
|
||||||
|
let blob = new Blob([res.data], {
|
||||||
|
type: "application/vnd.ms-excel"
|
||||||
|
})
|
||||||
|
let a = document.createElement('a')
|
||||||
|
a.setAttribute("download", "产品信息.xlsx");
|
||||||
|
a.href = window.URL.createObjectURL(blob)
|
||||||
|
a.click()
|
||||||
|
window.URL.revokeObjectURL(a.href)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 点击取消按钮
|
// 点击取消按钮
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
productFormRef.value.resetFields()
|
productFormRef.value.resetFields()
|
||||||
@@ -343,6 +370,7 @@ export default {
|
|||||||
onCancel,
|
onCancel,
|
||||||
onDelete,
|
onDelete,
|
||||||
getProductList,
|
getProductList,
|
||||||
|
onExport,
|
||||||
keyWord,
|
keyWord,
|
||||||
pagination,
|
pagination,
|
||||||
onPagination,
|
onPagination,
|
||||||
|
|||||||
Reference in New Issue
Block a user