openPower.go 17 KB

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