专栏首页艺述思维石桥码农:如何在本地基于 nideshop 架设一个微信小程序商城?

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

目录

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

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

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

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

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

一、首先架构服务器端

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

下载源码:

git clone https://github.com/harlanc/moshopserver --depth=1

批量安装依赖:

go get -d ./...

不好,出现一个错误:

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:

init	initialize new module in current directory(在当前目录初始化mod)

现在,初始化之:

go mod init moshopserver

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

没有问题了。

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

// 石桥码农
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,不影响测试

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

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

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。

三、尝试运行后端代码

运行:

go run main.go

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

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

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

downloading golang.org/x/text v0.3.2

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

1)安装gopm
go get -u github.com/gpmgo/gopm
2) 用 gopm get 代替 go get

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

例如

gopm get -g golang.org/x/net

另一个方法是:

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

https://github.com.ipaddress.com

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

vim /etc/hosts
140.82.114.4 github.com
199.232.5.194 github.global.ssl.fastly.net

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

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

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

$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

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

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

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

// 石桥码农
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地址的错误

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地址,改成本地地址就好了:

beego.BConfig.Listen.HTTPAddr = "127.0.0.1"
// beego.BConfig.Listen.HTTPAddr = "192.168.0.104"

再次运行,看到这个界面

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

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

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

下载源码:

git clone https://github.com/tumobi/nideshop-mini-program.git --depth=1

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

const ApiRootUrl = 'http://127.0.0.1:8080/api/';

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

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

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

关于 db default alias 的错误

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

must have one register DataBase alias named `default`

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

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

找到这个文件

$GOPATH/pkg/mod/github.com/harlanc/moshopserver@v0.0.0-20190822051454-a778a28f1d37/models/db.go

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

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

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。

执行这条指令

go mod vendor

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

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

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

开启指令:

export GO111MODULE=on

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

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

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

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

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

参考链接

略,平台都不喜欢链接

本文分享自微信公众号 - 艺述思维(yishulun2005),作者:石桥码农

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • go modules:使用 mod 管理项目依赖包,通过vendor实现一键分发编译包

    在go语言1.11版本之前,没有modules机制,所有软件包都在安装在$GOPATH/src目录下。不同项目如果引用了同一个软件包的不同版本,就会造成编译麻烦...

    李艺
  • 前端:浏览器、GPU 工作原理简要及动画编程启示

    “ 最近作者在 VIPKID 企业内部做了一次关于‘动画增强技术方案’的分享,在原分享的基础之上,加入了对浏览器工作原理的考察,并补充动画编码启示若干,烩成此篇...

    李艺
  • 2.2 progress简介:如何实现一个环形进度条?

    在前端网络操作是异步的,一般都需要一个进度条。在很多应用中,我们经常可以看到环形进度条,但是小程序原生的 progress 组件,是一个从左到右的方形进度条,那...

    李艺
  • Go Module详细使用教程,包管理不在难

    go modules是 golang 1.11引入的新特性。模块是相关Go包的集合。modules是源代码交换和版本控制的单元。go命令直接支持使用module...

    咻咻ing
  • Go——依赖管理

    在Go1.5 release的版本的发布vendor目录被添加到除了GOPATH和GOROOT之外的依赖目录查找的解决方法。 查找依赖包路径的解决 当前包下...

    羊羽shine
  • Go Modules 的智障版本选择

    之前 go mod 用的比较少,而且一直听社区有各种抱怨,所以也兴趣寥寥。新公司的项目直接使用了 go mod,本来觉得无非是个简单的工具,不需要学习,结果在一...

    梦醒人间
  • go module

    go 1.5 引进了vendor管理工程依赖包,但是vendor的存放路径是在GOPATH底下,另外每个依赖还可以有自己的vendor,通常会弄得很乱,尽管de...

    用户2937493
  • go mod使用

    最近由于换工作,开始交接工作。整理以前的工作内容,由于组内就我一个在做go和大数据。 所以开发没有规划,当时是怎么快怎么来。go也是使用最传统的go path的...

    若与
  • 用go-module作为包管理器搭建go的web服务器

    本篇博客主要介绍了如何从零开始,使用Go Module作为依赖管理,基于Gin来一步一步搭建Go的Web服务器。并使用Endless来使服务器平滑重启,使用Sw...

    SH的全栈笔记
  • 使用 Go Modules 管理依赖

    Go Modules 是 Go 语言的一种依赖管理方式,该 feature 是在 Go 1.11 版本中出现的,由于最近在做的项目中,团队都开始使用 go m...

    田飞雨

扫码关注云+社区

领取腾讯云代金券