李哲 4 жил өмнө
commit
7a1f04ea9b

+ 4 - 0
README.md

@@ -0,0 +1,4 @@
+剑鱼会员积分服务
+说明
+(积分帐套维护) 积分支持有效期(支持每积分获取,单独设定到期时间),积分到期自动清除。
+ 积分常规操作:获取、消费、到期清除、撤单返还等。

+ 5 - 0
go.mod

@@ -0,0 +1,5 @@
+module points_service
+
+go 1.13
+
+require google.golang.org/grpc v1.26.0

+ 47 - 0
go.sum

@@ -0,0 +1,47 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 10 - 0
rpc/etc/integral.yaml

@@ -0,0 +1,10 @@
+Name: integral.rpc
+ListenOn: 127.0.0.1:8080
+Etcd:
+  Hosts:
+  - 127.0.0.1:2379
+  Key: integral.rpc
+DataSource: admin:123456@tcp(192.168.3.14:3306)/jyintegral
+Table: i_balance
+Cache:
+  - Host: localhost:6379

+ 34 - 0
rpc/integral.go

@@ -0,0 +1,34 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+
+	"points_service/rpc/integral"
+	"points_service/rpc/internal/config"
+	"points_service/rpc/internal/server"
+	"points_service/rpc/internal/svc"
+
+	"github.com/tal-tech/go-zero/core/conf"
+	"github.com/tal-tech/go-zero/zrpc"
+	"google.golang.org/grpc"
+)
+
+var configFile = flag.String("f", "etc/integral.yaml", "the config file")
+
+func main() {
+	flag.Parse()
+
+	var c config.Config
+	conf.MustLoad(*configFile, &c)
+	ctx := svc.NewServiceContext(c)
+	srv := server.NewIntegralServer(ctx)
+
+	s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
+		integral.RegisterIntegralServer(grpcServer, srv)
+	})
+	defer s.Stop()
+
+	fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
+	s.Start()
+}

+ 27 - 0
rpc/integral.proto

@@ -0,0 +1,27 @@
+syntax = "proto3";
+
+package integral;
+
+message addReq {
+  string userId = 1;
+  int64 countPoints = 2;
+}
+
+message addResp {
+  bool status = 1;
+}
+
+message checkReq {
+  string userId = 1;
+}
+
+message checkResp {
+  int64 countPoints = 1;
+}
+
+service Integral {
+  rpc add(addReq) returns(addResp);
+  rpc update(addReq) returns(addResp);
+  rpc select(checkReq) returns(checkResp);
+}
+

+ 515 - 0
rpc/integral/integral.pb.go

