openPower.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. "log"
  8. "time"
  9. . "app.yhyue.com/moapp/jybase/common"
  10. "app.yhyue.com/moapp/jybase/date"
  11. "app.yhyue.com/moapp/jybase/mongodb"
  12. ml "app.yhyue.com/moapp/jybase/mysql"
  13. . "app.yhyue.com/moapp/jypkg/middleground"
  14. "bp.jydev.jianyu360.cn/BaseService/resourceCenter/rpc/pb"
  15. "bp.jydev.jianyu360.cn/BaseService/resourceCenter/rpc/resource"
  16. upb "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
  17. "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/usercenter"
  18. )
  19. const (
  20. appid = "10000"
  21. )
  22. var (
  23. etcdAddress []string
  24. BaseService *ml.Mysql
  25. Mgo *mongodb.MongodbSim
  26. JyOrder *ml.Mysql
  27. goodsCode string
  28. goodsSpecId int64
  29. all map[string]string
  30. powerType string
  31. middleground *Middleground
  32. allEntity = map[string]Entity{
  33. "yxy": &Yxy{},
  34. }
  35. c *Config
  36. )
  37. type Config struct {
  38. EtcdAddr []string
  39. Mongodb struct {
  40. Main *mgoConf
  41. }
  42. Mysql struct {
  43. Main *mysqlConf
  44. Base *mysqlConf
  45. }
  46. Products map[string]*Common
  47. }
  48. type mgoConf struct {
  49. Address string
  50. Size int
  51. DbName string
  52. ReplSet string
  53. UserName string
  54. Password string
  55. Collection string
  56. }
  57. type mysqlConf struct {
  58. DbName string
  59. Address string
  60. UserName string
  61. PassWord string
  62. MaxOpenConns int
  63. MaxIdleConns int
  64. }
  65. func init() {
  66. ReadConfig(&c)
  67. }
  68. func main() {
  69. allT := "yxy:医械云"
  70. for k, v := range c.Products {
  71. allEntity[k] = v
  72. allT += " " + k + ":" + v.Name
  73. }
  74. phone := flag.String("p", "", "手机号")
  75. m := flag.Int("m", 0, "1:查询权益 2:开通权益 3:取消权益")
  76. t := flag.String("t", "", allT)
  77. dayCount := flag.Int("c", 0, "自定义设置需要开通权益的天数,包含今天")
  78. entName := flag.String("n", "", "企业名称")
  79. isCheck := flag.Int("b", 1, "是否前置校验和后置处理")
  80. powerWay := flag.Int("a", 0, "权益开通/取消方式;0:一个身份 1:全部身份 2:仅仅企业上")
  81. flag.Parse()
  82. if *phone == "" {
  83. log.Fatalln("-p 参数无效")
  84. }
  85. entity := allEntity[*t]
  86. if entity == nil {
  87. log.Fatalln("-t 参数无效")
  88. }
  89. powerType, goodsCode, goodsSpecId, all = entity.init()
  90. middleground = NewMiddleground(c.EtcdAddr)
  91. middleground.RegResourceCenter("resource.rpc").RegUserCenter("usercenter.rpc")
  92. //
  93. BaseService = &ml.Mysql{
  94. Address: c.Mysql.Base.Address,
  95. UserName: c.Mysql.Base.UserName,
  96. PassWord: c.Mysql.Base.PassWord,
  97. DBName: c.Mysql.Base.DbName,
  98. MaxOpenConns: c.Mysql.Base.MaxOpenConns,
  99. MaxIdleConns: c.Mysql.Base.MaxIdleConns,
  100. }
  101. BaseService.Init()
  102. //
  103. JyOrder = &ml.Mysql{
  104. Address: c.Mysql.Main.Address,
  105. UserName: c.Mysql.Main.UserName,
  106. PassWord: c.Mysql.Main.PassWord,
  107. DBName: c.Mysql.Main.DbName,
  108. MaxOpenConns: c.Mysql.Main.MaxOpenConns,
  109. MaxIdleConns: c.Mysql.Main.MaxIdleConns,
  110. }
  111. JyOrder.Init()
  112. //
  113. Mgo = &mongodb.MongodbSim{
  114. MongodbAddr: c.Mongodb.Main.Address,
  115. Size: c.Mongodb.Main.Size,
  116. DbName: c.Mongodb.Main.DbName,
  117. ReplSet: c.Mongodb.Main.ReplSet,
  118. UserName: c.Mongodb.Main.UserName,
  119. Password: c.Mongodb.Main.Password,
  120. }
  121. Mgo.InitPool()
  122. //
  123. ur, _ := Mgo.Find("user", map[string]interface{}{
  124. "$or": []map[string]interface{}{
  125. map[string]interface{}{
  126. "s_phone": *phone,
  127. },
  128. map[string]interface{}{
  129. "s_m_phone": *phone,
  130. },
  131. },
  132. "i_appid": 2,
  133. }, nil, `{"base_user_id":1}`, false, -1, -1)
  134. if ur == nil || len(*ur) <= 0 {
  135. log.Fatalln("没有找到该用户!")
  136. }
  137. for _, v := range *ur {
  138. id := Int64All(v["base_user_id"])
  139. for _, identity := range middleground.UserCenter.IdentityList(id) {
  140. if *powerWay == 0 {
  141. if *entName == "" && identity.PositionType == 1 {
  142. continue
  143. } else if *entName != "" && (identity.PositionType == 0 || *entName != identity.Name) {
  144. continue
  145. }
  146. } else if *powerWay == 2 {
  147. if *entName == "" {
  148. continue
  149. } else if identity.PositionType == 0 || *entName != identity.Name {
  150. continue
  151. }
  152. }
  153. msg := "身份信息:" + fmt.Sprintf("%+v", identity) + " 手机号:" + *phone
  154. var c = resource.NewResource(middleground.ResourceCenter.NewClient())
  155. if *m == 1 {
  156. r, err := c.Haspowers(context.Background(), &pb.HaspowersReq{
  157. Appid: "10000",
  158. EntId: identity.EntId,
  159. EntUserId: identity.EntUserId,
  160. AccountId: identity.AccountId,
  161. EntAccountId: identity.EntAccountId,
  162. })
  163. if err != nil {
  164. log.Println(msg, "查询", powerType, "权益失败!", err)
  165. } else {
  166. mp := map[string]bool{}
  167. for _, v := range r.Powers {
  168. mp[v] = true
  169. }
  170. flag := true
  171. for k, v := range all {
  172. if !mp[v] {
  173. log.Println(msg, powerType, "权益异常,缺少权益:", k)
  174. flag = false
  175. continue
  176. }
  177. }
  178. if flag {
  179. for k, _ := range all {
  180. log.Println(msg, "拥有", powerType, "权益:", k)
  181. }
  182. }
  183. }
  184. } else if *m == 2 {
  185. if *isCheck == 1 && !entity.beforeOpen(phone, identity) {
  186. return
  187. }
  188. endTime := ""
  189. if *dayCount > 0 {
  190. now := time.Now()
  191. end_time := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local)
  192. end_time = end_time.AddDate(0, 0, *dayCount-1)
  193. endTime = date.FormatDate(&end_time, date.Date_Full_Layout)
  194. }
  195. powerReq := &pb.PowerReq{
  196. Appid: appid,
  197. GoodsCode: goodsCode,
  198. GoodsSpecId: goodsSpecId,
  199. BuyNum: 1,
  200. Type: 1,
  201. EndTime: endTime,
  202. }
  203. if *powerWay == 2 {
  204. powerReq.EntAccountId = identity.EntAccountId
  205. powerReq.EntId = identity.EntId
  206. } else {
  207. powerReq.AccountId = identity.AccountId
  208. }
  209. r, err := c.PowerHandle(context.Background(), powerReq)
  210. if err != nil {
  211. log.Println(msg, powerType, "开通失败!", err)
  212. } else if r.Status == 1 {
  213. if *isCheck == 1 {
  214. entity.afterOpen(phone, identity)
  215. }
  216. log.Println(msg, powerType, "已开通!")
  217. } else {
  218. log.Println(msg, powerType, "开通失败!")
  219. }
  220. } else if *m == 3 {
  221. powerReq := &pb.PowerReq{
  222. Appid: appid,
  223. GoodsCode: goodsCode,
  224. GoodsSpecId: goodsSpecId,
  225. BuyNum: 1,
  226. Type: -1,
  227. }
  228. if *powerWay == 2 {
  229. powerReq.EntAccountId = identity.EntAccountId
  230. powerReq.EntId = identity.EntId
  231. } else {
  232. powerReq.AccountId = identity.AccountId
  233. powerReq.EntAccountId = identity.EntAccountId
  234. powerReq.EntId = identity.EntId
  235. }
  236. r, err := c.PowerHandle(context.Background(), powerReq)
  237. if err != nil {
  238. log.Println(msg, powerType, "取消失败!", err)
  239. } else if r.Status == 1 {
  240. log.Println(msg, powerType, "已取消!")
  241. } else {
  242. log.Println(msg, powerType, "取消失败!", r.Status)
  243. }
  244. } else {
  245. log.Fatalln("-m 参数无效")
  246. }
  247. if *m == 2 || *m == 3 {
  248. _, err := usercenter.NewUserCenter(middleground.UserCenter.NewClient()).WorkDesktopClearUserInfo(context.Background(), &upb.WorkDesktopClearUserInfoReq{
  249. PositionId: fmt.Sprint(identity.PositionId),
  250. AppId: appid,
  251. })
  252. if err != nil {
  253. log.Println("清除用户工作桌面缓存失败", err)
  254. }
  255. }
  256. }
  257. }
  258. }
  259. type Entity interface {
  260. init() (string, string, int64, map[string]string)
  261. beforeOpen(phone *string, identity *upb.Identity) bool
  262. afterOpen(phone *string, identity *upb.Identity)
  263. }
  264. type Common struct {
  265. Name string
  266. GoodsCode string
  267. GoodsSpecId int64
  268. All map[string]string
  269. }
  270. //
  271. func (c *Common) init() (string, string, int64, map[string]string) {
  272. return c.Name, c.GoodsCode, c.GoodsSpecId, c.All
  273. }
  274. //
  275. func (c *Common) beforeOpen(phone *string, identity *upb.Identity) bool {
  276. return true
  277. }
  278. //
  279. func (c *Common) afterOpen(phone *string, identity *upb.Identity) {
  280. }
  281. /******************************医械云******************************************/
  282. type Yxy struct {
  283. }
  284. //
  285. func (y *Yxy) init() (string, string, int64, map[string]string) {
  286. return "医械云权益", "lyh", 13, map[string]string{
  287. "医疗标讯搜索": "lyh_yl_ylbxss",
  288. "医疗机构搜索": "lyh_yl_yljgss",
  289. "经销商搜索": "lyh_yl_jxsss",
  290. "医疗机构画像": "lyh_yl_yljghx",
  291. "医疗机构认领": "lyh_yl_yljgrl",
  292. "经销商认领": "lyh_yl_jxsrl",
  293. "医疗订阅": "lyh_yl_yldy",
  294. }
  295. }
  296. //
  297. func (y *Yxy) beforeOpen(phone *string, identity *upb.Identity) bool {
  298. order_user_id, u := y.getUser(identity)
  299. if u == nil {
  300. return false
  301. }
  302. ok, _, _, _ := y.isOK(*phone, *u, order_user_id)
  303. return ok
  304. }
  305. //
  306. func (y *Yxy) getUser(identity *upb.Identity) (string, *map[string]interface{}) {
  307. if identity.PositionType == 0 {
  308. u, _ := Mgo.FindOneByField("user", map[string]interface{}{"base_user_id": identity.UserId}, `{"_id":1,"l_vip_endtime":1,"i_member_endtime":1,"s_member_mainid":1,"i_member_sub_status":1}`)
  309. if u == nil || len(*u) == 0 {
  310. log.Println(fmt.Sprintf("%+v", identity), "mongodb user 中没有找到该用户!")
  311. return "", nil
  312. }
  313. return mongodb.BsonIdToSId((*u)["_id"]), u
  314. } else {
  315. u, _ := Mgo.FindOneByField("ent_user", map[string]interface{}{"i_userid": identity.EntUserId}, `{"_id":1,"l_vip_endtime":1,"i_member_endtime":1,"s_member_mainid":1,"i_member_sub_status":1}`)
  316. if u == nil || len(*u) == 0 {
  317. log.Println(fmt.Sprintf("%+v", identity), "mongodb ent_user 中没有找到该用户!")
  318. return "", nil
  319. }
  320. return fmt.Sprint(identity.PositionId), u
  321. }
  322. }
  323. //
  324. func (y *Yxy) afterOpen(phone *string, identity *upb.Identity) {
  325. order_user_id, u := y.getUser(identity)
  326. if u == nil {
  327. return
  328. }
  329. ok, orderVip, vipRs, bigRs := y.isOK(*phone, *u, order_user_id)
  330. if ok {
  331. y.createYxtOrder(*phone, *u, orderVip, vipRs, bigRs)
  332. }
  333. }
  334. func (y *Yxy) isOK(phone string, user map[string]interface{}, order_user_id string) (bool, bool, *[]map[string]interface{}, *[]map[string]interface{}) {
  335. orderVip := true // 是否根据超级订阅订单处理 如果是大会员也是超级订阅则按大会员处理
  336. flag1 := false
  337. flag2 := false
  338. mainUserId := order_user_id
  339. if IntAllDef(user["i_member_sub_status"], -1) == 1 {
  340. mainUser, ok := Mgo.FindById("user", ObjToString(user["s_member_mainid"]), `{"s_phone"1:,"s_m_phone":1}`)
  341. if ok && mainUser != nil {
  342. mainUserId = mongodb.BsonIdToSId((*mainUser)["_id"])
  343. } else {
  344. log.Println("该用户是子账号,没有找到其主账号的信息")
  345. return false, false, nil, nil
  346. }
  347. }
  348. bigMemberRs := JyOrder.SelectBySql(`select * from dataexport_order where user_id=? and order_status=1 and product_type ="大会员" and (timestampdiff(day,vip_starttime,vip_endtime)>=365) order by create_time desc limit 1`, mainUserId)
  349. if bigMemberRs != nil && len(*bigMemberRs) == 1 {
  350. (*bigMemberRs)[0]["user_phone"] = phone
  351. (*bigMemberRs)[0]["user_id"] = order_user_id
  352. }
  353. vipRs := JyOrder.SelectBySql(`select * from dataexport_order where user_id=? and order_status=1 and product_type ="VIP订阅" and (timestampdiff(day,vip_starttime,vip_endtime)>=365) order by create_time desc limit 1`, order_user_id)
  354. if (bigMemberRs == nil || len(*bigMemberRs) == 0) && (vipRs == nil || len(*vipRs) == 0) {
  355. log.Println("没有查询到该用户的年度超级订阅或者大会员订单")
  356. return false, false, nil, nil
  357. }
  358. // 同时存在超级订阅和大会员年度订单 不再判断最晚到期时间 大会员优先
  359. if vipRs != nil && len(*vipRs) == 1 {
  360. vipEndTime := Int64All(user["l_vip_endtime"])
  361. leftdayvip := time.Unix(vipEndTime, 0).Sub(time.Now()).Hours() / 24
  362. if leftdayvip >= 90 {
  363. orderVip = true
  364. flag1 = true
  365. }
  366. }
  367. if *bigMemberRs != nil && len(*bigMemberRs) == 1 {
  368. // 判断最晚到期时间
  369. bigMemberEndTime := IntAll(user["i_member_endtime"])
  370. leftdaybig := time.Unix(int64(bigMemberEndTime), 0).Sub(time.Now()).Hours() / 24
  371. if leftdaybig >= 90 {
  372. orderVip = false
  373. flag2 = true
  374. }
  375. }
  376. if !flag1 && !flag2 {
  377. log.Println("该用户剩余不符合条件")
  378. return false, false, nil, nil
  379. }
  380. return true, orderVip, vipRs, bigMemberRs
  381. }
  382. // 生成医械通订单
  383. func (y *Yxy) createYxtOrder(phone string, user map[string]interface{}, orderVip bool, vipRs, bigMemberRs *[]map[string]interface{}) {
  384. var insertOrder map[string]interface{}
  385. filterMap := map[string]interface{}{}
  386. // 超级订阅
  387. if orderVip {
  388. insertOrder = (*vipRs)[0]
  389. // 生订单信息
  390. orderMoney := Float64All(insertOrder["order_money"])
  391. endTime := Int64All(user["l_vip_endtime"])
  392. var money int
  393. filterData := (*vipRs)[0]["filter"]
  394. err := json.Unmarshal([]byte(filterData.(string)), &filterMap)
  395. if err != nil {
  396. log.Println("反序列化失败", err)
  397. return
  398. }
  399. if IntAll(insertOrder["is_backstage_order"]) == 1 {
  400. cycle := Float64All(filterMap["cyclecount"])
  401. cycleUnit := Float64All(filterMap["cycleunit"])
  402. money = y.getPriceBack(orderMoney, time.Unix(endTime, 0), cycle, cycleUnit)
  403. } else {
  404. money = y.getPrice(orderMoney, time.Unix(endTime, 0))
  405. }
  406. insertOrder["order_money"] = money
  407. insertOrder["original_price"] = money
  408. insertOrder["vip_endtime"] = time.Unix(endTime, 0).Format(date.Date_Full_Layout)
  409. } else {
  410. // 大会员
  411. endTime := Int64All(user["i_member_endtime"])
  412. filterData := (*bigMemberRs)[0]["filter"]
  413. err := json.Unmarshal([]byte(filterData.(string)), &filterMap)
  414. if err != nil {
  415. log.Println("反序列化失败", err)
  416. return
  417. }
  418. filterMap["area"] = "-"
  419. insertOrder = (*bigMemberRs)[0]
  420. insertOrder["order_money"] = 0
  421. insertOrder["original_price"] = 0
  422. insertOrder["vip_endtime"] = time.Unix(endTime, 0).Format(date.Date_Full_Layout)
  423. }
  424. filterMap["source"] = "qmx" // 后台订单
  425. // 生订单信息
  426. filter, _ := json.Marshal(filterMap)
  427. insertOrder["filter"] = string(filter)
  428. insertOrder["is_backstage_order"] = 1 // 后台创建
  429. insertOrder["product_type"] = "医械通"
  430. insertOrder["order_code"] = fmt.Sprintf("%s%s", time.Now().Format("150405"), GetRandom(6))
  431. insertOrder["prepay_id"] = ""
  432. insertOrder["pay_money"] = 0
  433. insertOrder["discount_price"] = 0
  434. insertOrder["pay_way"] = ""
  435. insertOrder["out_trade_no"] = ""
  436. insertOrder["create_time"] = date.NowFormat(date.Date_Full_Layout)
  437. insertOrder["vip_starttime"] = date.NowFormat(date.Date_Full_Layout)
  438. insertOrder["pay_time"] = insertOrder["vip_starttime"]
  439. insertOrder["prepay_time"] = insertOrder["vip_starttime"]
  440. delete(insertOrder, "id")
  441. saveRs := JyOrder.Insert("dataexport_order", insertOrder)
  442. if saveRs > 0 {
  443. log.Println("医械通订单保存成功")
  444. } else {
  445. log.Println("医械通订单保存失败", saveRs)
  446. }
  447. }
  448. // 计算价格 线上的
  449. func (y *Yxy) getPrice(orderMoney float64, endTime time.Time) int {
  450. // 计算价格
  451. dis := endTime.Sub(time.Now())
  452. days := dis.Hours() / 24 // 剩余天数
  453. money := int(orderMoney / 360 * float64(int(days)))
  454. return money
  455. }
  456. // 计算价格 管理后台创建的
  457. func (y *Yxy) getPriceBack(orderMoney float64, endTime time.Time, cycle, cycleUnit float64) int {
  458. //(1:年 2:月 3:天 4:季)
  459. // 计算价格
  460. unitPrice := 0.0
  461. switch cycleUnit {
  462. case 1:
  463. unitPrice = orderMoney / cycle / 360
  464. case 2:
  465. unitPrice = orderMoney / cycle / 30
  466. case 3:
  467. unitPrice = orderMoney / cycle
  468. case 4:
  469. unitPrice = orderMoney / cycle / 90
  470. }
  471. dis := endTime.Sub(time.Now())
  472. days := dis.Hours() / 24 // 剩余天数
  473. //log.Println("=========", int(days), "=================")
  474. money := unitPrice * float64(int(days))
  475. return int(money)
  476. }