front.go 15 KB

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