123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- package login
- import (
- "context"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "log"
- "strings"
- "time"
- "git.listensoft.net/tool/jspkit/common"
- "git.listensoft.net/tool/jspkit/common/models"
- "git.listensoft.net/tool/jspkit/logger"
- "git.listensoft.net/tool/jspkit/taxerr"
- "github.com/forgoer/openssl"
- "github.com/go-rod/rod"
- "github.com/go-rod/rod/lib/proto"
- "github.com/go-rod/rod/lib/utils"
- "github.com/tidwall/gjson"
- )
- func CheckSessionAndLogin(ctx context.Context, p *rod.Page, BaseUri string, info models.CompanyInfo) (err error) {
- //return taxerr.NewUser("税局代理机构登录存在风险,预计6号恢复,请等待税局修复后使用")//12.6 09:20左右 确认完了
- if info.Dlfs == "代理登录" && info.IdNo == "" {
- return taxerr.DlTaxNoError
- }
- return AutoCheckSessionAndLogin(ctx, p, BaseUri, info)
- }
- func LoadCookie(sessionInfos models.SsoSession, p *rod.Page, BaseUri string, info models.CompanyInfo) (name string, err error) {
- err = rod.Try(func() {
- defer AddErr()
- p.Navigate("")
- _ = p.Timeout(common.ClickTimeOut).MustNavigate(areaURLmap[info.Area+".pro"]).StopLoading() // 此时必须得去tpass域名 要不然写入cookie后进不去发票
- p.MustSetCookies(sessionInfos.Cookies...)
- {
- p.MustEval(`() => localStorage.clear()`)
- utils.Sleep(1)
- // 设置 localStorage 在第二个页面中,逐条设置
- logger.Info("Setting localStorage in second browser...")
- for key, value := range sessionInfos.LocalStorage {
- if key == "logConfig" {
- continue
- }
- script := fmt.Sprintf(`() => localStorage.setItem('%s', '%s')`, key, value)
- _, err := p.Eval(script)
- if err != nil {
- log.Printf("Error setting localStorage %s=%s: %v", key, value, err)
- }
- }
- }
- utils.Sleep(1)
- if info.Area == "shaanxi" {
- //陕西地区必须带后面/才能登录上去
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb/")
- } else {
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb")
- }
- utils.Sleep(4)
- _ = rod.Try(func() {
- p.Timeout(common.LoadTimeout * 2).MustWaitStable()
- p.Timeout(common.LoadTimeout * 2).MustWaitDOMStable()
- })
- //p.MustStopLoading()
- logger.Info("加载完成")
- if info.Area == "hebei" && !common.MustHasXV(p, `//div[@class='leftMain']//div[contains(@class,'title')]`) {
- logger.Info("河北重新访问loginb")
- p.Timeout(common.ClickTimeOut).MustNavigate(`https://tpass.hebei.chinatax.gov.cn:8443/#/login?redirect_uri=https%3A%2F%2Fetax.hebei.chinatax.gov.cn%3A8443%2Fmhzx%2Fapi%2Fmh%2Ftpass%2Fcode&client_id=ap5bfdavp66a49979apa5848fpaa5353&response_type=code&state=8f8f3db7ecb948f08b1da177cda40854&client_pid=ap5bfdavp66a49979apa5848fpaa5353`)
- utils.Sleep(4)
- p.MustWaitStable()
- p.MustWaitDOMStable()
- }
- if common.MustHasXV(p, "//div[text()=' 关于电子税务局“新办智能开业”的通知 ']") {
- p.Timeout(common.ClickTimeOut).MustSearch("//span[text()='我知道了']").MustClick()
- utils.Sleep(1)
- common.MustElementXV(p, "//span[text()='确认']").MustClick()
- utils.Sleep(40) //要转很久
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb")
- }
- if p.MustHasX(`//div[@class='leftMain']//div[contains(@class,'title')]`) {
- _ = p.Timeout(common.ClickTimeOut).MustElementX(`//div[@class='leftMain']//div[contains(@class,'title')]`).WaitStable(300 * time.Millisecond)
- if *p.Timeout(common.ClickTimeOut).MustElementX(`//div[@class='leftMain']//div[contains(@class,'title')]`).MustAttribute(`title`) == "" {
- logger.Info("公司名空刷新")
- p.Reload()
- utils.Sleep(4)
- p.MustWaitDOMStable()
- }
- }
- if common.MustHasXV(p, `//div[@class='leftMain']//div[contains(@class,'title')]`) {
- name = *common.WaitElementX(p, `//div[@class='leftMain']//div[contains(@class,'title')]`, 0.5).MustAttribute(`title`)
- if name == "" {
- err = taxerr.New("代理登录切换公司后异常公司名")
- return
- }
- return
- }
- DlSy := false //登录完是代理登录的首页
- if common.MustHasXV(p, `//a[@title="单户办理"]`) {
- common.MustElementX(p, `//a[@title="单户办理"]`).MustClick()
- DlSy = true
- utils.Sleep(3)
- }
- if !strings.Contains(p.MustInfo().URL, "tpass") {
- panic(taxerr.New("cookie失效"))
- }
- if !p.MustHasR(`[class="s_Breadcrumb"]`, "企业办税") {
- panic(taxerr.New("cookie失效"))
- }
- if !DlSy {
- r := p.MustWaitRequestIdle()
- p.Timeout(common.ClickTimeOut).MustSearch("返回").MustClick()
- r()
- } else {
- //这里需要手动切换到首页
- common.MustInputX(p, `//input[@placeholder="请输入统一社会信用代码"]`, info.TaxNo)
- common.MustElementX(p, `//span[text()="查询"]`).MustClick()
- utils.Sleep(2)
- tbody := common.MustElementsX(p, `//div[@class="el-table__body-wrapper is-scrolling-none"]//table//tr`)
- if len(tbody) == 0 {
- common.MustInputX(p, `//input[@placeholder="请输入统一社会信用代码"]`, "")
- p.Timeout(common.ClickTimeOut).MustElementX(`//input[@placeholder="请输入纳税人名称"]`).MustInput(info.ComName)
- common.MustElementX(p, `//span[text()="查询"]`).MustClick()
- utils.Sleep(2)
- tbody = common.MustElementsX(p, `//div[@class="el-table__body-wrapper is-scrolling-none"]//table//tr`)
- if len(tbody) == 0 {
- panic(taxerr.NewUserV3("未在当前账号下["+info.Zzridno+"]找到该企业", "请检查手机号与企业的关联关系"))
- }
- panic(taxerr.NewUserV3("该公司账号跟公司名称不匹配", "请检查后重新发起"))
- } else if len(tbody) == 1 {
- common.MustElementX(p, `//span[text()='进入']`).MustClick()
- if common.MustHasXV(p, `//span[text()="身份切换"]/../../..//span[contains(text(),"确定")]`) {
- common.MustElementX(p, `//span[text()="身份切换"]/../../..//span[contains(text(),"确定")]`).MustClick()
- time.Sleep(5 * time.Second)
- }
- } else {
- panic(taxerr.NewSystemV3("未在当前税号下["+info.TaxNo+"]找到多家企业", "请联系运维处理"))
- }
- }
- utils.Sleep(2)
- p.MustWaitDOMStable()
- name = *common.WaitElementX(p, `//div[@class='leftMain']//div[contains(@class,'title')]`, 0.5).MustAttribute(`title`)
- })
- // 这是panic的失效
- if err != nil {
- rod.Try(func() {
- patjh := common.GeneratePath("png")
- p.MustScreenshot(patjh)
- logger.Info("代理登录切换公司后异常公司名或判定为失效截图:" + patjh)
- })
- logger.Info(err.Error())
- return "", err
- }
- if (err != nil) && name == "" {
- logger.Info("cookie失效,当前url:" + p.MustInfo().URL)
- return "", taxerr.NewSystemV3("税局加载异常", "系统将于30分钟后重试")
- }
- return
- }
- func LoadCookieFast(sessionInfos models.SsoSession, p *rod.Page, BaseUri string, info models.CompanyInfo) (name string, err error) {
- err = rod.Try(func() {
- defer AddErr()
- p.Navigate("")
- p.Timeout(common.ClickTimeOut).MustNavigate(areaURLmap[info.Area+".pro"]).MustStopLoading() // 此时必须得去tpass域名 要不然写入cookie后进不去发票
- p.MustSetCookies(sessionInfos.Cookies...)
- {
- p.MustEval(`() => localStorage.clear()`)
- //utils.Sleep(1)
- // 设置 localStorage 在第二个页面中,逐条设置
- logger.Info("Setting localStorage in second browser...")
- for key, value := range sessionInfos.LocalStorage {
- if key == "logConfig" {
- continue
- }
- script := fmt.Sprintf(`() => localStorage.setItem('%s', '%s')`, key, value)
- _, err := p.Eval(script)
- if err != nil {
- log.Printf("Error setting localStorage %s=%s: %v", key, value, err)
- }
- }
- }
- utils.Sleep(0.5)
- if info.Area == "shaanxi" {
- //陕西地区必须带后面/才能登录上去
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb/")
- } else {
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb")
- }
- utils.Sleep(1)
- _ = rod.Try(func() {
- p.Timeout(2 * time.Second).MustWaitStable()
- p.Timeout(2 * time.Second).MustWaitDOMStable()
- })
- //p.MustStopLoading()
- logger.Info("加载完成")
- if info.Area == "hebei" && !common.MustHasXV(p, `//div[@class='leftMain']//div[contains(@class,'title')]`) {
- logger.Info("河北重新访问loginb")
- p.Timeout(common.ClickTimeOut).MustNavigate(`https://tpass.hebei.chinatax.gov.cn:8443/#/login?redirect_uri=https%3A%2F%2Fetax.hebei.chinatax.gov.cn%3A8443%2Fmhzx%2Fapi%2Fmh%2Ftpass%2Fcode&client_id=ap5bfdavp66a49979apa5848fpaa5353&response_type=code&state=8f8f3db7ecb948f08b1da177cda40854&client_pid=ap5bfdavp66a49979apa5848fpaa5353`)
- utils.Sleep(4)
- p.MustWaitStable()
- p.MustWaitDOMStable()
- }
- if common.MustHasXV(p, "//div[text()=' 关于电子税务局“新办智能开业”的通知 ']") {
- p.Timeout(common.ClickTimeOut).MustSearch("//span[text()='我知道了']").MustClick()
- utils.Sleep(1)
- common.MustElementXV(p, "//span[text()='确认']").MustClick()
- utils.Sleep(40) //要转很久
- p.Timeout(common.ClickTimeOut).MustNavigate(BaseUri + "/loginb")
- }
- if p.MustHasX(`//div[@class='leftMain']//div[contains(@class,'title')]`) {
- _ = p.Timeout(common.ClickTimeOut).MustElementX(`//div[@class='leftMain']//div[contains(@class,'title')]`).WaitStable(300 * time.Millisecond)
- if *p.Timeout(common.ClickTimeOut).MustElementX(`//div[@class='leftMain']//div[contains(@class,'title')]`).MustAttribute(`title`) == "" {
- logger.Info("公司名空刷新")
- p.Reload()
- utils.Sleep(4)
- p.MustWaitDOMStable()
- }
- }
- if common.MustHasXV(p, `//div[@class='leftMain']//div[contains(@class,'title')]`) {
- name = *common.WaitElementX(p, `//div[@class='leftMain']//div[contains(@class,'title')]`, 0.5).MustAttribute(`title`)
- if name == "" {
- err = taxerr.New("代理登录切换公司后异常公司名")
- return
- }
- return
- }
- DlSy := false //登录完是代理登录的首页
- if common.MustHasXV(p, `//a[@title="单户办理"]`) {
- common.MustElementX(p, `//a[@title="单户办理"]`).MustClick()
- DlSy = true
- utils.Sleep(3)
- }
- if !strings.Contains(p.MustInfo().URL, "tpass") {
- panic(taxerr.New("cookie失效"))
- }
- if !p.MustHasR(`[class="s_Breadcrumb"]`, "企业办税") {
- panic(taxerr.New("cookie失效"))
- }
- if !DlSy {
- r := p.MustWaitRequestIdle()
- p.Timeout(common.ClickTimeOut).MustSearch("返回").MustClick()
- r()
- } else {
- //这里需要手动切换到首页
- common.MustInputX(p, `//input[@placeholder="请输入统一社会信用代码"]`, info.TaxNo)
- common.MustElementX(p, `//span[text()="查询"]`).MustClick()
- utils.Sleep(2)
- tbody := common.MustElementsX(p, `//div[@class="el-table__body-wrapper is-scrolling-none"]//table//tr`)
- if len(tbody) == 0 {
- common.MustInputX(p, `//input[@placeholder="请输入统一社会信用代码"]`, "")
- p.Timeout(common.ClickTimeOut).MustElementX(`//input[@placeholder="请输入纳税人名称"]`).MustInput(info.ComName)
- common.MustElementX(p, `//span[text()="查询"]`).MustClick()
- utils.Sleep(2)
- tbody = common.MustElementsX(p, `//div[@class="el-table__body-wrapper is-scrolling-none"]//table//tr`)
- if len(tbody) == 0 {
- panic(taxerr.NewUserV3("未在当前账号下["+info.Zzridno+"]找到该企业", "请检查手机号与企业的关联关系"))
- }
- panic(taxerr.NewUserV3("该公司账号跟公司名称不匹配", "请检查后重新发起"))
- } else if len(tbody) == 1 {
- common.MustElementX(p, `//span[text()='进入']`).MustClick()
- if common.MustHasXV(p, `//span[text()="身份切换"]/../../..//span[contains(text(),"确定")]`) {
- common.MustElementX(p, `//span[text()="身份切换"]/../../..//span[contains(text(),"确定")]`).MustClick()
- time.Sleep(5 * time.Second)
- }
- } else {
- panic(taxerr.NewSystemV3("未在当前税号下["+info.TaxNo+"]找到多家企业", "请联系运维处理"))
- }
- }
- utils.Sleep(0.5)
- p.MustWaitDOMStable()
- name = *common.WaitElementX(p, `//div[@class='leftMain']//div[contains(@class,'title')]`, 0.5).MustAttribute(`title`)
- logger.Info(name)
- })
- // 这是panic的失效
- if err != nil {
- rod.Try(func() {
- patjh := common.GeneratePath("png")
- p.MustScreenshot(patjh)
- logger.Info("代理登录切换公司后异常公司名或判定为失效截图:" + patjh)
- })
- logger.Info(err.Error())
- return "", err
- }
- if (err != nil) && name == "" {
- logger.Info("cookie失效,当前url:" + p.MustInfo().URL)
- return "", taxerr.NewSystemV3("税局加载异常", "系统将于30分钟后重试")
- }
- if name == "" {
- logger.Info("公司名加载异常,当前url:" + p.MustInfo().URL)
- path := common.GeneratePath("png")
- p.MustScreenshot(path)
- logger.Info(path)
- }
- return
- }
- func AddErr() {
- if err := recover(); err != nil {
- e := err.(error)
- if _, ok := err.(*taxerr.UserErr); ok {
- err = taxerr.NewUser(e.Error() + "(代理登录失败)")
- }
- if _, ok := err.(*taxerr.SystemErr); ok {
- err = taxerr.New(e.Error() + "(代理登录失败)")
- }
- panic(err)
- }
- }
- func AutoCheckSessionAndLogin(ctx context.Context, p *rod.Page, BaseUri string, info models.CompanyInfo) (err error) {
- if info.Area == "hubei" && info.Dlfs == "代理登录" && len(info.Tel) != 11 {
- return taxerr.NewUserV3("湖北代理登录需要接受验证码", "请在登录信息中修改为手机号")
- }
- if info.Zzrmm == "" {
- return taxerr.PasswdEmpty
- }
- var LoginResponse []byte
- var Session models.SsoSession
- // 直接登录获取cookie
- {
- logger.Info("开始代理登陆获取cookie")
- LoginData := MakeLoginData(ctx, info)
- a, _ := json.Marshal(LoginData)
- logger.Info("代理登录加密前参数" + string(a))
- R := AesECBEncrypt(LoginData)
- headder := map[string]string{
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
- "content-type": "application/json",
- "x-token": XToken,
- }
- marshal, _ := json.Marshal(LoginData)
- logger.Info(fmt.Sprintf("PostLoin参数%s" + string(marshal)))
- LoginResponse, err = PostLoin(R, headder, info)
- logger.Info("代理登陆获取cookie成功")
- if err != nil {
- if info.Dlfs == "代理登录" {
- e := err.(error)
- if _, ok := err.(*taxerr.UserErr); ok {
- err = taxerr.NewUser(e.Error() + "(代理登录失败)")
- }
- if _, ok := err.(*taxerr.SystemErr); ok {
- err = taxerr.New(e.Error() + "(代理登录失败)")
- }
- }
- return err
- }
- }
- // 整理cookie
- {
- gdata := gjson.GetBytes(LoginResponse, "data")
- cookies := []*proto.NetworkCookieParam{}
- domain := ""
- gdata.Get("cookies").ForEach(func(key, value gjson.Result) bool {
- if key.String() == "lzkqow38189" {
- domain = "dppt." + info.Area + ".chinatax.gov.cn"
- } else if key.String() == "token" {
- domain = "tpass." + info.Area + ".chinatax.gov.cn"
- } else {
- domain = ".chinatax.gov.cn"
- }
- cookies = append(cookies, &proto.NetworkCookieParam{
- Name: key.String(),
- Value: value.String(),
- Domain: domain,
- Path: "/",
- })
- return true
- })
- localStorage := map[string]string{}
- gdata.Get("localStorage").ForEach(func(key, value gjson.Result) bool {
- localStorage[key.String()] = value.String()
- return true
- })
- Session.Cookies = cookies
- Session.LocalStorage = localStorage
- //dpptURL = gdata.Get("redirectUri").String()
- }
- //if ctxValue := ctx.Value("website"); ctxValue != nil { //只有发票任务会传website
- // // 写入浏览器
- // name, err := LoadCookieFast(Session, p, BaseUri, info)
- // if err != nil {
- // fmt.Println(err.Error())
- // return err
- // }
- // if name != info.ComName {
- // return taxerr.CompanyNameError(name)
- // }
- //} else {
- // 写入浏览器
- name, err := LoadCookie(Session, p, BaseUri, info)
- if err != nil {
- return err
- }
- if name != info.ComName {
- return taxerr.CompanyNameError(name)
- }
- //}
- return
- }
- func AesECBEncrypt(data map[string]any) []byte {
- jsonData, _ := json.Marshal(data)
- fmt.Println(string(jsonData))
- padded := make([]byte, 16)
- copy(padded, key)
- encryptData, err := openssl.AesECBEncrypt(jsonData, []byte(padded), openssl.PKCS5_PADDING)
- if err != nil {
- return []byte("")
- }
- jsonData, _ = json.Marshal(map[string]string{"data": base64.StdEncoding.EncodeToString(encryptData)})
- return jsonData
- }
|