当前位置: 首页 > wzjs >正文

大鹏网站建设全媒体运营师培训

大鹏网站建设,全媒体运营师培训,如何建设黔货出山电子商务网站,中国电商平台排行榜前十简介 工作一年多了,天天CRUD,终于以前学习的算法排上用场了。 背景 我们的系统在用户注册时没有校验身份id(身份证)和电话号码的唯一,可能使用相同的身份id或者电话号码创建多个账号,导致有些人开多个账…

简介

工作一年多了,天天CRUD,终于以前学习的算法排上用场了。

背景

我们的系统在用户注册时没有校验身份id(身份证)和电话号码的唯一,可能使用相同的身份id或者电话号码创建多个账号,导致有些人开多个账号领多份钱。现在公司想降本增效,让我统计出各个市场存在相同身份id或者电话号码的账号信息。

输入

两张表已过滤本次统计不涉及的字段
ops_tab
(operator 是站点员工表)
在这里插入图片描述

staff_tab
(员工表,里面包含的信息更详细。staff包括operator和driver,因此ops_tab的数据是staff_tab的子集)
在这里插入图片描述
ops_tab没有PassportId,因此需要拿staff Id去staff_tab获取对应passport id。

另外各个市场判断账号是否来自于同一个人是有差别的,有些市场允许多个账号使用同一个电话号码。

市场判断条件
印度尼西亚ID1、PassportId 2、Phone Number
马来西亚MY1、PassportId 2、Phone Number
菲律宾PH1、PassportId 2、Phone Number
新加坡SG1、PassportId 2、Phone Number
泰国TH1、Phone Number
台湾TW1、PassportId
越南VN1、PassportId 2、Phone Number

比如印度尼西亚就不允许Passport Id和电话号码重复,而泰国允许Passport Id重复而电话号码不能重复。

输出

输出excel,相同信息在同一个组,只统计存在重复信息的账号,不重复的不需要展示。
在这里插入图片描述

详细设计

流程图
在这里插入图片描述

golang实现

算法主体

func Run(opsList []*OpsTab, staffList []*StaffTab) {cid := strings.ToUpper(os.Getenv("CID"))fmt.Println(cid)if len(cid) == 0 {return}NewExcelListWithOpsAndStaff(opsList, staffList).Group(cid).Export(cid)
}type OpsTab struct {Id             uint64 `gorm:"column:id" json:"id"`OpsId          string `gorm:"column:ops_id" json:"ops_id"`OpsName        string `gorm:"column:ops_name" json:"ops_name"`Phone          string `gorm:"column:phone" json:"phone"`OpsStatus      int    `gorm:"column:ops_status" json:"ops_status"`StaffId        string `gorm:"column:staff_id" json:"staff_id"`
}type StaffTab struct {StaffId         string `gorm:"column:staff_id" json:"staff_id"`PassportId      string `gorm:"column:passport_id" json:"passport_id"`
}// 根据staff_id将Ops_tab和staff_tab合并成一个结构体
type ExcelResultItem struct {OpsName    stringOpsId      stringStaffId    stringPhone      stringPassportId stringOpsStatus  int
}type ExcelList []*ExcelResultItemfunc NewExcelListWithOpsAndStaff(opsList []*OpsTab, staffList []*StaffTab) *ExcelList {return (&ExcelList{}).toExcelResultItemList(opsList, staffList)
}func NewExcelList() *ExcelList {return &ExcelList{}
}func (e *ExcelList) Append(item *ExcelResultItem) {*e = append(*e, item)
}func (e *ExcelList) Size() int {return len(*e)
}func (e *ExcelList) toExcelResultItemList(opsList []*OpsTab, staffList []*StaffTab) *ExcelList {staffId2StaffMap := make(map[string]*StaffTab)for _, item := range staffList {staffId2StaffMap[item.StaffId] = item}for _, item := range opsList {passportId := ""if staff, ok := staffId2StaffMap[item.StaffId]; ok {passportId = staff.PassportId}*e = append(*e, &ExcelResultItem{OpsName:    item.OpsName,OpsId:      item.OpsId,StaffId:    item.StaffId,Phone:      item.Phone,PassportId: passportId,OpsStatus:  item.OpsStatus,})}return e
}func (e *ExcelList) Group(cid string) *GroupedExcelList {excelItemList := *euf := NewPathCompressionUnionFind(len(excelItemList))for i := range excelItemList {for j := i + 1; j < len(excelItemList); j++ {if handler.Check(cid, excelItemList[i], excelItemList[j]) {uf.Union(i, j)}}}ufId2ExcelListMap := make(map[int]*ExcelList)for id, item := range excelItemList {root := uf.Find(id)if uf.GetSize(root) < 2 {continue}if _, ok := ufId2ExcelListMap[root]; !ok {ufId2ExcelListMap[root] = NewExcelList()}ufId2ExcelListMap[root].Append(item)}res := NewGroupedExcelList()for _, list := range ufId2ExcelListMap {res.Append(list)}return res
}type GroupedExcelList []*ExcelListfunc NewGroupedExcelList() *GroupedExcelList {return &GroupedExcelList{}
}func (g *GroupedExcelList) Append(list *ExcelList) {*g = append(*g, list)
}

