140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package redirect
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"fonchain-fiee/pkg/service"
 | |
| 	"github.com/PuerkitoBio/goquery"
 | |
| 	"github.com/gin-gonic/gin"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| // ToRedirectRealUrl 重定向到指定位置
 | |
| func ToRedirectRealUrl(c *gin.Context) {
 | |
| 
 | |
| 	realUrl := c.Query("base_redirect_url")
 | |
| 	if realUrl == "" {
 | |
| 		service.Error(c, errors.New("not real url"))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	c.Redirect(http.StatusMovedPermanently, realUrl)
 | |
| }
 | |
| 
 | |
| // ToRedirectRealUrlAdnRand 重定向到指定位置
 | |
| func ToRedirectRealUrlAdnRand(c *gin.Context) {
 | |
| 
 | |
| 	realUrl := c.Query("base_redirect_url")
 | |
| 	if realUrl == "" {
 | |
| 		service.Error(c, errors.New("not real url"))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	c.Redirect(http.StatusMovedPermanently, realUrl+fmt.Sprintf("?time=%d", time.Now().Unix()))
 | |
| }
 | |
| func ForwardTest(c *gin.Context) {
 | |
| 	url := "https://stockanalysis.com/quote/otc/MINM/"
 | |
| 
 | |
| 	// Create HTTP client with timeout
 | |
| 	client := &http.Client{
 | |
| 		Timeout: 10 * time.Second,
 | |
| 	}
 | |
| 
 | |
| 	// Make request
 | |
| 	resp, err := client.Get(url)
 | |
| 	if err != nil {
 | |
| 		sendErrorResponse(c, http.StatusInternalServerError, "请求失败", err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 	defer resp.Body.Close()
 | |
| 
 | |
| 	if resp.StatusCode != http.StatusOK {
 | |
| 		sendErrorResponse(c, http.StatusInternalServerError, "请求失败", fmt.Sprintf("status code: %d", resp.StatusCode))
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// Parse HTML
 | |
| 	doc, err := goquery.NewDocumentFromReader(resp.Body)
 | |
| 	if err != nil {
 | |
| 		sendErrorResponse(c, http.StatusInternalServerError, "解析失败", err.Error())
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	var (
 | |
| 		openValue      string
 | |
| 		volumeValue    string
 | |
| 		daysRangeValue string
 | |
| 		week52Value    string
 | |
| 		marketCapValue string
 | |
| 		changeValue    []string
 | |
| 	)
 | |
| 	type StockData struct {
 | |
| 		Open        string   `json:"Open"`
 | |
| 		Volume      string   `json:"Volume"`
 | |
| 		DaysRange   string   `json:"DaysRange"`
 | |
| 		Week52Range string   `json:"Week52Range"`
 | |
| 		MarketCap   string   `json:"MarketCap"`
 | |
| 		Change      []string `json:"change"`
 | |
| 	}
 | |
| 	// Get price
 | |
| 	priceDiv := doc.Find("div.text-4xl.font-bold.transition-colors.duration-300.inline-block").First()
 | |
| 	price := strings.TrimSpace(priceDiv.Text())
 | |
| 
 | |
| 	// Get change
 | |
| 	changeDiv := priceDiv.NextFiltered("div.font-semibold.inline-block.text-2xl")
 | |
| 	//"font-semibold inline-block text-2xl text-green-vivid"
 | |
| 	change := strings.TrimSpace(changeDiv.Text())
 | |
| 
 | |
| 	if price != "" && change != "" {
 | |
| 		changeValue = []string{price, change}
 | |
| 	}
 | |
| 
 | |
| 	// Find other values in table
 | |
| 	doc.Find("td").Each(func(i int, s *goquery.Selection) {
 | |
| 		text := strings.TrimSpace(s.Text())
 | |
| 		switch text {
 | |
| 		case "Open":
 | |
| 			openValue = strings.TrimSpace(s.Next().Text())
 | |
| 		case "Volume":
 | |
| 			volumeValue = strings.TrimSpace(s.Next().Text())
 | |
| 		case "Day's Range":
 | |
| 			daysRangeValue = strings.TrimSpace(s.Next().Text())
 | |
| 		case "52-Week Range":
 | |
| 			week52Value = strings.TrimSpace(s.Next().Text())
 | |
| 		case "Market Cap":
 | |
| 			marketCapValue = strings.TrimSpace(s.Next().Text())
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	// Check if all values were found
 | |
| 	if openValue != "" && volumeValue != "" && daysRangeValue != "" &&
 | |
| 		week52Value != "" && marketCapValue != "" && len(changeValue) == 2 {
 | |
| 		c.JSON(http.StatusOK, StockData{
 | |
| 			Open:        openValue,
 | |
| 			Volume:      volumeValue,
 | |
| 			DaysRange:   daysRangeValue,
 | |
| 			Week52Range: week52Value,
 | |
| 			MarketCap:   marketCapValue,
 | |
| 			Change:      changeValue,
 | |
| 		})
 | |
| 	} else {
 | |
| 		c.JSON(http.StatusOK, gin.H{
 | |
| 			"error":       "未找到全部数据",
 | |
| 			"Open":        openValue,
 | |
| 			"Volume":      volumeValue,
 | |
| 			"DaysRange":   daysRangeValue,
 | |
| 			"Week52Range": week52Value,
 | |
| 			"MarketCap":   marketCapValue,
 | |
| 			"change":      changeValue,
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| func sendErrorResponse(c *gin.Context, statusCode int, errorMsg string, detail string) {
 | |
| 	c.JSON(statusCode, gin.H{
 | |
| 		"error":  errorMsg,
 | |
| 		"detail": detail,
 | |
| 	})
 | |
| }
 |