前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >石桥码农:如何在本地基于 nideshop 架设一个微信小程序商城?

石桥码农:如何在本地基于 nideshop 架设一个微信小程序商城?

作者头像
LIYI
发布2020-02-13 11:52:26
2.2K0
发布2020-02-13 11:52:26
举报
文章被收录于专栏:艺述论专栏艺述论专栏
代码语言:javascript
复制
目录

一、首先架构服务器端
二、创建数据库
三、尝试运行后端代码
四、配置数据库连接,与初始化数据
五、小程序这一端,下载、导入、运行
六、问题

架设完成后,产品相貌大概长这个样子:

是仿网易严选的小程序,产品设计还是ok的。

本文主要基于 nideshop 和 moshopserver 构建,在本地构建,mysql可以用本地的,也可以用云上的。这个项目的意义,主要在于自己学习和研究小程序商城项目的开发。

这是两个开源项目,服务端基于 golang 开发,读者也可以基于它们二次开发。下面是架设过程中可能遇到的一些坑。

一、首先架构服务器端

首先进行服务器端源码的下载、安装依赖,还有使用 go modules

下载源码:

代码语言:javascript
复制
git clone https://github.com/harlanc/moshopserver --depth=1

批量安装依赖:

代码语言:javascript
复制
go get -d ./...

不好,出现一个错误:

代码语言:javascript
复制
go: cannot find main module, but found .git/config in /work/2020/小程序/moshopserver

貌似是go语言的module有问题,先看看go modules怎么回事。

创建本地的 go modules

go modules 是 golang 1.11 新加的特性。官方定义为:

模块是相关Go包的集合。modules是源代码交换和版本控制的单元。go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。

golang 提供了 go mod 命令来管理包,有init指令可以初始化本地module:

代码语言:javascript
复制
init	initialize new module in current directory(在当前目录初始化mod)

现在,初始化之:

代码语言:javascript
复制
go mod init moshopserver

再执行 go get -d ./...

没有问题了。

看一下 go.mod文件,使用指令cat go.mod,返回:

代码语言:javascript
复制
// 石桥码农
module moshopserver

go 1.13

require (
	github.com/astaxie/beego v1.12.1
	github.com/bradfitz/slice v0.0.0-20180809154707-2b758aa73013
	github.com/dgrijalva/jwt-go v3.2.0+incompatible
	github.com/go-sql-driver/mysql v1.4.1
	github.com/harlanc/moshopserver v0.0.0-20190822051454-a778a28f1d37
	github.com/objcoding/wxpay v1.0.6
	github.com/satori/go.uuid v1.2.0
	github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
	go4.org v0.0.0-20200104003542-c7e774b10ea0 // indirect
	google.golang.org/appengine v1.6.5 // indirect
)

go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。

go modules 解决什么问题?

在 Go Module 之前,如果你执行 go get github.com/xxx/xx,代码将会被 clone 到 $GOPATH/src/github.com/xxx/xx 目录下。

这不是一个完美的方案,因为 go get 仅仅只能从 master 分支下载和更新最新的代码。当初期写代码时,从 master 下载代码没什么问题。但几个月后,有些依赖可能已经升级了,master 分支的最新代码可能已经不再兼容你的项目,这时代运行可能就要出bug了

如何实现依赖版本化管理一直是golang的最大痛点之一。

go modules 做到了这两件事。

  • 为整个项目中的每个依赖,指定一个兼容版本。
  • 还支持针对同一个依赖,引用不同的主版本,以应对出现同一个项目中依赖同一个包的不同主版本

后端代码下载了,依赖安装了,下载开始设置数据库

二、创建数据库

可以使用本地mysql,不影响测试

也可以使用云数据库,随时随地开发,不依赖于本地电脑。以腾讯云为例,登陆云操作后台,登陆某云数据库服务器:

登陆后,在“新建”菜单下,可以选择新建库,创建脚本是这样的:

代码语言:javascript
复制
CREATE SCHEMA `nideshop` DEFAULT CHARACTER SET utf8mb4 ;

不通过SQL语句,通过菜单面板,手动创建也可以。

mb4 什么意思?

创建数据库时指定的 utf8mb4编码,其中mb4是什么意思呢?

utf8mb4 是目前最大的一个字符编码,支持任意文字。

低版本的MySQL支持的utf8编码,最大字符长度为 3 字节,如果遇到 4 字节的字符就会出现错误了。

