front.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. package front
  2. import (
  3. "github.com/dchest/captcha"
  4. "github.com/go-xweb/xweb"
  5. "github.com/gorilla/sessions"
  6. "gopkg.in/mgo.v2/bson"
  7. "log"
  8. mongoutil "qfw/mongodb"
  9. qu "qfw/util"
  10. "qfw/util/sms"
  11. "regexp"
  12. "strconv"
  13. "strings"
  14. "time"
  15. . "util"
  16. )
  17. var UserMenu map[string][]map[string]interface{} //存储菜单
  18. func init() {
  19. UserMenu = make(map[string][]map[string]interface{})
  20. }
  21. type Front struct {
  22. *xweb.Action
  23. login xweb.Mapper `xweb:"/"` //登录页面
  24. code xweb.Mapper `xweb:"/code"` //获取图片验证码
  25. sendVerifyCode xweb.Mapper `xweb:"/sendVerifyCode"` //获取手机验证码
  26. chooseEnt xweb.Mapper `xweb:"/chooseEnt"` //选择企业
  27. index xweb.Mapper `xweb:"/front/index"` //index页面
  28. logout xweb.Mapper `xweb:"/front/logout"` //注销
  29. updatePwd xweb.Mapper `xweb:"/front/updatepwd"` //更新密码
  30. //user
  31. user xweb.Mapper `xweb:"/front/user"` //查所有用户
  32. userDel xweb.Mapper `xweb:"/front/user/del"` //删除用户
  33. userSave xweb.Mapper `xweb:"/front/user/save"` //保存用户
  34. //menu
  35. menu xweb.Mapper `xweb:"/front/menu"` //查一级菜单
  36. menuSave xweb.Mapper `xweb:"/front/menu/save"` //保存一级菜单
  37. menuDel xweb.Mapper `xweb:"/front/menu/del"` //删除一级菜单
  38. menuSecond xweb.Mapper `xweb:"/front/menuSecond"` //查二级菜单
  39. menuSecondSave xweb.Mapper `xweb:"/front/menuSecond/save"` //保存二级菜单
  40. menuSecondDel xweb.Mapper `xweb:"/front/menuSecond/del"` //删除二级菜单
  41. personalMenu xweb.Mapper `xweb:"/front/personalMenu"`
  42. //role
  43. roleManager xweb.Mapper `xweb:"/front/role"` //角色权限管理
  44. roleNew xweb.Mapper `xweb:"/front/role/save"` //新增角色
  45. roleEdit xweb.Mapper `xweb:"/front/role/edit/(.*)"` //角色权限查看
  46. roleFirst xweb.Mapper `xweb:"/front/role/first"` //一级权限的查看
  47. roleSecond xweb.Mapper `xweb:"/front/role/second"` //二级权限的查看
  48. roleSave xweb.Mapper `xweb:"/front/role/edit/save"` //权限编辑保存
  49. roleDel xweb.Mapper `xweb:"/front/role/edit/del"` //权限编辑删除
  50. roleSecondEdit xweb.Mapper `xweb:"/front/role/second/edit"` //二级权限编辑
  51. }
  52. var store = sessions.NewCookieStore([]byte("jianyu_secret20210422"))
  53. func (f *Front) Login() {
  54. defer qu.Catch()
  55. if f.Method() == "POST" {
  56. // 1. 验证参数有效性
  57. phone := f.GetString("phone")
  58. phoneCode := f.GetString("phoneCode")
  59. reg := regexp.MustCompile("^1([3456789])\\d{9}$")
  60. log.Println(phone)
  61. log.Println(phoneCode)
  62. if !reg.MatchString(phone) {
  63. f.ServeJson(map[string]interface{}{
  64. "code": 0,
  65. "status": false,
  66. "message": "手机号格式有误",
  67. })
  68. return
  69. }
  70. if phoneCode == "" {
  71. f.ServeJson(map[string]interface{}{
  72. "code": 0,
  73. "status": false,
  74. "message": "短信验证码不能为空",
  75. })
  76. return
  77. }
  78. // 2. 验证短信验证码
  79. session, err := store.Get(f.Request, "dataTagLoginPhoneCode")
  80. if err != nil {
  81. f.ServeJson(map[string]interface{}{
  82. "code": 0,
  83. "status": false,
  84. "message": "验证码比对失败",
  85. })
  86. log.Println("phone-session2获取失败")
  87. return
  88. }
  89. realPhoneCode := qu.ObjToString(session.Values["code"])
  90. log.Println("realPhoneCode", realPhoneCode)
  91. log.Println("param.phoneCode", phoneCode)
  92. sessionPhone := qu.ObjToString(session.Values["phone"])
  93. if sessionPhone == "" {
  94. log.Printf("短信验证码过期-%s \n", phone)
  95. f.ServeJson(map[string]interface{}{
  96. "code": 0,
  97. "status": false,
  98. "message": "短信验证码过期",
  99. })
  100. return
  101. }
  102. if phoneCode != realPhoneCode || phone != sessionPhone {
  103. log.Println("短信验证码错误")
  104. f.ServeJson(map[string]interface{}{
  105. "code": 0,
  106. "status": false,
  107. "message": "短信验证码错误",
  108. })
  109. return
  110. }
  111. // 清理验证过的验证码
  112. session.Values["code"] = ""
  113. session.Values["phone"] = ""
  114. if err := session.Save(f.Request, f.ResponseWriter); err != nil {
  115. log.Println("session1清理出错,短信验证码")
  116. }
  117. log.Println("验证码验证通过")
  118. // 3. 验证用户导出权限 确认认用户是否有数据导出权限
  119. loginUser := JyMysql.SelectBySql("select id, name,ent_id,phone,export_power,name from entniche_user where phone=? and export_power=1", phone)
  120. if len(*loginUser) == 0 {
  121. log.Println("该用户无数据导出权限")
  122. f.ServeJson(map[string]interface{}{
  123. "code": 0,
  124. "status": false,
  125. "message": "无权限",
  126. })
  127. return
  128. }
  129. // 手机号 如果用户在多个企业并且都有剑鱼库里都有数据导出权限,则让用户选择企业
  130. if len(*loginUser) > 1 {
  131. f.SetSession("user", map[string]interface{}{
  132. "phone": phone,
  133. })
  134. f.ServeJson(map[string]interface{}{
  135. "code": 1,
  136. "status": true,
  137. "message": "",
  138. })
  139. return
  140. }
  141. // 4. 根据用户的企业id查询对应的管理员手机号 根据管理员手机号查询jyqyfw的企业表对应的appid 放到session里 以及确认用户角色
  142. log.Println((*loginUser)[0]["ent_id"], "=====================")
  143. entInfo := JyMysql.SelectBySql("select phone,name from entniche_info WHERE id = ?", (*loginUser)[0]["ent_id"])
  144. if len(*entInfo) == 0 {
  145. f.ServeJson(map[string]interface{}{
  146. "code": 0,
  147. "status": false,
  148. "message": "企业信息查询失败",
  149. })
  150. return
  151. }
  152. var role int // 角色 1 管理员 3 普通用户
  153. // 判断当前用户手机号是否是管理员手机号
  154. if phone != qu.ObjToString((*entInfo)[0]["phone"]) {
  155. role = 3
  156. } else {
  157. role = 1
  158. }
  159. // 查询mongo企业信息库 获取appid
  160. query := bson.M{
  161. "phone": qu.ObjToString((*entInfo)[0]["phone"]),
  162. "username": qu.ObjToString((*entInfo)[0]["name"]),
  163. }
  164. entMgoInfo, ok := MgoCus.FindOne("user", query)
  165. if !ok {
  166. // 企业信息查询失败
  167. f.ServeJson(map[string]interface{}{
  168. "code": 0,
  169. "status": false,
  170. "message": "appid查询失败",
  171. })
  172. return
  173. }
  174. //相关信息存入session
  175. if entMgoInfo != nil && len(*entMgoInfo) > 0 {
  176. f.SetSession("user", map[string]interface{}{
  177. "name": (*loginUser)[0]["name"],
  178. "phone": phone,
  179. "role": role,
  180. "appid": (*entMgoInfo)["appid"],
  181. "ent_id": (*loginUser)[0]["entid"],
  182. "id": (*loginUser)[0]["id"],
  183. "messageVerify": true,
  184. })
  185. //UserMenu[email] = GetUserMenu(qu.ObjToString((*user)["s_role"]))
  186. }
  187. f.ServeJson(map[string]interface{}{
  188. "code": 0,
  189. "status": true,
  190. "role": role,
  191. "message": "",
  192. })
  193. } else {
  194. f.Render("login.html")
  195. }
  196. }
  197. func (f *Front) ChooseEnt() {
  198. defer qu.Catch()
  199. //选择页面
  200. // 根据session信息查询
  201. tempSession := f.GetSession("user")
  202. if tempSession == nil || tempSession == "" {
  203. f.Redirect("/", 302)
  204. return
  205. }
  206. info := tempSession.(map[string]interface{})
  207. if info["phone"] == "" || info["phone"] == nil {
  208. f.Redirect("/", 302)
  209. return
  210. }
  211. if f.Method() == "GET" {
  212. rs := JyMysql.SelectBySql("select a.ent_id, b.name ent_name from entniche_user a, entniche_info b WHERE a.phone =? and export_power=1 and a.ent_id=b.id", info["phone"])
  213. // 企业信息 name ent_id
  214. //铺页面
  215. f.T["ent_info"] = rs
  216. f.Render("choose_ent.html", &f.T)
  217. } else {
  218. entId := f.GetString("ent_id")
  219. log.Println(entId, "entId")
  220. log.Println(info["phone"], "info[\"phone\"]")
  221. //确认该手机号有数据导出权限
  222. loginUser := JyMysql.SelectBySql("select id, name,ent_id,phone,export_power,name from entniche_user where phone=? and export_power=1 and ent_id=?", info["phone"], entId)
  223. if len(*loginUser) == 0 {
  224. f.ServeJson(map[string]interface{}{
  225. "code": 0,
  226. "status": false,
  227. "message": "无权限",
  228. })
  229. return
  230. }
  231. var role int // 角色 1 管理员 3 普通用户
  232. // 判断当前用户手机号是否是管理员手机号
  233. entInfo := JyMysql.SelectBySql("select phone,name from entniche_info WHERE id = ?", (*loginUser)[0]["ent_id"])
  234. if len(*entInfo) == 0 {
  235. f.ServeJson(map[string]interface{}{
  236. "code": 0,
  237. "status": false,
  238. "message": "企业信息查询失败",
  239. })
  240. return
  241. }
  242. query := bson.M{
  243. "phone": (*entInfo)[0]["phone"],
  244. "username": (*entInfo)[0]["name"],
  245. }
  246. entMgoInfo, ok := MgoCus.FindOne("user", query)
  247. if !ok {
  248. // 企业信息查询失败
  249. f.ServeJson(map[string]interface{}{
  250. "code": 0,
  251. "status": false,
  252. "message": "appid查询失败",
  253. })
  254. return
  255. }
  256. // 确认该企业有使用该系统的权限 查询配置文件appid 确认是否有使用该系统的权限
  257. query2 := bson.M{
  258. "app_id": (*entMgoInfo)["appid"],
  259. }
  260. isExist, _ := Mgo.FindOne("datatag_export_config", query2)
  261. log.Println(isExist)
  262. if len((*isExist)) == 0 {
  263. f.ServeJson(map[string]interface{}{
  264. "code": 0,
  265. "status": false,
  266. "message": "该企业无权限",
  267. })
  268. return
  269. }
  270. if info["phone"] != qu.ObjToString((*entInfo)[0]["phone"]) {
  271. role = 3
  272. } else {
  273. role = 1
  274. }
  275. // 确认用户角色 存session
  276. f.SetSession("user", map[string]interface{}{
  277. "name": (*loginUser)[0]["name"],
  278. "phone": info["phone"],
  279. "role": role,
  280. "appid": (*entMgoInfo)["appid"],
  281. "ent_id": (*loginUser)[0]["entid"],
  282. "id": (*loginUser)[0]["id"],
  283. })
  284. // 返回
  285. f.ServeJson(map[string]interface{}{
  286. "code": 0,
  287. "status": true,
  288. "role": role,
  289. "message": "",
  290. })
  291. }
  292. }
  293. func (f *Front) Index() {
  294. defer qu.Catch()
  295. f.Render("index.html")
  296. }
  297. func (f *Front) Logout() {
  298. f.DelSession("user")
  299. f.Redirect("/")
  300. }
  301. func (f *Front) UpdatePwd() {
  302. defer qu.Catch()
  303. id := f.GetString("id")
  304. password := f.GetString("pwd")
  305. set := bson.M{
  306. "$set": bson.M{
  307. "s_pwd": qu.SE.EncodeString(password),
  308. },
  309. }
  310. if Mgo.UpdateById("user", id, set) {
  311. sessionuser := f.GetSession("user").(map[string]interface{})
  312. sessionuser["pwd"] = password
  313. f.SetSession("user", sessionuser)
  314. }
  315. }
  316. func (f *Front) User() {
  317. defer qu.Catch()
  318. role, _ := Mgo.Find("role", nil, nil, nil, false, -1, -1)
  319. roleMap := make(map[string]string)
  320. for _, v := range *role {
  321. level := qu.ObjToString(v["level"])
  322. if level != "" {
  323. roleMap[level] = qu.ObjToString(v["name"])
  324. }
  325. }
  326. if f.Method() == "POST" {
  327. query := bson.M{
  328. "s_role": bson.M{
  329. "$ne": "0",
  330. },
  331. }
  332. data, _ := Mgo.Find("user", query, `{"_id":1}`, nil, false, -1, -1)
  333. for _, d := range *data {
  334. d["s_pwd"] = qu.SE.DecodeString(qu.ObjToString(d["s_pwd"]))
  335. d["role_name"] = roleMap[qu.ObjToString(d["s_role"])]
  336. }
  337. f.ServeJson(map[string]interface{}{
  338. "data": data,
  339. })
  340. } else {
  341. f.T["role"] = roleMap
  342. f.Render("com/user.html", &f.T)
  343. }
  344. }
  345. func (f *Front) UserDel() {
  346. defer qu.Catch()
  347. _id := f.GetString("_id")
  348. query := bson.M{
  349. "_id": mongoutil.StringTOBsonId(_id),
  350. }
  351. b := Mgo.Del("user", query)
  352. f.ServeJson(map[string]interface{}{
  353. "rep": b,
  354. })
  355. }
  356. func (f *Front) UserSave() {
  357. _id := f.GetString("_id")
  358. role := f.GetString("role")
  359. name := f.GetString("name")
  360. email := f.GetString("email")
  361. pwd := f.GetString("pwd")
  362. set := bson.M{
  363. "$set": bson.M{
  364. "s_role": role,
  365. "s_name": name,
  366. "s_email": email,
  367. "s_pwd": qu.SE.EncodeString(pwd),
  368. "i_comeintime": time.Now().Unix(),
  369. },
  370. }
  371. query := bson.M{
  372. "_id": mongoutil.StringTOBsonId(_id),
  373. }
  374. if _id == "" {
  375. query = bson.M{
  376. "_id": bson.NewObjectId(),
  377. }
  378. }
  379. b := Mgo.Update("user", query, set, true, false)
  380. //b := Mgo.UpdateById("user", _id, set)
  381. f.ServeJson(map[string]interface{}{
  382. "rep": b,
  383. })
  384. }
  385. func (f *Front) PersonalMenu() {
  386. user := f.GetSession("user").(map[string]interface{})
  387. list := UserMenu[qu.ObjToString(user["email"])]
  388. f.ServeJson(map[string]interface{}{
  389. "data": list,
  390. })
  391. }
  392. func GetUserMenu(role string) []map[string]interface{} {
  393. var list []map[string]interface{}
  394. maps := map[string]interface{}{
  395. "delete": false,
  396. }
  397. if role != "0" {
  398. maps["role."+role] = true
  399. }
  400. data, _ := Mgo.Find("menu_first", maps, nil, nil, false, -1, -1)
  401. for _, d := range *data {
  402. _id := d["_id"]
  403. maps = map[string]interface{}{
  404. "delete": false,
  405. "s_pid": mongoutil.BsonIdToSId(_id),
  406. }
  407. if role != "0" {
  408. maps["role."+role] = true
  409. }
  410. secdatas, _ := Mgo.Find("menu_second", maps, nil, nil, false, -1, -1)
  411. secmenumap := map[string]interface{}{}
  412. for index, secdata := range *secdatas {
  413. secmenumap[strconv.Itoa(index+1)] = secdata
  414. }
  415. if len(secmenumap) != 0 {
  416. d["secondmenu"] = secmenumap
  417. }
  418. list = append(list, d)
  419. }
  420. return list
  421. }
  422. // 获取图片验证码
  423. func (f *Front) Code() {
  424. id := captcha.NewLen(4)
  425. //r := &http.Request{}
  426. f.Request.Header.Add("Cache-Control", "no-cache, no-store, must-revalidate")
  427. f.Request.Header.Add("Pragma", "no-cache")
  428. f.Request.Header.Add("Expires", "0")
  429. f.Request.Header.Add("Content-Type", "image/png")
  430. w := f.ResponseWriter
  431. session, err := store.Get(f.Request, "dataTagLoginImgCode")
  432. if err != nil {
  433. log.Println("session1获取失败")
  434. return
  435. }
  436. session.Values["dataTagLoginImgCode"] = id
  437. session.Options.MaxAge = 60
  438. if err := session.Save(f.Request, w); err != nil {
  439. log.Println("session1保存错误,验证码 ", id)
  440. }
  441. err2 := captcha.WriteImage(w, id, 90, 30)
  442. if err2 != nil {
  443. log.Println("生成图片验证码错误,验证码 ", id)
  444. }
  445. return
  446. }
  447. // 发送手机验证码接口
  448. func (f *Front) SendVerifyCode() {
  449. if f.Method() == "POST" {
  450. //1. 验证参数有效性
  451. phone := f.GetString("phone")
  452. imgCode := f.GetString("imgCode")
  453. reg := regexp.MustCompile("^1(3|4|5|6|7|8|9)\\d{9}$")
  454. if !reg.MatchString(phone) {
  455. f.ServeJson(map[string]interface{}{
  456. "code": 0,
  457. "status": false,
  458. "message": "手机号格式有误",
  459. })
  460. return
  461. }
  462. //2. 验证图片验证码
  463. session, err := store.Get(f.Request, "dataTagLoginImgCode")
  464. if err != nil {
  465. log.Printf("图片验证码session获取失败-%s \n", phone)
  466. f.ServeJson(map[string]interface{}{
  467. "code": 0,
  468. "status": false,
  469. "message": "获取失败",
  470. })
  471. return
  472. }
  473. code := qu.ObjToString(session.Values["dataTagLoginImgCode"])
  474. if code == "" {
  475. log.Printf("图片验证码过期-%s \n", phone)
  476. f.ServeJson(map[string]interface{}{
  477. "code": 0,
  478. "status": false,
  479. "message": "图片验证码过期",
  480. })
  481. return
  482. }
  483. if !captcha.VerifyString(code, imgCode) {
  484. log.Printf("图片验证码错误-%s \n", phone)
  485. f.ServeJson(map[string]interface{}{
  486. "code": 0,
  487. "status": false,
  488. "message": "图片验证码错误",
  489. })
  490. return
  491. }
  492. //3. 验证手机号是否存在
  493. user := JyMysql.SelectBySql("select * from entniche_user where phone=? and export_power=1", phone)
  494. // 确认用户是否存在
  495. if len(*user) == 0 || ((*user)[0])["phone"] != phone {
  496. log.Println("没有数据导出权限")
  497. f.ServeJson(map[string]interface{}{
  498. "code": 0,
  499. "status": false,
  500. "message": "无权限",
  501. })
  502. return
  503. }
  504. //4. 发送验证码
  505. SendPhoneCode(f, phone)
  506. f.ServeJson(map[string]interface{}{
  507. "code": 0,
  508. "status": true,
  509. "message": "发送成功",
  510. })
  511. return
  512. } else {
  513. f.ServeJson(map[string]interface{}{
  514. "code": 0,
  515. "status": false,
  516. "message": "无效的请求方式",
  517. })
  518. }
  519. }
  520. // 发送手机验证码方法
  521. func SendPhoneCode(f *Front, phone string) {
  522. r := f.Request
  523. w := f.ResponseWriter
  524. session, err := store.Get(r, "dataTagLoginPhoneCode")
  525. if err != nil {
  526. log.Println("phone-session1获取失败")
  527. return
  528. }
  529. lastSentTime := qu.Int64All(session.Values["identCodeTime"])
  530. //60秒之内不允许重复发
  531. if lastSentTime > 0 && time.Now().Unix()-lastSentTime <= 60 {
  532. }
  533. s_ranNum := qu.GetRandom(6) //生成随机数
  534. session.Values["code"] = s_ranNum
  535. session.Values["phone"] = phone
  536. session.Values["identCodeTime"] = time.Now().Unix()
  537. session.Options.MaxAge = 300
  538. if err := session.Save(r, w); err != nil {
  539. log.Println("session1保存错误,验证码")
  540. }
  541. //发送短信
  542. param := map[string]string{"code": s_ranNum}
  543. log.Println("短信验证码", phone, s_ranNum)
  544. SendSMS("2828060", phone, param)
  545. }
  546. //第三个参数是可变参数,可以传入多个,但要和模板相匹配
  547. func SendSMS(tplcode /*模板代码*/, mobile /*手机号码*/ string, param map[string]string) {
  548. tmp := []string{}
  549. for k, v := range param {
  550. tmp = append(tmp, "#"+k+"#="+v)
  551. }
  552. text := strings.Join(tmp, "&")
  553. sms.SendSms(mobile, tplcode, text)
  554. }