@@ -0,0 +1,515 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.25.0
+// 	protoc        v3.15.3
+// source: integral.proto
+
+package integral
+
+import (
+	context "context"
+	proto "github.com/golang/protobuf/proto"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// This is a compile-time assertion that a sufficiently up-to-date version
+// of the legacy proto package is being used.
+const _ = proto.ProtoPackageIsVersion4
+
+type AddReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UserId      string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"`
+	CountPoints int64  `protobuf:"varint,2,opt,name=countPoints,proto3" json:"countPoints,omitempty"`
+}
+
+func (x *AddReq) Reset() {
+	*x = AddReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_integral_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AddReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AddReq) ProtoMessage() {}
+
+func (x *AddReq) ProtoReflect() protoreflect.Message {
+	mi := &file_integral_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AddReq.ProtoReflect.Descriptor instead.
+func (*AddReq) Descriptor() ([]byte, []int) {
+	return file_integral_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AddReq) GetUserId() string {
+	if x != nil {
+		return x.UserId
+	}
+	return ""
+}
+
+func (x *AddReq) GetCountPoints() int64 {
+	if x != nil {
+		return x.CountPoints
+	}
+	return 0
+}
+
+type AddResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Status bool `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
+}
+
+func (x *AddResp) Reset() {
+	*x = AddResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_integral_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AddResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AddResp) ProtoMessage() {}
+
+func (x *AddResp) ProtoReflect() protoreflect.Message {
+	mi := &file_integral_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AddResp.ProtoReflect.Descriptor instead.
+func (*AddResp) Descriptor() ([]byte, []int) {
+	return file_integral_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *AddResp) GetStatus() bool {
+	if x != nil {
+		return x.Status
+	}
+	return false
+}
+
+type CheckReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"`
+}
+
+func (x *CheckReq) Reset() {
+	*x = CheckReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_integral_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CheckReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CheckReq) ProtoMessage() {}
+
+func (x *CheckReq) ProtoReflect() protoreflect.Message {
+	mi := &file_integral_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CheckReq.ProtoReflect.Descriptor instead.
+func (*CheckReq) Descriptor() ([]byte, []int) {
+	return file_integral_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CheckReq) GetUserId() string {
+	if x != nil {
+		return x.UserId
+	}
+	return ""
+}
+
+type CheckResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	CountPoints int64 `protobuf:"varint,1,opt,name=countPoints,proto3" json:"countPoints,omitempty"`
+}
+
+func (x *CheckResp) Reset() {
+	*x = CheckResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_integral_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CheckResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CheckResp) ProtoMessage() {}
+
+func (x *CheckResp) ProtoReflect() protoreflect.Message {
+	mi := &file_integral_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CheckResp.ProtoReflect.Descriptor instead.
+func (*CheckResp) Descriptor() ([]byte, []int) {
+	return file_integral_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CheckResp) GetCountPoints() int64 {
+	if x != nil {
+		return x.CountPoints
+	}
+	return 0
+}
+
+var File_integral_proto protoreflect.FileDescriptor
+
+var file_integral_proto_rawDesc = []byte{
+	0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x22, 0x42, 0x0a, 0x06, 0x61, 0x64,
+	0x64, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x21,
+	0x0a, 0x07, 0x61, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x22, 0x22, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a,
+	0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75,
+	0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x2d, 0x0a, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65,
+	0x73, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74,
+	0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x6f,
+	0x69, 0x6e, 0x74, 0x73, 0x32, 0x98, 0x01, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61,
+	0x6c, 0x12, 0x2a, 0x0a, 0x03, 0x61, 0x64, 0x64, 0x12, 0x10, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67,
+	0x72, 0x61, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x69, 0x6e, 0x74,
+	0x65, 0x67, 0x72, 0x61, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d, 0x0a,
+	0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72,
+	0x61, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x69, 0x6e, 0x74, 0x65,
+	0x67, 0x72, 0x61, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x12, 0x31, 0x0a, 0x06,
+	0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x12, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61,
+	0x6c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x69, 0x6e, 0x74,
+	0x65, 0x67, 0x72, 0x61, 0x6c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_integral_proto_rawDescOnce sync.Once
+	file_integral_proto_rawDescData = file_integral_proto_rawDesc
+)
+
+func file_integral_proto_rawDescGZIP() []byte {
+	file_integral_proto_rawDescOnce.Do(func() {
+		file_integral_proto_rawDescData = protoimpl.X.CompressGZIP(file_integral_proto_rawDescData)
+	})
+	return file_integral_proto_rawDescData
+}
+
+var file_integral_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_integral_proto_goTypes = []interface{}{
+	(*AddReq)(nil),    // 0: integral.addReq
+	(*AddResp)(nil),   // 1: integral.addResp
+	(*CheckReq)(nil),  // 2: integral.checkReq
+	(*CheckResp)(nil), // 3: integral.checkResp
+}
+var file_integral_proto_depIdxs = []int32{
+	0, // 0: integral.Integral.add:input_type -> integral.addReq
+	0, // 1: integral.Integral.update:input_type -> integral.addReq
+	2, // 2: integral.Integral.select:input_type -> integral.checkReq
+	1, // 3: integral.Integral.add:output_type -> integral.addResp
+	1, // 4: integral.Integral.update:output_type -> integral.addResp
+	3, // 5: integral.Integral.select:output_type -> integral.checkResp
+	3, // [3:6] is the sub-list for method output_type
+	0, // [0:3] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_integral_proto_init() }
+func file_integral_proto_init() {
+	if File_integral_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_integral_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AddReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_integral_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AddResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_integral_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CheckReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_integral_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CheckResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_integral_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_integral_proto_goTypes,
+		DependencyIndexes: file_integral_proto_depIdxs,
+		MessageInfos:      file_integral_proto_msgTypes,
+	}.Build()
+	File_integral_proto = out.File
+	file_integral_proto_rawDesc = nil
+	file_integral_proto_goTypes = nil
+	file_integral_proto_depIdxs = nil
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConnInterface
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion6
+
+// IntegralClient is the client API for Integral service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type IntegralClient interface {
+	Add(ctx context.Context, in *AddReq, opts ...grpc.CallOption) (*AddResp, error)
+	Update(ctx context.Context, in *AddReq, opts ...grpc.CallOption) (*AddResp, error)
+	Select(ctx context.Context, in *CheckReq, opts ...grpc.CallOption) (*CheckResp, error)
+}
+
+type integralClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewIntegralClient(cc grpc.ClientConnInterface) IntegralClient {
+	return &integralClient{cc}
+}
+
+func (c *integralClient) Add(ctx context.Context, in *AddReq, opts ...grpc.CallOption) (*AddResp, error) {
+	out := new(AddResp)
+	err := c.cc.Invoke(ctx, "/integral.Integral/add", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *integralClient) Update(ctx context.Context, in *AddReq, opts ...grpc.CallOption) (*AddResp, error) {
+	out := new(AddResp)
+	err := c.cc.Invoke(ctx, "/integral.Integral/update", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *integralClient) Select(ctx context.Context, in *CheckReq, opts ...grpc.CallOption) (*CheckResp, error) {
+	out := new(CheckResp)
+	err := c.cc.Invoke(ctx, "/integral.Integral/select", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// IntegralServer is the server API for Integral service.
+type IntegralServer interface {
+	Add(context.Context, *AddReq) (*AddResp, error)
+	Update(context.Context, *AddReq) (*AddResp, error)
+	Select(context.Context, *CheckReq) (*CheckResp, error)
+}
+
+// UnimplementedIntegralServer can be embedded to have forward compatible implementations.
+type UnimplementedIntegralServer struct {
+}
+
+func (*UnimplementedIntegralServer) Add(context.Context, *AddReq) (*AddResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Add not implemented")
+}
+func (*UnimplementedIntegralServer) Update(context.Context, *AddReq) (*AddResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
+}
+func (*UnimplementedIntegralServer) Select(context.Context, *CheckReq) (*CheckResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Select not implemented")
+}
+
+func RegisterIntegralServer(s *grpc.Server, srv IntegralServer) {
+	s.RegisterService(&_Integral_serviceDesc, srv)
+}
+
+func _Integral_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AddReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IntegralServer).Add(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/integral.Integral/Add",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IntegralServer).Add(ctx, req.(*AddReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Integral_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(AddReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IntegralServer).Update(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/integral.Integral/Update",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IntegralServer).Update(ctx, req.(*AddReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Integral_Select_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(CheckReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IntegralServer).Select(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/integral.Integral/Select",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IntegralServer).Select(ctx, req.(*CheckReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Integral_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "integral.Integral",
+	HandlerType: (*IntegralServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "add",
+			Handler:    _Integral_Add_Handler,
+		},
+		{
+			MethodName: "update",
+			Handler:    _Integral_Update_Handler,
+		},
+		{
+			MethodName: "select",
+			Handler:    _Integral_Select_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "integral.proto",
+}

+ 52 - 0
rpc/integralclient/integral.go

@@ -0,0 +1,52 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: integral.proto
+
+//go:generate mockgen -destination ./integral_mock.go -package integralclient -source $GOFILE
+
+package integralclient
+
+import (
+	"context"
+
+	"points_service/rpc/integral"
+
+	"github.com/tal-tech/go-zero/zrpc"
+)
+
+type (
+	AddReq    = integral.AddReq
+	AddResp   = integral.AddResp
+	CheckReq  = integral.CheckReq
+	CheckResp = integral.CheckResp
+
+	Integral interface {
+		Add(ctx context.Context, in *AddReq) (*AddResp, error)
+		Update(ctx context.Context, in *AddReq) (*AddResp, error)
+		Select(ctx context.Context, in *CheckReq) (*CheckResp, error)
+	}
+
+	defaultIntegral struct {
+		cli zrpc.Client
+	}
+)
+
+func NewIntegral(cli zrpc.Client) Integral {
+	return &defaultIntegral{
+		cli: cli,
+	}
+}
+
+func (m *defaultIntegral) Add(ctx context.Context, in *AddReq) (*AddResp, error) {
+	client := integral.NewIntegralClient(m.cli.Conn())
+	return client.Add(ctx, in)
+}
+
+func (m *defaultIntegral) Update(ctx context.Context, in *AddReq) (*AddResp, error) {
+	client := integral.NewIntegralClient(m.cli.Conn())
+	return client.Update(ctx, in)
+}
+
+func (m *defaultIntegral) Select(ctx context.Context, in *CheckReq) (*CheckResp, error) {
+	client := integral.NewIntegralClient(m.cli.Conn())
+	return client.Select(ctx, in)
+}

+ 12 - 0
rpc/internal/config/config.go

@@ -0,0 +1,12 @@
+package config
+
+import (
+	"github.com/tal-tech/go-zero/core/stores/cache"
+	"github.com/tal-tech/go-zero/zrpc"
+)
+
+type Config struct {
+	zrpc.RpcServerConf
+	DataSource string             // 手动代码
+	Cache      cache.CacheConf    // 手动代码
+}

+ 37 - 0
rpc/internal/logic/addlogic.go

@@ -0,0 +1,37 @@
+package logic
+
+import (
+	"context"
+	"points_service/rpc/model"
+
+	"points_service/rpc/integral"
+	"points_service/rpc/internal/svc"
+
+	"github.com/tal-tech/go-zero/core/logx"
+)
+
+type AddLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewAddLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddLogic {
+	return &AddLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *AddLogic) Add(in *integral.AddReq) (*integral.AddResp, error) {
+	// todo: add your logic here and delete this line
+	_, err := l.svcCtx.Model.Insert(model.Balance{
+		UserId:  in.UserId,
+		CountPoints: in.CountPoints,
+	})
+	if err != nil {
+		return nil, err
+	}
+	return &integral.AddResp{Status: true}, nil
+}

+ 30 - 0
rpc/internal/logic/selectlogic.go

@@ -0,0 +1,30 @@
+package logic
+
+import (
+	"context"
+
+	"points_service/rpc/integral"
+	"points_service/rpc/internal/svc"
+
+	"github.com/tal-tech/go-zero/core/logx"
+)
+
+type SelectLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewSelectLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SelectLogic {
+	return &SelectLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *SelectLogic) Select(in *integral.CheckReq) (*integral.CheckResp, error) {
+	// todo: add your logic here and delete this line
+
+	return &integral.CheckResp{}, nil
+}

+ 30 - 0
rpc/internal/logic/updatelogic.go

@@ -0,0 +1,30 @@
+package logic
+
+import (
+	"context"
+
+	"points_service/rpc/integral"
+	"points_service/rpc/internal/svc"
+
+	"github.com/tal-tech/go-zero/core/logx"
+)
+
+type UpdateLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLogic {
+	return &UpdateLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *UpdateLogic) Update(in *integral.AddReq) (*integral.AddResp, error) {
+	// todo: add your logic here and delete this line
+
+	return &integral.AddResp{}, nil
+}

+ 37 - 0
rpc/internal/server/integralserver.go

@@ -0,0 +1,37 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: integral.proto
+
+package server
+
+import (
+	"context"
+
+	"points_service/rpc/integral"
+	"points_service/rpc/internal/logic"
+	"points_service/rpc/internal/svc"
+)
+
+type IntegralServer struct {
+	svcCtx *svc.ServiceContext
+}
+
+func NewIntegralServer(svcCtx *svc.ServiceContext) *IntegralServer {
+	return &IntegralServer{
+		svcCtx: svcCtx,
+	}
+}
+
+func (s *IntegralServer) Add(ctx context.Context, in *integral.AddReq) (*integral.AddResp, error) {
+	l := logic.NewAddLogic(ctx, s.svcCtx)
+	return l.Add(in)
+}
+
+func (s *IntegralServer) Update(ctx context.Context, in *integral.AddReq) (*integral.AddResp, error) {
+	l := logic.NewUpdateLogic(ctx, s.svcCtx)
+	return l.Update(in)
+}
+
+func (s *IntegralServer) Select(ctx context.Context, in *integral.CheckReq) (*integral.CheckResp, error) {
+	l := logic.NewSelectLogic(ctx, s.svcCtx)
+	return l.Select(in)
+}

+ 19 - 0
rpc/internal/svc/servicecontext.go

@@ -0,0 +1,19 @@
+package svc
+
+import (
+	"github.com/tal-tech/go-zero/core/stores/sqlx"
+	"points_service/rpc/internal/config"
+	"points_service/rpc/model"
+)
+
+type ServiceContext struct {
+	Config config.Config
+	Model model.BalanceModel
+}
+
+func NewServiceContext(c config.Config) *ServiceContext {
+	return &ServiceContext{
+		Config: c,
+		Model: model.NewBalanceModel(sqlx.NewMysql(c.DataSource),c.Cache),
+	}
+}

+ 7 - 0
rpc/model/balance.sql

@@ -0,0 +1,7 @@
+CREATE TABLE `balance`
+(
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `userId` varchar(255) NOT NULL COMMENT '用户标识',
+  `countPoints` int NOT NULL COMMENT '合计',
+  PRIMARY KEY(`userId`)
+) ENGINE=InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '积分余额表' ROW_FORMAT = DYNAMIC;

+ 101 - 0
rpc/model/balancemodel.go

@@ -0,0 +1,101 @@
+package model
+
+import (
+	"database/sql"
+	"fmt"
+	"strings"
+
+	"github.com/tal-tech/go-zero/core/stores/cache"
+	"github.com/tal-tech/go-zero/core/stores/sqlc"
+	"github.com/tal-tech/go-zero/core/stores/sqlx"
+	"github.com/tal-tech/go-zero/core/stringx"
+	"github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx"
+)
+
+var (
+	balanceFieldNames          = builderx.RawFieldNames(&Balance{})
+	balanceRows                = strings.Join(balanceFieldNames, ",")
+	balanceRowsExpectAutoSet   = strings.Join(stringx.Remove(balanceFieldNames, "`create_time`", "`update_time`"), ",")
+	balanceRowsWithPlaceHolder = strings.Join(stringx.Remove(balanceFieldNames, "`userId`", "`create_time`", "`update_time`"), "=?,") + "=?"
+
+	cacheBalanceUserIdPrefix = "cache#balance#userId#"
+)
+
+type (
+	BalanceModel interface {
+		Insert(data Balance) (sql.Result, error)
+		FindOne(userId string) (*Balance, error)
+		Update(data Balance) error
+		Delete(userId string) error
+	}
+
+	defaultBalanceModel struct {
+		sqlc.CachedConn
+		table string
+	}
+
+	Balance struct {
+		Id          int64  `db:"id"`
+		UserId      string `db:"userId"`      // 用户标识
+		CountPoints int64  `db:"countPoints"` // 合计
+	}
+)
+
+func NewBalanceModel(conn sqlx.SqlConn, c cache.CacheConf) BalanceModel {
+	return &defaultBalanceModel{
+		CachedConn: sqlc.NewConn(conn, c),
+		table:      "`balance`",
+	}
+}
+
+func (m *defaultBalanceModel) Insert(data Balance) (sql.Result, error) {
+	query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?)", m.table, balanceRowsExpectAutoSet)
+	ret, err := m.ExecNoCache(query, data.Id, data.UserId, data.CountPoints)
+
+	return ret, err
+}
+
+func (m *defaultBalanceModel) FindOne(userId string) (*Balance, error) {
+	balanceUserIdKey := fmt.Sprintf("%s%v", cacheBalanceUserIdPrefix, userId)
+	var resp Balance
+	err := m.QueryRow(&resp, balanceUserIdKey, func(conn sqlx.SqlConn, v interface{}) error {
+		query := fmt.Sprintf("select %s from %s where `userId` = ? limit 1", balanceRows, m.table)
+		return conn.QueryRow(v, query, userId)
+	})
+	switch err {
+	case nil:
+		return &resp, nil
+	case sqlc.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}
+
+func (m *defaultBalanceModel) Update(data Balance) error {
+	balanceUserIdKey := fmt.Sprintf("%s%v", cacheBalanceUserIdPrefix, data.UserId)
+	_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
+		query := fmt.Sprintf("update %s set %s where `userId` = ?", m.table, balanceRowsWithPlaceHolder)
+		return conn.Exec(query, data.Id, data.CountPoints, data.UserId)
+	}, balanceUserIdKey)
+	return err
+}
+
+func (m *defaultBalanceModel) Delete(userId string) error {
+
+	balanceUserIdKey := fmt.Sprintf("%s%v", cacheBalanceUserIdPrefix, userId)
+	_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
+		query := fmt.Sprintf("delete from %s where `userId` = ?", m.table)
+		return conn.Exec(query, userId)
+	}, balanceUserIdKey)
+	return err
+}
+
+func (m *defaultBalanceModel) formatPrimary(primary interface{}) string {
+	return fmt.Sprintf("%s%v", cacheBalanceUserIdPrefix, primary)
+}
+
+func (m *defaultBalanceModel) queryPrimary(conn sqlx.SqlConn, v, primary interface{}) error {
+	query := fmt.Sprintf("select %s from %s where `userId` = ? limit 1", balanceRows, m.table)
+	return conn.QueryRow(v, query, primary)
+}

+ 5 - 0
rpc/model/vars.go

@@ -0,0 +1,5 @@
+package model
+
+import "github.com/tal-tech/go-zero/core/stores/sqlx"
+
+var ErrNotFound = sqlx.ErrNotFound