• 租房项目 启动前的处理


    项目启动

    拆分原则

    1、单一职责(一个服务只做一件事)

    2、服务粒度适中

    3、考虑团队结构

    4、以业务模型切入

    5、演进式拆分

    6、避免环形依赖和双向依赖

    如果还没有安装 beego 的话先安装 beego

    $ go get -u -v github.com/astaxie/beego
    $ go get -u -v github.com/beego/bee
    $ cd $GOPATH/src/github.com/beego/bee
    $ go build
    $ sudo mv bee /bin/
    

    服务发现的启动

    项目开始之前,我们先要启动我们单机版的 consul

    $ consul agent -dev
    

    数据库的准备

    在 mysql 中创建一个数据库:ihome

    $ mysql -uroot -p
    # 输入 root 密码
    
    # 创建1个数据库:ihome
    mysql>create database if not exists ihome default charset utf8 collate utf8_general_ci;
    

    Web 端

    可以先去 Github 中提前查看一下 Web 端的文件结构::https://github.com/lpg-it/ihome/tree/master/ihomeWeb

    创建命令

    $ cd $GOPATH/src
    $ micro new --type "web" ihome/ihomeWeb
    

    Web 服务的调整

    修改 main.go

    package main
    
    import (
            "github.com/julienschmidt/httprouter"
            "github.com/micro/go-log"
            "net/http"
    
            "github.com/micro/go-web"
    )
    
    func main() {
    	// create new web service
    	service := web.NewService(
    		web.Name("go.micro.web.ihomeWeb"),
    		web.Version("latest"),
    		web.Address(":8080"),
    	)
    
    	// initialise service
    	if err := service.Init(); err != nil {
    		log.Fatal(err)
    	}
    	
    	rou := httprouter.New()
    	rou.NotFound = http.FileServer(http.Dir("html"))
    
    	// register html handler
    	service.Handle("/", rou)
    	
    	// run service
    	if err := service.Run(); err != nil {
    		log.Fatal(err)
    	}
    }
    

    创建工具函数文件夹

    # 创建工具函数文件夹
    $ mkdir utils
    # 进入文件夹创建文件
    $ cd utils
    # 配置文件读取函数文件
    $ sudo vim config.go
    # 错误码文件
    $ sudo vim error.go
    # 字符串拼接文件
    $ sudo vim misc.go
    

    配置 文件读取文件 config.go

    package utils
    
    import (
    	"github.com/astaxie/beego"
    	//使用了beego框架的配置文件读取模块
    	"github.com/astaxie/beego/config"
    )
    
    var (
    	G_server_name  string //项目名称
    	G_server_addr  string //服务器ip地址
    	G_server_port  string //服务器端口
    	G_redis_addr   string //redis ip地址
    	G_redis_port   string //redis port端口
    	G_redis_dbnum  string //redis db 编号
    	G_mysql_addr   string //mysql ip 地址
    	G_mysql_port   string //mysql 端口
    	G_mysql_dbname string //mysql db name
    	G_fastdfs_port string //fastdfs 端口
    	G_fastdfs_addr string //fastdfs ip
    )
    
    func InitConfig() {
    	//从配置文件读取配置信息
    	//如果项目迁移需要进行修改
    	appconf, err := config.NewConfig("ini", "/home/lpgit/go/src/ihome/ihomeWeb/conf/app.conf")
    	if err != nil {
    		beego.Debug(err)
    		return
    	}
    	G_server_name = appconf.String("appname")
    	G_server_addr = appconf.String("httpaddr")
    	G_server_port = appconf.String("httpport")
    	G_redis_addr = appconf.String("redisaddr")
    	G_redis_port = appconf.String("redisport")
    	G_redis_dbnum = appconf.String("redisdbnum")
    	G_mysql_addr = appconf.String("mysqladdr")
    	G_mysql_port = appconf.String("mysqlport")
    	G_mysql_dbname = appconf.String("mysqldbname")
    	G_fastdfs_port = appconf.String("fastdfsport")
    	G_fastdfs_addr = appconf.String("fastdfsaddr")
    	return
    }
    
    func init() {
    	InitConfig()
    }
    

    错误码文件 error.go

    package utils
    
    const (
    	RECODE_OK         = "0"
    	RECODE_DBERR      = "4001"
    	RECODE_NODATA     = "4002"
    	RECODE_DATAEXIST  = "4003"
    	RECODE_DATAERR    = "4004"
    	RECODE_SESSIONERR = "4101"
    	RECODE_LOGINERR   = "4102"
    	RECODE_PARAMERR   = "4103"
    	RECODE_USERERR    = "4104"
    	RECODE_ROLEERR    = "4105"
    	RECODE_PWDERR     = "4106"
    	RECODE_SMSERR     = "4017"
    	RECODE_REQERR     = "4201"
    	RECODE_IPERR      = "4202"
    	RECODE_THIRDERR   = "4301"
    	RECODE_IOERR      = "4302"
    	RECODE_SERVERERR  = "4500"
    	RECODE_UNKNOWERR  = "4501"
    )
    
    var recodeText = map[string]string{
    	RECODE_OK:         "成功",
    	RECODE_DBERR:      "数据库查询错误",
    	RECODE_NODATA:     "无数据",
    	RECODE_DATAEXIST:  "数据已存在",
    	RECODE_DATAERR:    "数据错误",
    	RECODE_SESSIONERR: "用户未登录",
    	RECODE_LOGINERR:   "用户登录失败",
    	RECODE_PARAMERR:   "参数错误",
    	RECODE_USERERR:    "用户不存在或未激活",
    	RECODE_ROLEERR:    "用户身份错误",
    	RECODE_PWDERR:     "密码错误",
    	RECODE_REQERR:     "非法请求或请求次数受限",
    	RECODE_IPERR:      "IP受限",
    	RECODE_THIRDERR:   "第三方系统错误",
    	RECODE_IOERR:      "文件读写错误",
    	RECODE_SERVERERR:  "内部错误",
    	RECODE_UNKNOWERR:  "未知错误",
    	RECODE_SMSERR:     "短信失败",
    }
    
    func RecodeText(code string) string {
    	str, ok := recodeText[code]
    	if ok {
    		return str
    	}
    	return recodeText[RECODE_UNKNOWERR]
    }
    

    字符串拼接文件 misc.go

    package utils
    
    /* 将url加上 http://IP:PROT/  前缀 */
    //http:// + 127.0.0.1 + :+ 8080 + 请求
    
    func AddDomain2Url(url string) (domain_url string) {
    	domain_url = "http://" + G_fastdfs_addr + ":" + G_fastdfs_port + "/" + url
    
    	return domain_url
    }
    

    创建数据库文件

    没有下载 mysql 驱动的先下载 mysql

    $ go get -u -v github.com/go-sql-driver/mysql
    
    $ mkdir models
    # 创建数据库文件
    $ sudo vim models.go
    

    models.go 文件内容

    package models
    
    import (
    	"github.com/astaxie/beego"
    	// 使用了beego的orm模块
    	"github.com/astaxie/beego/orm"
    	// go语言的sql的驱动
    	_ "github.com/go-sql-driver/mysql"
    	// 已经创建好的工具包
    	"ihome/ihomeWeb/utils"
    	"time"
    )
    
    /* 用户 table_name = user */
    type User struct {
    	Id           int           `json:"user_id"`                       // 用户编号
    	Name         string        `orm:"size(32)"  json:"name"`          // 用户昵称
    	PasswordHash string        `orm:"size(128)" json:"password"`      // 用户密码加密的
    	Mobile       string        `orm:"size(11);unique"  json:"mobile"` // 手机号
    	RealName     string        `orm:"size(32)" json:"real_name"`      // 真实姓名  实名认证
    	IdCard       string        `orm:"size(20)" json:"id_card"`        // 身份证号  实名认证
    	AvatarUrl    string        `orm:"size(256)" json:"avatar_url"`    // 用户头像路径       通过 fastDFS 进行图片存储
    	Houses       []*House      `orm:"reverse(many)" json:"houses"`    // 用户发布的房屋信息  一个人多套房
    	Orders       []*OrderHouse `orm:"reverse(many)" json:"orders"`    // 用户下的订单       一个人多次订单
    }
    
    /* 房屋信息 table_name = house */
    type House struct {
    	Id            int           `json:"house_id"`                                          // 房屋编号
    	User          *User         `orm:"rel(fk)" json:"user_id"`                             // 房屋主人的用户编号  与用户进行关联
    	Area          *Area         `orm:"rel(fk)" json:"area_id"`                             // 归属地的区域编号   和地区表进行关联
    	Title         string        `orm:"size(64)" json:"title"`                              // 房屋标题
    	Price         int           `orm:"default(0)" json:"price"`                            // 单价,单位:分   每次的价格要乘以100
    	Address       string        `orm:"size(512)" orm:"default('')" json:"address"`         // 地址
    	RoomCount     int           `orm:"default(1)" json:"room_count"`                       // 房间数目
    	Acreage       int           `orm:"default(0)" json:"acreage"`                          // 房屋总面积
    	Unit          string        `orm:"size(32)" orm:"default('')" json:"unit"`             // 房屋单元,如 几室几厅
    	Capacity      int           `orm:"default(1)" json:"capacity"`                         // 房屋容纳的总人数
    	Beds          string        `orm:"size(64)" orm:"default('')" json:"beds"`             // 房屋床铺的配置
    	Deposit       int           `orm:"default(0)" json:"deposit"`                          // 押金
    	MinDays       int           `orm:"default(1)" json:"min_days"`                         // 最少入住的天数
    	MaxDays       int           `orm:"default(0)" json:"max_days"`                         // 最多入住的天数 0表示不限制
    	OrderCount    int           `orm:"default(0)" json:"order_count"`                      // 预定完成的该房屋的订单数
    	IndexImageUrl string        `orm:"size(256)" orm:"default('')" json:"index_image_url"` // 房屋主图片路径
    	Facilities    []*Facility   `orm:"reverse(many)" json:"facilities"`                    // 房屋设施   与设施表进行关联
    	Images        []*HouseImage `orm:"reverse(many)" json:"img_urls"`                      // 房屋的图片   除主要图片之外的其他图片地址
    	Orders        []*OrderHouse `orm:"reverse(many)" json:"orders"`                        // 房屋的订单    与房屋表进行管理
    	Ctime         time.Time     `orm:"auto_now_add;type(datetime)" json:"ctime"`
    }
    
    // 首页最高展示的房屋数量
    var HomePageMaxHouses int = 5
    
    // 房屋列表页面每页显示条目数
    var HouseListPageCapacity int = 2
    
    // 处理房子信息
    func (this *House) ToHouseInfo() interface{} {
    	houseInfo := map[string]interface{}{
    		"house_id":    this.Id,
    		"title":       this.Title,
    		"price":       this.Price,
    		"area_name":   this.Area.Name,
    		"img_url":     utils.AddDomain2Url(this.IndexImageUrl),
    		"room_count":  this.RoomCount,
    		"order_count": this.OrderCount,
    		"address":     this.Address,
    		"user_avatar": utils.AddDomain2Url(this.User.AvatarUrl),
    		"ctime":       this.Ctime.Format("2006-01-02 15:04:05"),
    	}
    
    	return houseInfo
    }
    
    // 处理 1 个房子的全部信息
    func (this *House) ToOneHouseDesc() interface{} {
    	houseDesc := map[string]interface{}{
    		"hid":         this.Id,
    		"user_id":     this.User.Id,
    		"user_name":   this.User.Name,
    		"user_avatar": utils.AddDomain2Url(this.User.AvatarUrl),
    		"title":       this.Title,
    		"price":       this.Price,
    		"address":     this.Address,
    		"room_count":  this.RoomCount,
    		"acreage":     this.Acreage,
    		"unit":        this.Unit,
    		"capacity":    this.Capacity,
    		"beds":        this.Beds,
    		"deposit":     this.Deposit,
    		"min_days":    this.MinDays,
    		"max_days":    this.MaxDays,
    	}
    
    	//房屋图片
    	imgUrls := []string{}
    	for _, imgUrl := range this.Images {
    		imgUrls = append(imgUrls, utils.AddDomain2Url(imgUrl.Url))
    	}
    	houseDesc["img_urls"] = imgUrls
    
    	//房屋设施
    	facilities := []int{}
    	for _, facility := range this.Facilities {
    		facilities = append(facilities, facility.Id)
    	}
    	houseDesc["facilities"] = facilities
    
    	//评论信息
    
    	comments := []interface{}{}
    	orders := []OrderHouse{}
    	o := orm.NewOrm()
    	orderNum, err := o.QueryTable("order_house").Filter("house__id", this.Id).Filter("status", OrderStatusComplete).OrderBy("-ctime").Limit(10).All(&orders)
    	if err != nil {
    		beego.Error("select orders comments error, err =", err, "house id = ", this.Id)
    	}
    	for i := 0; i < int(orderNum); i++ {
    		o.LoadRelated(&orders[i], "User")
    		var username string
    		if orders[i].User.Name == "" {
    			username = "匿名用户"
    		} else {
    			username = orders[i].User.Name
    		}
    
    		comment := map[string]string{
    			"comment":   orders[i].Comment,
    			"user_name": username,
    			"ctime":     orders[i].Ctime.Format("2006-01-02 15:04:05"),
    		}
    		comments = append(comments, comment)
    	}
    	houseDesc["comments"] = comments
    
    	return houseDesc
    }
    
    /* 区域信息 table_name = area */ //区域信息是需要我们手动添加到数据库中的
    type Area struct {
    	Id     int      `json:"aid"`                        // 区域编号     1    2
    	Name   string   `orm:"size(32)" json:"aname"`       // 区域名字     昌平 海淀
    	Houses []*House `orm:"reverse(many)" json:"houses"` // 区域所有的房屋   与房屋表进行关联
    }
    
    /* 设施信息 table_name = "facility"*/ // 设施信息 需要我们提前手动添加的
    type Facility struct {
    	Id     int      `json:"fid"`     // 设施编号
    	Name   string   `orm:"size(32)"` // 设施名字
    	Houses []*House `orm:"rel(m2m)"` // 都有哪些房屋有此设施  与房屋表进行关联的
    }
    
    /* 房屋图片 table_name = "house_image"*/
    type HouseImage struct {
    	Id    int    `json:"house_image_id"`         // 图片 id
    	Url   string `orm:"size(256)" json:"url"`    // 图片 url     存放我们房屋的图片
    	House *House `orm:"rel(fk)" json:"house_id"` // 图片所属房屋编号
    }
    
    const (
    	OrderStatusWaitAccept  = "WAIT_ACCEPT"  //待接单
    	OrderStatusWaitPayment = "WAIT_PAYMENT" //待支付
    	OrderStatusPaid        = "PAID"         //已支付
    	OrderStatusWaitComment = "WAIT_COMMENT" //待评价
    	OrderStatusComplete    = "COMPLETE"     //已完成
    	OrderStatusCanceled    = "CONCELED"     //已取消
    	OrderStatusRejected    = "REJECTED"     //已拒单
    )
    
    /* 订单 table_name = order */
    type OrderHouse struct {
    	Id         int       `json:"order_id"`               //订单编号
    	User       *User     `orm:"rel(fk)" json:"user_id"`  //下单的用户编号   //与用户表进行关联
    	House      *House    `orm:"rel(fk)" json:"house_id"` //预定的房间编号   //与房屋信息进行关联
    	BeginDate  time.Time `orm:"type(datetime)"`          //预定的起始时间
    	EndDate    time.Time `orm:"type(datetime)"`          //预定的结束时间
    	Days       int       //预定总天数
    	HousePrice int       //房屋的单价
    	Amount     int       //订单总金额
    	Status     string    `orm:"default(WAIT_ACCEPT)"`                 //订单状态
    	Comment    string    `orm:"size(512)"`                            //订单评论
    	Ctime      time.Time `orm:"auto_now;type(datetime)" json:"ctime"` //每次更新此表,都会更新这个字段
    	Credit     bool      //表示个人征信情况 true表示良好
    }
    
    // 处理订单信息
    func (this *OrderHouse) ToOrderInfo() interface{} {
    	orderInfo := map[string]interface{}{
    		"order_id":   this.Id,
    		"title":      this.House.Title,
    		"img_url":    utils.AddDomain2Url(this.House.IndexImageUrl),
    		"start_date": this.BeginDate.Format("2006-01-02 15:04:05"),
    		"end_date":   this.EndDate.Format("2006-01-02 15:04:05"),
    		"ctime":      this.Ctime.Format("2006-01-02 15:04:05"),
    		"days":       this.Days,
    		"amount":     this.Amount,
    		"status":     this.Status,
    		"comment":    this.Comment,
    		"credit":     this.Credit,
    	}
    
    	return orderInfo
    }
    
    // 数据库的初始化
    func init() {
    	//调用什么驱动
    	orm.RegisterDriver("mysql", orm.DRMySQL)
    
    	// set default database
    	// 连接数据   ( 默认参数 ,mysql数据库 ,"数据库的用户名 :数据库密码@tcp("+数据库地址+":"+数据库端口+")/库名?格式",默认参数)
    	orm.RegisterDataBase("default", "mysql", "root:lpg123456@tcp("+utils.G_mysql_addr+":"+utils.G_mysql_port+")/ihome?charset=utf8", 30)
    
    	// 注册 model 建表
    	orm.RegisterModel(new(User), new(House), new(Area), new(Facility), new(HouseImage), new(OrderHouse))
    
    	// create table
    	//第一个是别名
    	// 第二个是是否强制替换模块   如果表变更就将false 换成true 之后再换回来表就便更好来了
    	//第三个参数是如果没有则同步或创建
    	orm.RunSyncdb("default", false, true)
    }
    

    运行服务并且创建表单

    # 创建 conf 文件夹用来存放配置文件
    $ mkdir conf
    # 创建data.sql文件
    $ sudo vim data.sql
    

    datat.sql 文件内容

    INSERT INTO `area`(`name`) VALUES ('东城区'),('西城区'),('朝阳区'),('海淀区'),('昌平区'),('丰台区'),('房山区'),('通州区'),('顺义区'),('大兴区'),('怀柔区'),('平谷区'),('密云区'),('延庆区'),('石景山区');
    INSERT INTO `facility`(`name`) VALUES('无线网络'),('热水淋浴'),('空调'),('暖气'),('允许吸烟'),('饮水设备'),('牙具'),('香皂'),('拖鞋'),('手纸'),('毛巾'),('沐浴露、洗发露'),('冰箱'),('洗衣机'),('电梯'),('允许做饭'),('允许带宠物'),('允许聚会'),('门禁系统'),('停车位'),('有线网络'),('电视'),('浴缸'),('吃鸡'),('打台球');
    

    修改 main.go 内容

    import (
    	_ "ihome/ihomeWeb/models"
    )
    

    登录 mysql 进行数据导入

    # 登录mysql
    $ mysql -uroot -p
    # 输入root密码
    Mysql> use ihome;
    # 数据的导入
    mysql> source ./conf/data.sql;
    # 数据检查
    mysql> select * from area;
    mysql> select * from facility;
    

    image.png

    创建 app.conf文件

    # 应用名称
    appname = ihome
    # 地址
    httpaddr = 127.0.0.1
    # 端口
    httpport = 8080
    # 数据库地址
    mysqladdr = 127.0.0.1
    # 数据库端口
    mysqlport = 3306
    

    导入前端页面

    html 文件下载地址:https://cloud.189.cn/t/IzYbIbQVbEJn (访问码: 2owm)

    运行

    go run main.go
    

    打开浏览器,输入:127.0.0.1:8080,就可以看到效果啦。

    接下来, 我就带领大家一步一步完成每个服务。

    李培冠博客

    欢迎访问我的个人网站:

    李培冠博客:lpgit.com

  • 相关阅读:
    [MAC]如何抹掉 Mac 磁盘
    [MAC]出售、赠送或折抵 Mac 前该怎么做
    转载 软件项目计划如何编写举例
    GIT
    AWR实战分析之----direct path read temp
    ASM 磁盘组的的scrip
    巨杉db
    High waits on control file sequential read
    如何减小SQL 的物理读,。
    block size大小
  • 原文地址:https://www.cnblogs.com/lpgit/p/13556548.html
Copyright © 2020-2023  润新知