335 lines
8.6 KiB
Go
335 lines
8.6 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"syscall/js"
|
||
"wasm-go/internal/api"
|
||
"wasm-go/internal/excel"
|
||
)
|
||
|
||
func main() {
|
||
// 注册各种功能函数
|
||
js.Global().Set("analyzeCompanyIndustryAsync", js.FuncOf(analyzeCompanyIndustryAsync))
|
||
js.Global().Set("parseExcelAsync", js.FuncOf(parseExcelAsync))
|
||
js.Global().Set("callLLMAsync", js.FuncOf(callLLMAsync))
|
||
js.Global().Set("callTaxHealthAsync", js.FuncOf(callTaxHealthAsync))
|
||
|
||
// 保持程序运行
|
||
select {} // 无限循环,保持程序运行
|
||
}
|
||
|
||
// analyzeCompanyIndustryAsync 异步版本的函数,返回Promise
|
||
func analyzeCompanyIndustryAsync(this js.Value, args []js.Value) interface{} {
|
||
// 获取公司名称参数
|
||
companyName := args[0].String()
|
||
|
||
// 创建一个通道来处理结果
|
||
resultChan := make(chan interface{}, 1)
|
||
errorChan := make(chan error, 1) // 使用error类型而不是interface{}
|
||
|
||
// 在goroutine中执行异步操作
|
||
go func() {
|
||
// 创建LLM客户端
|
||
llmClient := api.NewOllamaClient("http://localhost:11434", "qwen3.5:9b")
|
||
|
||
// 创建企业行业分类器
|
||
classifier := api.NewCompanyIndustryClassifier(llmClient)
|
||
|
||
// 分析企业行业
|
||
result, err := classifier.ClassifyCompany(companyName)
|
||
if err != nil {
|
||
// 发送错误到错误通道
|
||
errorChan <- err
|
||
} else {
|
||
// 发送结果到结果通道
|
||
resultChan <- result
|
||
}
|
||
}()
|
||
|
||
// 创建Promise
|
||
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
|
||
if len(promiseArgs) < 2 {
|
||
// 如果参数不足,返回一个立即拒绝的Promise
|
||
return nil
|
||
}
|
||
|
||
resolve := promiseArgs[0]
|
||
reject := promiseArgs[1]
|
||
|
||
// 启动一个goroutine来处理结果
|
||
go func() {
|
||
select {
|
||
case result := <-resultChan:
|
||
// 将复杂结构体序列化为JSON
|
||
jsonResult, err := json.Marshal(result)
|
||
if err != nil {
|
||
// 序列化失败,返回错误
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": "JSON序列化失败: " + err.Error(),
|
||
}))
|
||
return
|
||
}
|
||
|
||
// 将JSON字符串解析为JavaScript对象
|
||
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
|
||
resolve.Invoke(jsResult)
|
||
case err := <-errorChan:
|
||
// 将错误转换为JavaScript值
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": err.Error(),
|
||
}))
|
||
}
|
||
}()
|
||
|
||
return nil
|
||
}))
|
||
|
||
return promise
|
||
}
|
||
|
||
// parseExcelAsync 解析Excel文件的异步函数
|
||
func parseExcelAsync(this js.Value, args []js.Value) interface{} {
|
||
// 获取Excel文件的ArrayBuffer
|
||
arrayBuffer := args[0]
|
||
uint8Array := js.Global().Get("Uint8Array").New(arrayBuffer)
|
||
|
||
// 创建字节切片
|
||
length := uint8Array.Get("length").Int()
|
||
excelBytes := make([]byte, length)
|
||
|
||
// 将数据复制到Go字节切片
|
||
for i := 0; i < length; i++ {
|
||
excelBytes[i] = byte(uint8Array.Index(i).Int())
|
||
}
|
||
|
||
// 创建一个通道来处理结果
|
||
resultChan := make(chan interface{}, 1)
|
||
errorChan := make(chan error, 1)
|
||
|
||
// 在goroutine中执行异步操作
|
||
go func() {
|
||
// 创建Excel读取器
|
||
reader, err := excel.NewXLSXReaderFromBytes(excelBytes)
|
||
if err != nil {
|
||
errorChan <- err
|
||
return
|
||
}
|
||
|
||
// 读取所有工作表
|
||
sheetNames, err := reader.GetSheetNames()
|
||
if err != nil {
|
||
errorChan <- err
|
||
return
|
||
}
|
||
|
||
// 创建一个map来存储所有工作表的数据
|
||
sheets := make(map[string][][]string)
|
||
|
||
// 读取每个工作表的数据
|
||
for _, sheetName := range sheetNames {
|
||
sheetData, err := reader.GetSheetData(sheetName)
|
||
if err != nil {
|
||
// 记录错误但继续处理其他工作表
|
||
continue
|
||
}
|
||
sheets[sheetName] = sheetData
|
||
}
|
||
|
||
// 将结果转换为适当的格式
|
||
result := map[string]interface{}{
|
||
"sheets": sheets,
|
||
}
|
||
|
||
resultChan <- result
|
||
}()
|
||
|
||
// 创建Promise
|
||
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
|
||
if len(promiseArgs) < 2 {
|
||
// 如果参数不足,返回一个立即拒绝的Promise
|
||
return nil
|
||
}
|
||
|
||
resolve := promiseArgs[0]
|
||
reject := promiseArgs[1]
|
||
|
||
// 启动一个goroutine来处理结果
|
||
go func() {
|
||
select {
|
||
case result := <-resultChan:
|
||
// 将复杂结构体序列化为JSON
|
||
jsonResult, err := json.Marshal(result)
|
||
if err != nil {
|
||
// 序列化失败,返回错误
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": "JSON序列化失败: " + err.Error(),
|
||
}))
|
||
return
|
||
}
|
||
|
||
// 将JSON字符串解析为JavaScript对象
|
||
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
|
||
resolve.Invoke(jsResult)
|
||
case err := <-errorChan:
|
||
// 将错误转换为JavaScript值
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": err.Error(),
|
||
}))
|
||
}
|
||
}()
|
||
|
||
return nil
|
||
}))
|
||
|
||
return promise
|
||
}
|
||
|
||
// callLLMAsync 调用大模型的异步函数
|
||
func callLLMAsync(this js.Value, args []js.Value) interface{} {
|
||
// 获取提示词参数
|
||
prompt := args[0].String()
|
||
|
||
// 创建一个通道来处理结果
|
||
resultChan := make(chan interface{}, 1)
|
||
errorChan := make(chan error, 1)
|
||
|
||
// 在goroutine中执行异步操作
|
||
go func() {
|
||
// 创建LLM客户端(可以根据需要选择不同的模型)
|
||
llmClient := api.NewOllamaClient("http://localhost:11434", "qwen3.5:9b")
|
||
|
||
// 调用大模型
|
||
response, err := llmClient.SimpleChat(prompt)
|
||
if err != nil {
|
||
errorChan <- err
|
||
return
|
||
}
|
||
|
||
result := map[string]string{
|
||
"response": response,
|
||
}
|
||
|
||
resultChan <- result
|
||
}()
|
||
|
||
// 创建Promise
|
||
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
|
||
if len(promiseArgs) < 2 {
|
||
// 如果参数不足,返回一个立即拒绝的Promise
|
||
return nil
|
||
}
|
||
|
||
resolve := promiseArgs[0]
|
||
reject := promiseArgs[1]
|
||
|
||
// 启动一个goroutine来处理结果
|
||
go func() {
|
||
select {
|
||
case result := <-resultChan:
|
||
// 将复杂结构体序列化为JSON
|
||
jsonResult, err := json.Marshal(result)
|
||
if err != nil {
|
||
// 序列化失败,返回错误
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": "JSON序列化失败: " + err.Error(),
|
||
}))
|
||
return
|
||
}
|
||
|
||
// 将JSON字符串解析为JavaScript对象
|
||
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
|
||
resolve.Invoke(jsResult)
|
||
case err := <-errorChan:
|
||
// 将错误转换为JavaScript值
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": err.Error(),
|
||
}))
|
||
}
|
||
}()
|
||
|
||
return nil
|
||
}))
|
||
|
||
return promise
|
||
}
|
||
|
||
// callTaxHealthAsync 调用税务健康API的异步函数
|
||
// 注意:由于WASM环境的CORS限制,我们在这里提供模拟实现
|
||
func callTaxHealthAsync(this js.Value, args []js.Value) interface{} {
|
||
// 获取公司信息参数
|
||
companyInfoJSON := args[0].String()
|
||
|
||
// 创建一个通道来处理结果
|
||
resultChan := make(chan interface{}, 1)
|
||
errorChan := make(chan error, 1)
|
||
|
||
// 在goroutine中执行异步操作
|
||
go func() {
|
||
// 由于WASM环境无法直接调用外部API(CORS限制)
|
||
// 我们返回一个模拟的响应
|
||
simulatedResponse := map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": map[string]interface{}{
|
||
"req_no": "REQ" + fmt.Sprint(js.Global().Get("Date").New().Call("getTime").Int()),
|
||
"order_no": "ORDER" + fmt.Sprint(js.Global().Get("Date").New().Call("getTime").Int()),
|
||
},
|
||
"message": "模拟的税务健康评估结果",
|
||
}
|
||
|
||
// 解析输入的JSON以获取一些信息用于模拟
|
||
var companyInfo map[string]interface{}
|
||
err := json.Unmarshal([]byte(companyInfoJSON), &companyInfo)
|
||
if err != nil {
|
||
errorChan <- err
|
||
return
|
||
}
|
||
|
||
// 根据输入数据添加一些模拟的评估结果
|
||
simulatedResponse["company_data"] = companyInfo
|
||
|
||
resultChan <- simulatedResponse
|
||
}()
|
||
|
||
// 创建Promise
|
||
promise := js.Global().Get("Promise").New(js.FuncOf(func(this js.Value, promiseArgs []js.Value) interface{} {
|
||
if len(promiseArgs) < 2 {
|
||
// 如果参数不足,返回一个立即拒绝的Promise
|
||
return nil
|
||
}
|
||
|
||
resolve := promiseArgs[0]
|
||
reject := promiseArgs[1]
|
||
|
||
// 启动一个goroutine来处理结果
|
||
go func() {
|
||
select {
|
||
case result := <-resultChan:
|
||
// 将复杂结构体序列化为JSON
|
||
jsonResult, err := json.Marshal(result)
|
||
if err != nil {
|
||
// 序列化失败,返回错误
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": "JSON序列化失败: " + err.Error(),
|
||
}))
|
||
return
|
||
}
|
||
|
||
// 将JSON字符串解析为JavaScript对象
|
||
jsResult := js.Global().Get("JSON").Call("parse", string(jsonResult))
|
||
resolve.Invoke(jsResult)
|
||
case err := <-errorChan:
|
||
// 将错误转换为JavaScript值
|
||
reject.Invoke(js.ValueOf(map[string]string{
|
||
"error": err.Error(),
|
||
}))
|
||
}
|
||
}()
|
||
|
||
return nil
|
||
}))
|
||
|
||
return promise
|
||
}
|