🐛 fix bug
This commit is contained in:
		| @@ -15,7 +15,8 @@ WORKDIR /go/src/miniapp | ||||
|  | ||||
| COPY --from=0 /go/src/miniapp/server ./ | ||||
| COPY --from=0 /go/src/miniapp/resource ./resource/ | ||||
| COPY --from=0 /go/src/miniapp/config.yaml ./ | ||||
| COPY --from=0 /go/src/miniapp/docker/config.docker.yaml ./docker/ | ||||
| COPY --from=0 /go/src/miniapp/docker ./ | ||||
|  | ||||
| EXPOSE 8888 | ||||
| ENTRYPOINT ./server -c config.yaml | ||||
| ENTRYPOINT ./server -c docker/config.docker.yaml | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| package app | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"git.echol.cn/loser/logger/log" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/medivhzhan/weapp/v3" | ||||
| 	msg "github.com/medivhzhan/weapp/v3/subscribemessage" | ||||
| 	"miniapp/api" | ||||
| 	"miniapp/model/app" | ||||
| 	"miniapp/model/app/request" | ||||
| @@ -86,6 +89,13 @@ func (u *UserApi) UpdateUser(ctx *gin.Context) { | ||||
| 	if p.Phone != "" { | ||||
| 		loginUser.Phone = p.Phone | ||||
| 	} | ||||
| 	if p.SurgeryTime != "" { | ||||
| 		//t, _ := time.Parse("2006-01-02", p.SurgeryTime) | ||||
| 		//format := t.UTC().Format("2006-01-02") | ||||
| 		loginUser.SurgeryTime = p.SurgeryTime | ||||
| 	} | ||||
| 	loginUser.IsSurgery = p.IsSurgery | ||||
| 	loginUser.HospitalId = p.HospitalId | ||||
| 	// 修改数据 | ||||
| 	if err := userService.UpdateUserInfo(&loginUser); err != nil { | ||||
| 		log.Errorf("修改用户信息失败:%s", err.Error()) | ||||
| @@ -137,3 +147,46 @@ func (u *UserApi) GetInfo(ctx *gin.Context) { | ||||
| 	} | ||||
| 	r.OkWithData(userInfo, ctx) | ||||
| } | ||||
|  | ||||
| // SendMedicineRemind 发送用药提醒消息 | ||||
| func (u *UserApi) SendMedicineRemind(ctx *gin.Context) { | ||||
| 	var req utils.SendRequest | ||||
| 	if err := ctx.ShouldBind(&req); err != nil { | ||||
| 		r.FailWithMessage("参数错误: "+err.Error(), ctx) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	//app-id: wxaaf66dbb5c3983b3 | ||||
| 	//app-secret: 0abba24dbff43febba1e551651f693b4 | ||||
| 	//template-id: PgxoZOOSDgBcmIGd_EVLDnYUmL3eu6NQTAZCsHQeuWY | ||||
|  | ||||
| 	sdk := weapp.NewClient("wxaaf66dbb5c3983b3", "0abba24dbff43febba1e551651f693b4") | ||||
|  | ||||
| 	msgData := msg.SendRequest{ | ||||
| 		ToUser:           "o9Fq_6_cYKvOWnyUM3McC11hWsTI", | ||||
| 		TemplateID:       "PgxoZOOSDgBcmIGd_EVLDnYUmL3eu6NQTAZCsHQeuWY", | ||||
| 		Page:             "page/index/todo", | ||||
| 		MiniprogramState: msg.MiniprogramStateTrial, | ||||
| 		Data: msg.SendData{ | ||||
| 			"thing1":        msg.SendValue{Value: "眼药水"}, | ||||
| 			"time2":         msg.SendValue{Value: "20:00"}, | ||||
| 			"short_thing17": msg.SendValue{Value: "一天4次"}, | ||||
| 			"time15":        msg.SendValue{Value: "2024-03-20 20:00"}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	send, err := sdk.NewSubscribeMessage().Send(&msgData) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = send.GetResponseError() | ||||
| 	if err != nil { | ||||
| 		fmt.Printf("微信返回错误: %#v", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("返回结果: %#v", send) | ||||
|  | ||||
| 	r.Ok(ctx) | ||||
| } | ||||
|   | ||||
| @@ -1,203 +0,0 @@ | ||||
| # miniapp Global Configuration | ||||
|  | ||||
| # jwt configuration | ||||
| jwt: | ||||
|   signing-key: qmPlus | ||||
|   expires-time: 7d | ||||
|   buffer-time: 1d | ||||
|   issuer: qmPlus | ||||
| # zap logger configuration | ||||
| zap: | ||||
|   level: info | ||||
|   format: console | ||||
|   prefix: "[miniapp]" | ||||
|   director: log | ||||
|   show-line: true | ||||
|   encode-level: LowercaseColorLevelEncoder | ||||
|   stacktrace-key: stacktrace | ||||
|   log-in-console: true | ||||
|  | ||||
| # redis configuration | ||||
| redis: | ||||
|   db: 0 | ||||
|   addr: 177.7.0.14:6379 | ||||
|   password: "" | ||||
|  | ||||
| # email configuration | ||||
| email: | ||||
|   to: xxx@qq.com | ||||
|   port: 465 | ||||
|   from: xxx@163.com | ||||
|   host: smtp.163.com | ||||
|   is-ssl: true | ||||
|   secret: xxx | ||||
|   nickname: test | ||||
|  | ||||
| # system configuration | ||||
| system: | ||||
|   env: public  # Change to "develop" to skip authentication for development mode | ||||
|   addr: 8888 | ||||
|   db-type: mysql | ||||
|   oss-type: local    # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server.exe.exe/utils/upload/upload.go 中 NewOss函数配置 | ||||
|   use-redis: false     # 使用redis | ||||
|   use-multipoint: false | ||||
|   # IP限制次数 一个小时15000次 | ||||
|   iplimit-count: 15000 | ||||
|   #  IP限制一个小时 | ||||
|   iplimit-time: 3600 | ||||
|  | ||||
| # captcha configuration | ||||
| captcha: | ||||
|   key-long: 6 | ||||
|   img-width: 240 | ||||
|   img-height: 80 | ||||
|   open-captcha: 0 # 0代表一直开启,大于0代表限制次数 | ||||
|   open-captcha-timeout: 3600 # open-captcha大于0时才生效 | ||||
|  | ||||
| # mysql connect configuration | ||||
| # 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master) | ||||
| mysql: | ||||
|   path: "" | ||||
|   port: "" | ||||
|   config: "" | ||||
|   db-name: "" | ||||
|   username: "" | ||||
|   password: "" | ||||
|   max-idle-conns: 10 | ||||
|   max-open-conns: 100 | ||||
|   log-mode: "" | ||||
|   log-zap: false | ||||
|  | ||||
| # pgsql connect configuration | ||||
| # 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master) | ||||
| pgsql: | ||||
|   path: "" | ||||
|   port: "" | ||||
|   config: "" | ||||
|   db-name: "" | ||||
|   username: "" | ||||
|   password: "" | ||||
|   max-idle-conns: 10 | ||||
|   max-open-conns: 100 | ||||
|   log-mode: "" | ||||
|   log-zap: false | ||||
|  | ||||
| db-list: | ||||
|   - disable: true # 是否禁用 | ||||
|     type: "" # 数据库的类型,目前支持mysql、pgsql | ||||
|     alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一 | ||||
|     path: "" | ||||
|     port: "" | ||||
|     config: "" | ||||
|     db-name: "" | ||||
|     username: "" | ||||
|     password: "" | ||||
|     max-idle-conns: 10 | ||||
|     max-open-conns: 100 | ||||
|     log-mode: "" | ||||
|     log-zap: false | ||||
|  | ||||
|  | ||||
| # local configuration | ||||
| local: | ||||
|   path: uploads/file | ||||
|   store-path: uploads/file | ||||
|  | ||||
| # autocode configuration | ||||
| autocode: | ||||
|   transfer-restart: true | ||||
|   # root 自动适配项目根目录 | ||||
|   # 请不要手动配置,他会在项目加载的时候识别出根路径 | ||||
|   root: "" | ||||
|   server: /server.exe.exe | ||||
|   server-plug: /plugin/%s | ||||
|   server-api: /api/v1/%s | ||||
|   server-initialize: /initialize | ||||
|   server-model: /model/%s | ||||
|   server-request: /model/%s/request/ | ||||
|   server-router: /router/%s | ||||
|   server-service: /service/%s | ||||
|   web: /web/src | ||||
|   web-api: /api | ||||
|   web-form: /view | ||||
|   web-table: /view | ||||
|  | ||||
| # qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址) | ||||
| qiniu: | ||||
|   zone: ZoneHuaDong | ||||
|   bucket: "" | ||||
|   img-path: "" | ||||
|   use-https: false | ||||
|   access-key: "" | ||||
|   secret-key: "" | ||||
|   use-cdn-domains: false | ||||
|  | ||||
| # aliyun oss configuration | ||||
| aliyun-oss: | ||||
|   endpoint: yourEndpoint | ||||
|   access-key-id: yourAccessKeyId | ||||
|   access-key-secret: yourAccessKeySecret | ||||
|   bucket-name: yourBucketName | ||||
|   bucket-url: yourBucketUrl | ||||
|   base-path: yourBasePath | ||||
|  | ||||
| # tencent cos configuration | ||||
| tencent-cos: | ||||
|   bucket: xxxxx-10005608 | ||||
|   region: ap-shanghai | ||||
|   secret-id: your-secret-id | ||||
|   secret-key: your-secret-key | ||||
|   base-url: https://gin.vue.admin | ||||
|   path-prefix: miniapp | ||||
|  | ||||
| # aws s3 configuration (minio compatible) | ||||
| aws-s3: | ||||
|   bucket: xxxxx-10005608 | ||||
|   region: ap-shanghai | ||||
|   endpoint: "" | ||||
|   s3-force-path-style: false | ||||
|   disable-ssl: false | ||||
|   secret-id: your-secret-id | ||||
|   secret-key: your-secret-key | ||||
|   base-url: https://gin.vue.admin | ||||
|   path-prefix: miniapp | ||||
|  | ||||
| # huawei obs configuration | ||||
| hua-wei-obs: | ||||
|   path: you-path | ||||
|   bucket: you-bucket | ||||
|   endpoint: you-endpoint | ||||
|   access-key: you-access-key | ||||
|   secret-key: you-secret-key | ||||
|  | ||||
| # excel configuration | ||||
| excel: | ||||
|   dir: ./resource/excel/ | ||||
|  | ||||
| # timer task db clear table | ||||
| Timer: | ||||
|   start: true | ||||
|   spec: "@daily"  # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3 | ||||
|   detail: | ||||
|     - tableName: sys_operation_records | ||||
|       compareField: created_at | ||||
|       interval: 2160h | ||||
|     - tableName: jwt_blacklists | ||||
|       compareField: created_at | ||||
|       interval: 168h | ||||
|  | ||||
| # 跨域配置 | ||||
| # 需要配合 server.exe.exe/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用 | ||||
| cors: | ||||
|   mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝 | ||||
|   whitelist: | ||||
|     - allow-origin: example1.com | ||||
|       allow-headers: content-type | ||||
|       allow-methods: GET, POST | ||||
|       expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type | ||||
|       allow-credentials: true # 布尔值 | ||||
|     - allow-origin: example2.com | ||||
|       allow-headers: content-type | ||||
|       allow-methods: GET, POST | ||||
|       expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type | ||||
|       allow-credentials: true # 布尔值 | ||||
| @@ -1,12 +1,12 @@ | ||||
| package config | ||||
|  | ||||
| // MiniApp 微信小程序配置 | ||||
| type MiniApp struct { | ||||
| 	AppId     string `mapstructure:"app-id" yaml:"app-id"` | ||||
| 	AppSecret string `mapstructure:"app-secret" yaml:"app-secret"` | ||||
| 	AppId      string `mapstructure:"app-id" yaml:"app-id"` | ||||
| 	AppSecret  string `mapstructure:"app-secret" yaml:"app-secret"` | ||||
| 	TemplateID string `mapstructure:"template-id" yaml:"template-id"` | ||||
| } | ||||
|  | ||||
| // 微信小程序配置 | ||||
|  | ||||
| // 微信支付配置 | ||||
| type wechatPayConfig struct { | ||||
| 	MchId      string `mapstructure:"mchId" yaml:"mchId"`           // 商户号 | ||||
|   | ||||
| @@ -79,12 +79,12 @@ mini-app: | ||||
|     app-secret: 0abba24dbff43febba1e551651f693b4 | ||||
| mysql: | ||||
|     prefix: "" | ||||
|     port: "3307" | ||||
|     port: "3306" | ||||
|     config: charset=utf8mb4&parseTime=True&loc=Local | ||||
|     db-name: mini_app | ||||
|     username: root | ||||
|     db-name: jmyl | ||||
|     username: jmyl | ||||
|     password: Jmyl123123 | ||||
|     path: 47.116.50.126 | ||||
|     path: 101.35.50.11 | ||||
|     engine: "" | ||||
|     log-mode: error | ||||
|     max-idle-conns: 10 | ||||
| @@ -92,8 +92,8 @@ mysql: | ||||
|     singular: false | ||||
|     log-zap: false | ||||
| redis: | ||||
|     addr: 47.116.50.126:6378 | ||||
|     password: "Jmyl123123" | ||||
|     addr: 101.35.50.11:6379 | ||||
|     password: "loser7659" | ||||
|     db: 0 | ||||
| system: | ||||
|     env: public | ||||
							
								
								
									
										132
									
								
								docker/config.docker.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								docker/config.docker.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| aliyun-oss: | ||||
|   endpoint: oss-cn-chengdu.aliyuncs.com | ||||
|   access-key-id: LTAI5tFHes6HBWJFUjuPwHso | ||||
|   access-key-secret: qXuWtEJvYEQvj9yhkmLYfRxHShheYa | ||||
|   bucket-name: jmyl-app | ||||
|   bucket-url: https://jmyl-app.oss-cn-chengdu.aliyuncs.com | ||||
|   base-path: miniapp | ||||
| autocode: | ||||
|   server-model: /model/%s | ||||
|   server-router: /router/%s | ||||
|   server: /server.exe.exe | ||||
|   server-api: /api/v1/%s | ||||
|   server-plug: /plugin/%s | ||||
|   server-initialize: /initialize | ||||
|   root: C:\Users\Administrator\Desktop | ||||
|   web-table: /view | ||||
|   web: /web/src | ||||
|   server-service: /service/%s | ||||
|   server-request: /model/%s/request/ | ||||
|   web-api: /api | ||||
|   web-form: /view | ||||
|   transfer-restart: true | ||||
| captcha: | ||||
|   key-long: 4 | ||||
|   img-width: 240 | ||||
|   img-height: 80 | ||||
|   open-captcha: 0 | ||||
|   open-captcha-timeout: 3600 | ||||
| cors: | ||||
|   mode: strict-whitelist | ||||
|   whitelist: | ||||
|     - allow-origin: example1.com | ||||
|       allow-methods: POST, GET | ||||
|       allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id | ||||
|       expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type | ||||
|       allow-credentials: true | ||||
|     - allow-origin: example2.com | ||||
|       allow-methods: GET, POST | ||||
|       allow-headers: content-type | ||||
|       expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type | ||||
|       allow-credentials: true | ||||
| db-list: | ||||
|   - type: "" | ||||
|     alias-name: "" | ||||
|     prefix: "" | ||||
|     port: "" | ||||
|     config: "" | ||||
|     db-name: "" | ||||
|     username: "" | ||||
|     password: "" | ||||
|     path: "" | ||||
|     engine: "" | ||||
|     log-mode: "" | ||||
|     max-idle-conns: 10 | ||||
|     max-open-conns: 100 | ||||
|     singular: false | ||||
|     log-zap: false | ||||
|     disable: true | ||||
| email: | ||||
|   to: xxx@qq.com | ||||
|   from: xxx@163.com | ||||
|   host: smtp.163.com | ||||
|   secret: xxx | ||||
|   nickname: test | ||||
|   port: 465 | ||||
|   is-ssl: true | ||||
| excel: | ||||
|   dir: ./resource/excel/ | ||||
| jwt: | ||||
|   signing-key: f2b1b2af-c8f1-43cf-88e4-40b0a64b5487 | ||||
|   expires-time: 7d | ||||
|   buffer-time: 1d | ||||
|   issuer: qmPlus | ||||
| local: | ||||
|   path: uploads/file | ||||
|   store-path: uploads/file | ||||
| mini-app: | ||||
|   app-id: wxaaf66dbb5c3983b3 | ||||
|   app-secret: 0abba24dbff43febba1e551651f693b4 | ||||
| mysql: | ||||
|   prefix: "" | ||||
|   port: "3307" | ||||
|   config: charset=utf8mb4&parseTime=True&loc=Local | ||||
|   db-name: mini_app | ||||
|   username: root | ||||
|   password: Jmyl123123 | ||||
|   path: 47.113.103.195 | ||||
|   engine: "" | ||||
|   log-mode: error | ||||
|   max-idle-conns: 10 | ||||
|   max-open-conns: 100 | ||||
|   singular: false | ||||
|   log-zap: false | ||||
| redis: | ||||
|   addr: 127.0.0.1:6379 | ||||
|   password: "Jmyl123123" | ||||
|   db: 0 | ||||
| system: | ||||
|   env: public | ||||
|   db-type: mysql | ||||
|   oss-type: aliyun-oss | ||||
|   router-prefix: "" | ||||
|   addr: 8888 | ||||
|   iplimit-count: 15000 | ||||
|   iplimit-time: 3600 | ||||
|   use-multipoint: false | ||||
|   use-redis: true | ||||
| timer: | ||||
|   spec: '@daily' | ||||
|   detail: | ||||
|     - tableName: sys_operation_records | ||||
|       compareField: created_at | ||||
|       interval: 2160h | ||||
|     - tableName: jwt_blacklists | ||||
|       compareField: created_at | ||||
|       interval: 168h | ||||
|   start: true | ||||
|   with_seconds: false | ||||
| zap: | ||||
|   level: info | ||||
|   prefix: '[miniapp]' | ||||
|   format: console | ||||
|   director: log | ||||
|   encode-level: LowercaseColorLevelEncoder | ||||
|   stacktrace-key: stacktrace | ||||
|   max-age: 0 | ||||
|   show-line: true | ||||
|   log-in-console: true | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
								
							| @@ -15,13 +15,14 @@ require ( | ||||
| 	github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 | ||||
| 	github.com/gin-gonic/gin v1.9.1 | ||||
| 	github.com/glebarez/sqlite v1.8.0 | ||||
| 	github.com/go-co-op/gocron v1.13.0 | ||||
| 	github.com/go-oauth2/oauth2/v4 v4.5.2 | ||||
| 	github.com/go-oauth2/redis/v4 v4.1.1 | ||||
| 	github.com/go-redis/redis/v8 v8.11.4 | ||||
| 	github.com/go-sql-driver/mysql v1.7.1 | ||||
| 	github.com/gofrs/uuid/v5 v5.0.0 | ||||
| 	github.com/golang-jwt/jwt/v4 v4.5.0 | ||||
| 	github.com/google/uuid v1.3.0 | ||||
| 	github.com/google/uuid v1.6.0 | ||||
| 	github.com/gookit/color v1.5.4 | ||||
| 	github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible | ||||
| 	github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84 | ||||
| @@ -37,7 +38,7 @@ require ( | ||||
| 	github.com/shirou/gopsutil/v3 v3.23.6 | ||||
| 	github.com/songzhibin97/gkit v1.2.11 | ||||
| 	github.com/spf13/viper v1.16.0 | ||||
| 	github.com/stretchr/testify v1.8.4 | ||||
| 	github.com/stretchr/testify v1.9.0 | ||||
| 	github.com/swaggo/files v1.0.1 | ||||
| 	github.com/swaggo/gin-swagger v1.6.0 | ||||
| 	github.com/swaggo/swag v1.16.2 | ||||
|   | ||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
								
							| @@ -137,6 +137,8 @@ github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0 | ||||
| github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E= | ||||
| github.com/glebarez/sqlite v1.8.0 h1:02X12E2I/4C1n+v90yTqrjRa8yuo7c3KeHI3FRznCvc= | ||||
| github.com/glebarez/sqlite v1.8.0/go.mod h1:bpET16h1za2KOOMb8+jCp6UBP/iahDpfPQqSaYLTLx8= | ||||
| github.com/go-co-op/gocron v1.13.0 h1:BjkuNImPy5NuIPEifhWItFG7pYyr27cyjS6BN9w/D4c= | ||||
| github.com/go-co-op/gocron v1.13.0/go.mod h1:GD5EIEly1YNW+LovFVx5dzbYVcIc8544K99D8UVRpGo= | ||||
| github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= | ||||
| github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= | ||||
| github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= | ||||
| @@ -264,8 +266,9 @@ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbu | ||||
| github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | ||||
| github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||||
| github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||||
| github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | ||||
| github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= | ||||
| github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= | ||||
| @@ -467,8 +470,8 @@ github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= | ||||
| github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||||
| github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= | ||||
| github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||||
| github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| @@ -480,8 +483,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO | ||||
| github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||||
| github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||||
| github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||||
| github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||||
| github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||||
| github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||||
| github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||||
| github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= | ||||
| github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= | ||||
| github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| package initialize | ||||
|  | ||||
| import ( | ||||
| 	swaggerFiles "github.com/swaggo/files" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	swaggerFiles "github.com/swaggo/files" | ||||
| 	ginSwagger "github.com/swaggo/gin-swagger" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"miniapp/global" | ||||
| 	"miniapp/middleware" | ||||
| @@ -31,7 +30,7 @@ func Routers() *gin.Engine { | ||||
| 	Router.StaticFS(global.GVA_CONFIG.Local.StorePath, http.Dir(global.GVA_CONFIG.Local.StorePath)) // 为用户头像和文件提供静态地址 | ||||
| 	// Router.Use(middleware.LoadTls())  // 如果需要使用https 请打开此中间件 然后前往 core/server.exe.exe.exe.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件") | ||||
| 	// 跨域,如需跨域可以打开下面的注释 | ||||
| 	// Router.Use(middleware.Cors()) // 直接放行全部跨域请求 | ||||
| 	Router.Use(middleware.Cors()) // 直接放行全部跨域请求 | ||||
| 	// Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求 | ||||
| 	//global.GVA_LOG.Info("use middleware cors") | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							| @@ -4,6 +4,7 @@ import ( | ||||
| 	"go.uber.org/zap" | ||||
| 	"miniapp/client" | ||||
| 	"miniapp/oauth2" | ||||
| 	"miniapp/task" | ||||
|  | ||||
| 	"miniapp/core" | ||||
| 	"miniapp/global" | ||||
| @@ -41,5 +42,6 @@ func main() { | ||||
| 	client.InitRedisClient() | ||||
| 	oauth2.InitOAuth2Server() // 初始化OAuth2服务 | ||||
| 	initialize.InitKp()       // 初始化关键词处理器 | ||||
| 	task.InitTask()           // 初始化定时任务 | ||||
| 	core.RunWindowsServer() | ||||
| } | ||||
|   | ||||
| @@ -21,9 +21,12 @@ type GetUserList struct { | ||||
|  | ||||
| // ChangeUserInfo 修改普通用户信息 | ||||
| type ChangeUserInfo struct { | ||||
| 	Nickname string `json:"nickname" form:"nickname"` // 昵称 | ||||
| 	Avatar   string `json:"avatar" form:"avatar"`     // 头像 | ||||
| 	Phone    string `json:"phone" form:"phone"`       // 手机号 | ||||
| 	Nickname    string `json:"nickname" form:"nickname"` // 昵称 | ||||
| 	Avatar      string `json:"avatar" form:"avatar"`     // 头像 | ||||
| 	Phone       string `json:"phone" form:"phone"`       // 手机号 | ||||
| 	IsSurgery   int    `json:"isSurgery" gorm:"default:0;comment:是否已经手术 0未手术 1已手术"` | ||||
| 	HospitalId  int    `json:"hospitalId" gorm:"comment:手术医院"` | ||||
| 	SurgeryTime string `json:"surgery_time" gorm:"comment:手术时间"` | ||||
| } | ||||
|  | ||||
| // ChangePassword 修改密码 | ||||
|   | ||||
| @@ -34,7 +34,7 @@ type UserVO struct { | ||||
| 	IsSurgery   int                 `json:"isSurgery" gorm:"default:0;comment:是否已经手术 0未手术 1已手术"` | ||||
| 	IsInfo      int                 `json:"isInfo" gorm:"default:0;comment:是否已经填写信息 0未填写 1已填写"` | ||||
| 	HospitalId  int                 `json:"hospital_id" gorm:"comment:手术医院"` | ||||
| 	SurgeryTime time.Time           `json:"surgery_time" gorm:"comment:手术时间"` | ||||
| 	SurgeryTime string              `json:"surgery_time" gorm:"comment:手术时间"` | ||||
| 	Todos       []common.UserTodo   `json:"todos" gorm:"comment:用户待办事项"` | ||||
| 	Notes       []common.Notes      `json:"notes" gorm:"comment:用户须知"` | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ type User struct { | ||||
| 	IsSurgery     int                 `json:"isSurgery" gorm:"default:0;comment:是否已经手术 0未手术 1已手术"` | ||||
| 	IsInfo        int                 `json:"isInfo" gorm:"default:0;comment:是否已经填写信息 0未填写 1已填写"` | ||||
| 	HospitalId    int                 `json:"hospital_id" gorm:"comment:手术医院"` | ||||
| 	SurgeryTime   time.Time           `json:"surgery_time" gorm:"comment:手术时间"` | ||||
| 	SurgeryTime   string              `json:"surgery_time" gorm:"comment:手术时间"` | ||||
| 	LastLoginAt   *time.Time          `json:"last_login_at" gorm:"comment:'最后登录时间'"` | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -4,3 +4,10 @@ type GetUserNotes struct { | ||||
| 	UserId   string `json:"userId" form:"userId" binding:"required"` | ||||
| 	IsFinish string `json:"isFinish" form:"isFinish" binding:"required"` | ||||
| } | ||||
|  | ||||
| type TodoTask struct { | ||||
| 	OpenId     string `json:"openId" form:"openId"` | ||||
| 	Context    string `json:"context" form:"context"` | ||||
| 	Frequency  string `json:"frequency" form:"frequency"` | ||||
| 	RemindTime string `json:"remindTime" form:"remindTime"` | ||||
| } | ||||
|   | ||||
| @@ -5,7 +5,11 @@ import "miniapp/global" | ||||
| type Todos struct { | ||||
| 	// 任务列表 | ||||
| 	global.GVA_MODEL | ||||
| 	Content string `json:"content" form:"content" gorm:"comment:任务内容;"` | ||||
| 	Content      string `json:"content" form:"content" gorm:"comment:任务内容;"` | ||||
| 	RemindTime   string `json:"remindTime" form:"remindTime" gorm:"comment:提醒时间;"` | ||||
| 	RemindPeriod int    `json:"remindPeriod" form:"remindPeriod" gorm:"comment:0术前,1术后;"` | ||||
| 	Frequency    string `json:"frequency" form:"frequency" gorm:"comment:用药频率;"` | ||||
| 	RemindDay    string `json:"remindDay" form:"remindDay" gorm:"comment:提醒日期;"` | ||||
| } | ||||
|  | ||||
| func (t Todos) TableName() string { | ||||
|   | ||||
| @@ -4,9 +4,13 @@ import "miniapp/global" | ||||
|  | ||||
| type UserTodo struct { | ||||
| 	global.GVA_MODEL | ||||
| 	UserId   int    `json:"userId" form:"userId" gorm:"comment:用户id;"` | ||||
| 	Content  string `json:"content" form:"content" gorm:"comment:任务内容;"` | ||||
| 	IsFinish int    `json:"isFinish" form:"isFinish" gorm:"comment:是否完成;"` | ||||
| 	UserId       int    `json:"userId" form:"userId" gorm:"comment:用户id;"` | ||||
| 	Content      string `json:"content" form:"content" gorm:"comment:任务内容;"` | ||||
| 	IsFinish     int    `json:"isFinish" form:"isFinish" gorm:"comment:是否完成;"` | ||||
| 	RemindTime   string `json:"remindTime" form:"remindTime" gorm:"comment:提醒时间;"` | ||||
| 	RemindPeriod int    `json:"remindPeriod" form:"remindPeriod" gorm:"comment:术前,术后;"` | ||||
| 	Frequency    string `json:"frequency" form:"frequency" gorm:"comment:用药频率;"` | ||||
| 	RemindDay    string `json:"remindDay" form:"remindDay" gorm:"comment:提醒日期;"` | ||||
| } | ||||
|  | ||||
| func (u UserTodo) TableName() string { | ||||
|   | ||||
| @@ -15,7 +15,7 @@ type SysOperationRecord struct { | ||||
| 	Path         string        `json:"path" form:"path" gorm:"column:path;comment:请求路径"`                             // 请求路径 | ||||
| 	Status       int           `json:"status" form:"status" gorm:"column:status;comment:请求状态"`                       // 请求状态 | ||||
| 	Latency      time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:延迟" swaggertype:"string"` // 延迟 | ||||
| 	Agent        string        `json:"agent" form:"agent" gorm:"column:agent;comment:代理"`                            // 代理 | ||||
| 	Agent        string        `json:"agent" form:"agent" gorm:"column:agent; type:longtext; comment:代理"`            // 代理 | ||||
| 	ErrorMessage string        `json:"error_message" form:"error_message" gorm:"column:error_message;comment:错误信息"`  // 错误信息 | ||||
| 	Body         string        `json:"body" form:"body" gorm:"type:text;column:body;comment:请求Body"`                 // 请求Body | ||||
| 	Resp         string        `json:"resp" form:"resp" gorm:"type:text;column:resp;comment:响应Body"`                 // 响应Body | ||||
|   | ||||
| @@ -116,6 +116,9 @@ func ExtensionFields(ti oauth2.TokenInfo) (fieldsValue map[string]any) { | ||||
| 	fieldsValue["IsSurgery"] = userInfo.IsSurgery | ||||
| 	fieldsValue["HospitalId"] = userInfo.HospitalId | ||||
| 	fieldsValue["IsInfo"] = userInfo.IsInfo | ||||
| 	fieldsValue["SurgeryTime"] = userInfo.SurgeryTime | ||||
| 	fieldsValue["HospitalId"] = userInfo.HospitalId | ||||
| 	fieldsValue["IsSurgery"] = userInfo.IsSurgery | ||||
|  | ||||
| 	return | ||||
| } | ||||
|   | ||||
| @@ -25,6 +25,7 @@ func (s *LoginRouter) InitUserRouter(Router *gin.RouterGroup) { | ||||
| 		userRouter.GET("todo", todoApi.GetUserTodos) | ||||
| 		userRouter.PUT("todo", todoApi.UpdateTodo) | ||||
|  | ||||
| 		userRouter.POST("msg", baseApi.SendMedicineRemind) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"miniapp/model/app/request" | ||||
| 	"miniapp/model/app/response" | ||||
| 	"miniapp/model/common" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| @@ -49,7 +50,53 @@ func (UserService) CheckUnionIdIsExist(unionId, openId string) bool { | ||||
|  | ||||
| // UpdateUserInfo 更新普通用户信息 | ||||
| func (UserService) UpdateUserInfo(e *app.User) (err error) { | ||||
| 	return global.GVA_DB.Updates(&e).Error | ||||
| 	tUser := app.User{} | ||||
| 	err = global.GVA_DB.Where("id = ?", e.ID).First(&tUser).Error | ||||
|  | ||||
| 	err = global.GVA_DB.Updates(&e).Error | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新用户信息失败", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if e.SurgeryTime != "" { | ||||
| 		if tUser.HospitalId != e.HospitalId { | ||||
|  | ||||
| 			err = global.GVA_DB.Delete(&common.UserTodo{}, "user_id = ?", e.ID).Error | ||||
| 			if err != nil { | ||||
| 				global.GVA_LOG.Error("清除用户Todo列表失败", zap.Error(err)) | ||||
| 				return | ||||
| 			} | ||||
| 			var hospital common.Hospital | ||||
| 			err = global.GVA_DB.Where("id = ?", e.HospitalId).Preload("Todos").First(&hospital).Error | ||||
| 			if err != nil { | ||||
| 				global.GVA_LOG.Error("获取医院信息失败", zap.Error(err)) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			if len(hospital.Todos) != 0 { | ||||
| 				var userTodos []common.UserTodo | ||||
| 				for _, todo := range hospital.Todos { | ||||
| 					for _, s := range strings.Split(todo.RemindTime, ",") { | ||||
| 						userTodos = append(userTodos, common.UserTodo{ | ||||
| 							Content:      todo.Content, | ||||
| 							UserId:       int(e.ID), | ||||
| 							IsFinish:     0, | ||||
| 							RemindTime:   s, | ||||
| 							RemindPeriod: todo.RemindPeriod, | ||||
| 						}) | ||||
| 					} | ||||
| 				} | ||||
| 				err = global.GVA_DB.Create(&userTodos).Error | ||||
| 				if err != nil { | ||||
| 					global.GVA_LOG.Error("创建用户Todo列表失败", zap.Error(err)) | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // GetAverageUserList 查询普通用户列表 | ||||
| @@ -126,11 +173,15 @@ func (UserService) UpdateUserHospital(r *request.ChangeUserHospital) (err error) | ||||
| 	if len(hospital.Todos) != 0 { | ||||
| 		var userTodos []common.UserTodo | ||||
| 		for _, todo := range hospital.Todos { | ||||
| 			userTodos = append(userTodos, common.UserTodo{ | ||||
| 				Content:  todo.Content, | ||||
| 				UserId:   r.UserId, | ||||
| 				IsFinish: 0, | ||||
| 			}) | ||||
| 			for _, s := range strings.Split(todo.RemindTime, ",") { | ||||
| 				userTodos = append(userTodos, common.UserTodo{ | ||||
| 					Content:      todo.Content, | ||||
| 					UserId:       r.UserId, | ||||
| 					IsFinish:     0, | ||||
| 					RemindTime:   s, | ||||
| 					RemindPeriod: todo.RemindPeriod, | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 		err = global.GVA_DB.Create(&userTodos).Error | ||||
| 		if err != nil { | ||||
| @@ -139,9 +190,9 @@ func (UserService) UpdateUserHospital(r *request.ChangeUserHospital) (err error) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	t, _ := time.Parse("2006-01-02", r.SurgeryTime) | ||||
| 	//t, _ := time.Parse("2006-01-02", r.SurgeryTime) | ||||
|  | ||||
| 	err = global.GVA_DB.Table("t_user").Where("id = ?", r.UserId).Updates(app.User{IsInfo: 1, HospitalId: r.HospitalId, SurgeryTime: t}).Error | ||||
| 	err = global.GVA_DB.Table("t_user").Where("id = ?", r.UserId).Updates(app.User{IsInfo: 1, HospitalId: r.HospitalId, SurgeryTime: r.SurgeryTime}).Error | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新用户信息失败", zap.Error(err)) | ||||
| 		return | ||||
|   | ||||
| @@ -23,12 +23,48 @@ func (h HospitalService) CreateHospital(hospital *common.Hospital) (err error) { | ||||
|  | ||||
| // UpdateHospital 更新医院 | ||||
| func (h HospitalService) UpdateHospital(hospital *common.Hospital) (err error) { | ||||
| 	return global.GVA_DB.Updates(&hospital).Error | ||||
| 	for i := range hospital.Notes { | ||||
| 		if hospital.Notes[i].NotesTime == "手术前" { | ||||
| 			hospital.Notes[i].NotestimeNum = 1 | ||||
| 		} else if hospital.Notes[i].NotesTime == "手术中" { | ||||
| 			hospital.Notes[i].NotestimeNum = 2 | ||||
| 		} else { | ||||
| 			hospital.Notes[i].NotestimeNum = 3 | ||||
| 		} | ||||
| 	} | ||||
| 	err = global.GVA_DB.Model(&common.Notes{}).Save(&hospital.Notes).Error | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新医院注意事项失败", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
| 	err = global.GVA_DB.Model(&hospital).Association("Notes").Replace(&hospital.Notes) | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新医院注意事项失败", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = global.GVA_DB.Model(&common.Todos{}).Save(&hospital.Todos).Error | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新医院Todo失败", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
| 	err = global.GVA_DB.Model(&hospital).Association("Todos").Replace(&hospital.Todos) | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("更新医院Todo关联失败", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	return global.GVA_DB.Save(&hospital).Error | ||||
| } | ||||
|  | ||||
| // DeleteHospital 删除医院 | ||||
| func (h HospitalService) DeleteHospital(hospital *common.Hospital) (err error) { | ||||
| 	return global.GVA_DB.Select("Notes").Delete(&hospital).Error | ||||
| 	err = global.GVA_DB.Model(&hospital).Association("Notes").Clear() | ||||
| 	err = global.GVA_DB.Model(&hospital).Association("Todos").Clear() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return global.GVA_DB.Delete(&hospital).Error | ||||
| } | ||||
|  | ||||
| // GetHospitalById 根据id获取医院 | ||||
|   | ||||
							
								
								
									
										18
									
								
								task/task.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								task/task.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| package task | ||||
|  | ||||
| import ( | ||||
| 	"github.com/go-co-op/gocron" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var WxTask *gocron.Scheduler | ||||
|  | ||||
| func InitTask() { | ||||
| 	WxTask = gocron.NewScheduler(time.Local) | ||||
|  | ||||
| 	// 每天凌晨1点执行 | ||||
| 	_, _ = WxTask.Every(1).Day().At("01:00").Do(CheckUserSurgeryDate) // 检查用户是否已到手术日期 | ||||
|  | ||||
| 	// 开启定时任务 | ||||
| 	WxTask.StartAsync() | ||||
| } | ||||
							
								
								
									
										19
									
								
								task/user.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								task/user.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| package task | ||||
|  | ||||
| import ( | ||||
| 	"miniapp/global" | ||||
| 	"miniapp/model/app" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // CheckUserSurgeryDate 检查用户是否已到手术日期 | ||||
| func CheckUserSurgeryDate() { | ||||
| 	var users []app.User | ||||
| 	global.GVA_DB.Model(&app.User{}).Find(&users) | ||||
| 	for _, user := range users { | ||||
| 		parse, _ := time.Parse("2006-01-02", user.SurgeryTime) | ||||
| 		if time.Now().Sub(parse).Hours()/24 == 0 { | ||||
| 			global.GVA_DB.Model(&app.User{}).Where("id = ?", user.ID).Updates(app.User{IsSurgery: 1}) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										83
									
								
								task/wxMsg.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								task/wxMsg.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| package task | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/medivhzhan/weapp/v3" | ||||
| 	msg "github.com/medivhzhan/weapp/v3/subscribemessage" | ||||
| 	"go.uber.org/zap" | ||||
| 	"miniapp/global" | ||||
| 	"miniapp/model/app" | ||||
| 	"miniapp/model/common" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func SendMsg(userId int) { | ||||
| 	var user app.User | ||||
| 	err := global.GVA_DB.Model(&user).Where("id = ?", userId).Find(&user).Error | ||||
| 	if err != nil { | ||||
| 		global.GVA_LOG.Error("获取用户信息失败:%s", zap.Error(err)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// 获取用户待办列表 | ||||
| 	var userTodo []common.UserTodo | ||||
| 	if user.IsSurgery == 0 { | ||||
| 		err = global.GVA_DB.Model(&userTodo).Where("user_id = ? and is_finish = ? and remind_period = 0", userId, 0).Find(&userTodo).Error | ||||
| 		if err != nil { | ||||
| 			global.GVA_LOG.Error("获取用户待办列表:%s", zap.Error(err)) | ||||
| 			return | ||||
| 		} | ||||
| 	} else { | ||||
| 		err = global.GVA_DB.Model(&userTodo).Where("user_id = ? and is_finish = ? and remind_period = 1", userId, 0).Find(&userTodo).Error | ||||
| 		if err != nil { | ||||
| 			global.GVA_LOG.Error("获取用户待办列表:%s", zap.Error(err)) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// 根据用户手术信息 发送提醒消息 | ||||
| 	parse, _ := time.Parse("2006-01-02", user.SurgeryTime) | ||||
| 	if time.Now().Sub(parse).Hours()/24 <= -3 { | ||||
| 		for _, todo := range userTodo { | ||||
| 			jbo, _ := WxTask.Every(1).Day().At(todo.RemindTime).Do(MiniappSendMsg, *user.WechatOpenId, todo.Content, todo.RemindPeriod, todo.RemindTime) // 检查用户待办事项 | ||||
| 			s := strings.Split("一天3次", "")[2] | ||||
| 			// 将s转为int类型 | ||||
| 			atoi, _ := strconv.Atoi(s) | ||||
| 			if jbo.RunCount() == atoi { | ||||
| 				WxTask.Remove(jbo) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func MiniappSendMsg(openId string, context string, frequency string, remindTime string) { | ||||
| 	sdk := weapp.NewClient(global.GVA_CONFIG.MiniApp.AppId, global.GVA_CONFIG.MiniApp.AppSecret) | ||||
|  | ||||
| 	msgData := msg.SendRequest{ | ||||
| 		ToUser:           openId, | ||||
| 		TemplateID:       "PgxoZOOSDgBcmIGd_EVLDnYUmL3eu6NQTAZCsHQeuWY", | ||||
| 		Page:             "/page/index/todo", | ||||
| 		MiniprogramState: msg.MiniprogramStateTrial, | ||||
| 		Data: msg.SendData{ | ||||
| 			"thing1":        msg.SendValue{Value: context}, | ||||
| 			"time2":         msg.SendValue{Value: remindTime}, | ||||
| 			"short_thing17": msg.SendValue{Value: frequency}, | ||||
| 			"time15":        msg.SendValue{Value: time.DateTime}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	send, err := sdk.NewSubscribeMessage().Send(&msgData) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = send.GetResponseError() | ||||
| 	if err != nil { | ||||
| 		fmt.Printf("微信返回错误: %#v", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("返回结果: %#v", send) | ||||
| } | ||||
							
								
								
									
										190
									
								
								utils/wx_msg.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								utils/wx_msg.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"crypto/sha1" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"miniapp/global" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| //type wxMsg struct{} | ||||
| // | ||||
| //func WxMsgUtils() *wxMsg { | ||||
| //	return &wxMsg{} | ||||
| //} | ||||
|  | ||||
| type Wechat struct { | ||||
| 	appID       string | ||||
| 	secret      string | ||||
| 	templateID  string | ||||
| 	accessToken *AccessToken | ||||
| 	sync.Mutex | ||||
| } | ||||
|  | ||||
| type OpenIDResponse struct { | ||||
| 	Openid     string `json:"openid"` | ||||
| 	SessionKey string `json:"session_key"` | ||||
| 	Unionid    string `json:"unionid"` | ||||
| 	WxErr | ||||
| } | ||||
|  | ||||
| type CheckTokenRequest struct { | ||||
| 	Signature string `json:"signature"` | ||||
| 	Timestamp string `json:"timestamp"` | ||||
| 	Nonce     string `json:"nonce"` | ||||
| 	Echostr   string `json:"echostr"` | ||||
| } | ||||
|  | ||||
| type WxErr struct { | ||||
| 	Errcode int    `json:"errcode"` | ||||
| 	Errmsg  string `json:"errmsg"` | ||||
| } | ||||
|  | ||||
| type AccessToken struct { | ||||
| 	AccessToken string `json:"access_token"` | ||||
| 	ExpiresIn   int64  `json:"expires_in"` | ||||
| 	WxErr | ||||
| } | ||||
|  | ||||
| type SendRequest struct { | ||||
| 	Touser          string  `json:"touser"` | ||||
| 	Page            string  `json:"page"` | ||||
| 	Data            Message `json:"data"` | ||||
| 	EmphasisKeyword string  `json:"emphasis_keyword"` | ||||
| } | ||||
|  | ||||
| type Message map[string]interface{} | ||||
|  | ||||
| func (w *Wechat) SendMsg(req SendRequest) (err error) { | ||||
| 	token, err := w.GetAccessToken() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	api, err := TokenAPI("https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send", token) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	for key := range req.Data { | ||||
| 		req.Data[key] = Message{"value": req.Data[key]} | ||||
| 	} | ||||
| 	body := map[string]interface{}{ | ||||
| 		"touser":           "o9Fq_6_cYKvOWnyUM3McC11hWsTI", | ||||
| 		"template_id":      global.GVA_CONFIG.MiniApp.TemplateID, | ||||
| 		"page":             "/pages/index/todo", | ||||
| 		"data":             req.Data, | ||||
| 		"emphasis_keyword": req.EmphasisKeyword, | ||||
| 	} | ||||
|  | ||||
| 	b, err := json.Marshal(body) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	res, err := http.Post(api, "application/json", strings.NewReader(string(b))) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer res.Body.Close() | ||||
|  | ||||
| 	if res.StatusCode != 200 { | ||||
| 		err = errors.New("WECHAT_SERVER_ERROR") | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var resp WxErr | ||||
| 	if err = json.NewDecoder(res.Body).Decode(&resp); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if resp.Errcode != 0 { | ||||
| 		return errors.New(resp.Errmsg) | ||||
| 	} | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func (w *Wechat) GetAccessToken() (token string, err error) { | ||||
| 	w.Lock() | ||||
| 	defer w.Unlock() | ||||
| 	if w.accessToken == nil || w.accessToken.ExpiresIn < time.Now().Unix() { | ||||
| 		for i := 0; i < 3; i++ { | ||||
| 			err = w.getAccessToken() | ||||
| 			if err == nil { | ||||
| 				break | ||||
| 			} | ||||
| 			time.Sleep(time.Second) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	token = w.accessToken.AccessToken | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (w *Wechat) CheckSignature(req CheckTokenRequest) (err error) { | ||||
| 	if sig := w.sortSha1(req.Timestamp, req.Nonce, req.Echostr); sig != req.Signature { | ||||
| 		err = errors.New("check signature failed.") | ||||
| 		return | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func TokenAPI(api, token string) (string, error) { | ||||
| 	u, err := url.Parse(api) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	query := u.Query() | ||||
| 	query.Set("access_token", token) | ||||
| 	u.RawQuery = query.Encode() | ||||
|  | ||||
| 	return u.String(), nil | ||||
| } | ||||
|  | ||||
| func (w *Wechat) getAccessToken() (err error) { | ||||
| 	urls, err := url.Parse("https://api.weixin.qq.com/cgi-bin/token") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	query := urls.Query() | ||||
| 	query.Set("appid", w.appID) | ||||
| 	query.Set("secret", w.secret) | ||||
| 	query.Set("grant_type", "client_credential") | ||||
|  | ||||
| 	urls.RawQuery = query.Encode() | ||||
|  | ||||
| 	res, err := http.Get(urls.String()) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	defer res.Body.Close() | ||||
|  | ||||
| 	if res.StatusCode != 200 { | ||||
| 		return errors.New("wechat internal server error.") | ||||
| 	} | ||||
|  | ||||
| 	var token AccessToken | ||||
| 	if err = json.NewDecoder(res.Body).Decode(&token); err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if token.Errcode != 0 { | ||||
| 		return errors.New(token.Errmsg) | ||||
| 	} | ||||
| 	w.accessToken.AccessToken = token.AccessToken | ||||
| 	w.accessToken.ExpiresIn = token.ExpiresIn | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (w *Wechat) sortSha1(s ...string) string { | ||||
| 	sort.Strings(s) | ||||
| 	h := sha1.New() | ||||
| 	h.Write([]byte(strings.Join(s, ""))) | ||||
| 	return fmt.Sprintf("%x", h.Sum(nil)) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user