校验是否重复(策略模式)

检查是否重复策略模式UML
类似这个,实际简单一点

var handler = NewCheckWhetherSameStrategyHandler()type CheckWhetherSameStrategyHandler struct {region2StrategyMap map[string]CheckWhetherSameStrategy
}func NewCheckWhetherSameStrategyHandler() *CheckWhetherSameStrategyHandler {return &CheckWhetherSameStrategyHandler{region2StrategyMap: make(map[string]CheckWhetherSameStrategy),}
}func (c *CheckWhetherSameStrategyHandler) Register(cid string, strategy CheckWhetherSameStrategy) {c.region2StrategyMap[cid] = strategy
}func (c *CheckWhetherSameStrategyHandler) Check(cid string, ops1, ops2 *ExcelResultItem) bool {if _, ok := c.region2StrategyMap[cid]; !ok {panic(fmt.Sprintf("cid[%v] not exist", cid))}return c.region2StrategyMap[cid].Check(ops1, ops2)
}type CheckWhetherSameStrategy interface {Check(ops1, ops2 *ExcelResultItem) bool
}type CheckWhetherSameStrategyID struct{}func (c *CheckWhetherSameStrategyID) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyMY struct{}func (c *CheckWhetherSameStrategyMY) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyPH struct{}func (c *CheckWhetherSameStrategyPH) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategySG struct{}func (c *CheckWhetherSameStrategySG) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyTH struct{}func (c *CheckWhetherSameStrategyTH) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}type CheckWhetherSameStrategyTW struct{}func (c *CheckWhetherSameStrategyTW) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId
}type CheckWhetherSameStrategyVN struct{}func (c *CheckWhetherSameStrategyVN) Check(ops1, ops2 *ExcelResultItem) bool {return len(ops1.PassportId) != 0 && ops1.PassportId == ops2.PassportId || len(ops1.Phone) != 0 && ops1.Phone == ops2.Phone
}func init() {handler.Register("ID", &CheckWhetherSameStrategyID{})handler.Register("MY", &CheckWhetherSameStrategyMY{})handler.Register("PH", &CheckWhetherSameStrategyPH{})handler.Register("SG", &CheckWhetherSameStrategySG{})handler.Register("TH", &CheckWhetherSameStrategyTH{})handler.Register("TW", &CheckWhetherSameStrategyTW{})handler.Register("VN", &CheckWhetherSameStrategyVN{})
}

golang Excel导出操作

在这里插入图片描述

func (g *GroupedExcelList) Export(cid string) {//创建excel文件xlsx := excelize.NewFile()sheet := fmt.Sprintf("same_field_ops_%v_excel", cid)//创建新表单index := xlsx.NewSheet(sheet)//第一行  各个字段的名称row := 1setFieldValue2Excel(xlsx, sheet, row, FieldNameGroup, FieldNameGroup)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsName, FieldNameOpsName)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsId, FieldNameOpsId)setFieldValue2Excel(xlsx, sheet, row, FieldNamePhoneNumber, FieldNamePhoneNumber)setFieldValue2Excel(xlsx, sheet, row, FieldNamePassportId, FieldNamePassportId)setFieldValue2Excel(xlsx, sheet, row, FieldNameStatus, FieldNameStatus)row++for groupId, listPtr := range *g {//Excel 一组list := *listPtrstartRow := rowrow++for _, item := range list {//Excel 一行setFieldValue2Excel(xlsx, sheet, row, FieldNameGroup, fmt.Sprintf("%v", groupId))setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsName, item.OpsName)setFieldValue2Excel(xlsx, sheet, row, FieldNameOpsId, item.OpsId)setFieldValue2Excel(xlsx, sheet, row, FieldNamePhoneNumber, item.Phone)setFieldValue2Excel(xlsx, sheet, row, FieldNamePassportId, item.PassportId)setFieldValue2Excel(xlsx, sheet, row, FieldNameStatus, fmt.Sprintf("%v", item.OpsStatus))row++}//合并A列成一组xlsx.MergeCell(sheet, fmt.Sprintf("A%v", startRow), fmt.Sprintf("A%v", row - 1))}//设置默认打开的表单xlsx.SetActiveSheet(index)//保存文件到指定路径err := xlsx.SaveAs(fmt.Sprintf("./%v.xlsx", sheet))if err != nil {log.Fatal(err)}
}type FieldName = stringconst (FieldNameGroup       FieldName = "Group"FieldNameOpsName     FieldName = "Ops Name"FieldNameOpsId       FieldName = "Ops Id"FieldNamePhoneNumber FieldName = "Phone Number"FieldNamePassportId  FieldName = "Passport Id"FieldNameStatus      FieldName = "Status"
)
//如图,表格上角的ABCDEF
var posMap = map[FieldName]string{FieldNameGroup:       "A",FieldNameOpsName:     "B",FieldNameOpsId:       "C",FieldNamePhoneNumber: "D",FieldNamePassportId:  "E",FieldNameStatus:      "F",
}func setFieldValue2Excel(xlsx *excelize.File, sheet string, row int, key FieldName, val string) {if _, err := strconv.ParseInt(val, 10, 64); len(val) > 1 && err == nil {val = "'" + val}xlsx.SetCellValue(sheet, fmt.Sprintf("%v%v", posMap[key], row), val)
}