三个字节的 UTF-8 最大能编码的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面,即BMP。也就是说,任何不在基本多文平面的 Unicode字符,都无法使用MySQL原有的旧的 utf8 字符集存储。

utf8mb4是在5.5版本之后加入的,或许mb就是max bytes的意思,而目前的utf8其实是utf8mb3。现在支持4个字节的字符了,是 utf8mb4。

这些不在 BMP 中的字符包括哪些呢?最常见的就是Emoji 表情,和一些不常用的汉字,以及任何新增的 Unicode 字符。

数据库排序,关于utf8mb4_general_ci

新建mysql库或者表的时候还有一个排序规则:utf8mb4_general_ci

utf8_unicode_ci比较准确,utf8_general_ci速度比较快。

通常情况下 utf8_general_ci的准确性就够我们用的了,如果是utf8mb4那么对应的就是 utf8mb4_general_ci。

三、尝试运行后端代码

运行:

代码语言:javascript
复制
go run main.go

首先遇到的第一个问题,可能就是网速。

go get 国内下载太慢怎么破?

在下载这个依赖时可能超时,失败:

代码语言:javascript
复制
downloading golang.org/x/text v0.3.2

因网络安装出现问题,一个解决方法是:

代码语言:javascript
复制
1)安装gopm
go get -u github.com/gpmgo/gopm
2) 用 gopm get 代替 go get

不采用-g参数,会把依赖包下载.vendor目录下面;采用-g 参数,可以把依赖包下载到GOPATH目录中

例如

代码语言:javascript
复制
gopm get -g golang.org/x/net

另一个方法是:

复用IP查找工具,地址是:

代码语言:javascript
复制
https://github.com.ipaddress.com

来获取IP地址设置hosts,然后改写hosts文件:

代码语言:javascript
复制
vim /etc/hosts
140.82.114.4 github.com
199.232.5.194 github.global.ssl.fastly.net

即使使用了go modules,但也可能会遇到代码兼容性的问题。

一个关于uuid的代码兼容性问题

执行go run时出现了一个错误:

代码语言:javascript
复制
$GOPATH/pkg/mod/github.com/harlanc/moshopserver@v0.0.0-20190822051454-a778a28f1d37/utils/utils.go:35:12: assignment mismatch: 2 variables but uuid.NewV4 returns 1 values

奇怪,这个目录竟然不在当前的项目目录下,但现在先不必管它,先处理错误。

大意是说,函数返回了一个值,但期望的赋值却是两个,个数不匹配啊。

进去文件,然后将其修改:

代码语言:javascript
复制
// 石桥码农
func GetUUID() string {
	uuid := uuid.NewV4()
	return uuid.String()
	// 以下是旧代码,注掉
	// uuid, err := uuid.NewV4()
	// if err != nil {
	// 	return ""
	// } else {
	// 	return uuid.String()
	// }
}

这样问题就得以解决了

四、配置数据库连接,与初始化数据

创建了数据库,但是还没有表,表里还没有数据。好在源码里提供了sql文件,可以直接复用的。

使用MySQLWorkbench连接云数据库,将源码目录下的nideshop.sql内容,在query窗口中执行。这个过程有点慢,但只要网络可以,没啥问题。

然后就是修改数据库连接字符串,在moshopserver/models/db.go文件中,修改为自己的实现的mysql连接字符串。

改完再运行,又出现了一个错误。

关于ip地址的错误
代码语言:javascript
复制
ListenAndServe:  listen tcp 192.168.0.104:8080: bind: can't assign requested address

这个错误大概是讲,这个104的ip不能使用,作者的ip不是104啊,那这个地址可能是写死了。

找到moshopserver/.vendor/src/moshopserver/main.go文件,修改里面的ip地址,改成本地地址就好了:

代码语言:javascript
复制
beego.BConfig.Listen.HTTPAddr = "127.0.0.1"
// beego.BConfig.Listen.HTTPAddr = "192.168.0.104"

再次运行,看到这个界面

说明后台服务启动成功了。

到这里,说明后端代码没啥问题了。但是在小程序端

五、小程序这一端,下载、导入、运行

下载源码:

代码语言:javascript
复制
git clone https://github.com/tumobi/nideshop-mini-program.git --depth=1

修改配置,在config/api.js中,修改ApiRootUrl地址:

代码语言:javascript
复制
const ApiRootUrl = 'http://127.0.0.1:8080/api/';

这是我们后端刚才启用的服务地址。

