front.go 14 KB

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