路径压缩并查集

type PathCompressionUnionFind struct {parents []intsize    []int
}func NewPathCompressionUnionFind(len int) *PathCompressionUnionFind {parents := make([]int, len)size := make([]int, len)for i := range parents {parents[i] = isize[i] = 1}return &PathCompressionUnionFind{parents: parents,size:    size,}
}func (t *PathCompressionUnionFind) Union(p, q int) {pRoot := t.Find(p)qRoot := t.Find(q)if pRoot == qRoot {return}t.parents[qRoot] = t.parents[pRoot]t.size[pRoot] += t.size[qRoot]
}func (t *PathCompressionUnionFind) Find(p int) int {for t.parents[p] != p {t.parents[p] = t.parents[t.parents[p]]p = t.parents[p]}return p
}func (t *PathCompressionUnionFind) GetSize(p int) int {if p < 0 || p >= len(t.parents) {panic("Union Find Array out of bounds")}return t.size[t.Find(p)]
}

复杂度

时间复杂度
O(N^2)

空间复杂度
O(N)

其他

从k8s pod上连接数据库并下载表数据

我们线上数据数据量约200万,从公司提供的平台查会被限制单词1000条数据,因此下载ops_tab和staff_tab的数据需要写个脚本在k8s上执行。

本地(MAC)
安装交叉编译环境

brew install FiloSottile/musl-cross/musl-cross

切换到main函数所在包,执行编译

CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS="-static" go build

压缩并拆分为多个文件方便上传

tar cjf - $your_name$ |split -b 5m - $your_name$.tar.bz2.

在k8s pod上
安装上传插件

apt install -y lrzsz

安装解压插件

apt install -y bzip2

上传文件

rz

给文件赋执行权限

chmod +x $your_name$

运行

./$your_name$
http://www.dtcms.com/wzjs/356477.html

相关文章:

  • 如何做求职招聘网站百度推广电话客服24小时
  • 网站设计公司兴田德润信任高nba球队排名
  • wordpress安装问题网站优化 推广
  • 免费网页游戏平台seo博客大全
  • ps插件国外网站山西网络营销外包
  • 百度云盘做网站空间百度文库首页
  • 网站建设属于什么类的采购湖南网站设计外包服务
  • 网站建设公司发展如何去除痘痘有效果
  • web网站建设调研报告关键词指数查询
  • 那里有专做粮食的网站网站关键词排名
  • 黄岛区城市建设局网站线上营销方式主要有哪些
  • 深圳医疗网站建设公司国际婚恋网站排名
  • 企业网站如何做微信营销站长之家最新网站
  • 怎样做集装箱网站网站运营专员
  • b2b网站框架北京网站推广公司
  • 站内优化怎么做手机百度正式版
  • 网购网站开发流程软文营销名词解释
  • 淘客客怎么做自己的网站手机怎么建网站
  • 网站网页翻页设计网站推广名词解释
  • 西安网站优化排名推广优化大师专业版
  • oblivion wordpressseo专业培训需要多久
  • 公众号里链接的网站怎么做的青海seo技术培训
  • 那个网站可以找人做设计师推广软文营销案例
  • 运城建设银行网站站长之家源码
  • 政务网站平台建设 招标微信推广平台哪里找
  • 长春市网站优化公司官网seo
  • 烟台市建委网站网络舆情优化公司
  • 建设网站的费用调研北京营销推广网站建设
  • 重庆网站推广 软件新网站怎么做推广
  • 手机网站模块培训心得体会总结简短