然后打开微信开发者工具,直接导入本地项目,就可以运行了。

但是从调试器中查看,有网络错误,接口访问是红色的,有的返回“need relogin”,这说明后台服务有问题。

关于 db default alias 的错误

查看后台终端日志,有这样的提示:

代码语言:javascript
复制
must have one register DataBase alias named `default`

这貌似是数据库连接问题。每个beego都需要一个default db,貌似没有成功配置。

哎呦,不对,我们创建了数据库,导入了数据,但是还没有在哪里设置mysql连接字符串,这肯定不对啊。钥匙没有,程序怎么连接。

找到这个文件

代码语言:javascript
复制
$GOPATH/pkg/mod/github.com/harlanc/moshopserver@v0.0.0-20190822051454-a778a28f1d37/models/db.go

修改关于init方法中的db连接字符串。这是$GOPATH目录下的文件,而修改项目中的db文件,不好使。

同理,还需要修改这个文件

代码语言:javascript
复制
moshopserver/conf/weixin.conf

那么问题来了,为什么要到GOPATH中修改mod中的文件?

关于$GOPATH中的go pkg mod是怎么回事?

启用go modules后,我们可以在GOPATH之外创建新的项目。

go mod download可以下载所需要的依赖,但是依赖并不是下载到$GOPATH中,而是下载到$GOPATH/pkg/mod中,这是多个项目可以共享缓存的module。

问题在这里,源码被默认共享了,放在了$GOPATH下面。这不是我们想要的。我们想要的是,一个工作区的源码目录,包括了项目源码及所有依赖库的源码,以后什么运行,项目都不会出bug。

或许vender指令,可以解决我们的问题。

go mod vendor 会复制modules下载到vendor中, 貌似只会下载你代码中引用的库,而不是go.mod中定义全部的module。

执行这条指令

代码语言:javascript
复制
go mod vendor

之后,在项目目录下就会生成一个vendor目录:

有个问题,go 语言依赖包的查找顺序是怎样的?

Go 1.11版本支持临时环境变量GO111MODULE,通过该环境变量来控制依赖包的管理方式。当GO111MODULE的值为on时,那么就会使用modules功能,这种模式下,$GOPATH不再作为build时导入的角色,依赖包会存放在$GOPATH/pkg/mod目录下。

开启指令:

代码语言:javascript
复制
export GO111MODULE=on

当GO111MODULE=off时,如果一个包在vendor和$GOPATH下都存在,那么使用顺序为:

  • 使用vendor目录下面的包
  • 搜索$GOPATH/src下面的包
  • 搜索$GOROOT/src下面的包

go.mod有一个功能,充许在go.mod中替换依赖包:

代码语言:javascript
复制
replace (
	golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
	golang.org/x/net v0.0.0-20180821023952-922f4815f713 => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d
	golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
)

这个或许可能有用。

搞定所有,现在终于可以运行了了

能取到昵称头像,说明微信配置已经成功了

问题

如果想在服务器上自己架设这个小程序商城,应该怎么做?

能在本地运行,就能在服务器上运行。需要下面三大步:

  • 购买云服务器,将服务器端的源码编译并发布到服务器上,使用 pm2 恒启动
  • 购买一个域名,还有ssl证书,修改后端、小程序前端的地址为自己的地址
  • 注册小程序帐号,将小程序前端代码发布并提交审核

但是,如果想在业务中实际使用它,有两个问题:

  • 这套源码中的微信支付依赖于企业资质,必须开通了微信支付的企业小程序帐号才能使用。
  • 还没有一个操作的后台,这个moshopserver只是一个golang实现的nideshop后台api

这套代码的意义,在于学习,方便不太熟悉小程序商城产品的开发者从代码层次研究它,甚至改造它。

参考链接

略,平台都不喜欢链接

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、首先架构服务器端
    • 创建本地的 go modules
      • go modules 解决什么问题?
      • 二、创建数据库
        • mb4 什么意思?
          • 数据库排序,关于utf8mb4_general_ci
          • 三、尝试运行后端代码
            • go get 国内下载太慢怎么破?
              • 一个关于uuid的代码兼容性问题
              • 四、配置数据库连接,与初始化数据
                • 关于ip地址的错误
                • 五、小程序这一端,下载、导入、运行
                  • 关于 db default alias 的错误
                    • 关于$GOPATH中的go pkg mod是怎么回事?
                    • 问题
                    相关产品与服务
                    云开发 CloudBase
                    云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档