| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- // ==========================================================================
- // GFast自动生成业务逻辑层相关代码,只生成一次,按需修改,再次生成不会覆盖.
- // 生成日期:2021-08-31 17:58:43
- // 生成路径: gfast/app/system/service/plugins_manage.go
- // 生成人:gfast
- // ==========================================================================
- package service
- import (
- "context"
- "encoding/json"
- "fmt"
- "gfast/app/common/global"
- "gfast/app/system/dao"
- "gfast/app/system/model"
- "gfast/library"
- "github.com/gogf/gf/container/garray"
- "github.com/gogf/gf/container/gmap"
- "github.com/gogf/gf/encoding/gcompress"
- "github.com/gogf/gf/encoding/gjson"
- "github.com/gogf/gf/encoding/gurl"
- "github.com/gogf/gf/errors/gerror"
- "github.com/gogf/gf/frame/g"
- "github.com/gogf/gf/net/ghttp"
- "github.com/gogf/gf/os/gfile"
- "github.com/gogf/gf/text/gstr"
- "github.com/gogf/gf/util/gconv"
- )
- type pluginsManage struct {
- }
- var PluginsManage = new(pluginsManage)
- // GetList 获取列表
- func (s *pluginsManage) GetList(req *dao.PluginsManageSearchReq) (total, page int, list []*dao.CsPluginListRes, err error) {
- //同步服务端插件商城
- total, page, list, err = s.syncFromStore(req)
- return
- }
- // GetInfoById 通过id获取
- func (s *pluginsManage) GetInfoById(ctx context.Context, id int64) (info *dao.PluginsManageInfoRes, err error) {
- if id == 0 {
- err = gerror.New("参数错误")
- return
- }
- var data *model.PluginsManage
- err = dao.PluginsManage.Ctx(ctx).Where(dao.PluginsManage.Columns.Id, id).Scan(&data)
- if err != nil {
- g.Log().Error(err)
- }
- if data == nil || err != nil {
- err = gerror.New("获取信息失败")
- }
- info = &dao.PluginsManageInfoRes{
- Id: data.Id,
- StoreId: data.StoreId,
- PName: data.PName,
- PTitle: data.PTitle,
- PDescription: data.PDescription,
- PAuth: data.PAuth,
- IsInstall: data.IsInstall,
- Status: data.Status,
- Version: data.Version,
- Price: data.Price,
- DownloadTimes: data.DownloadTimes,
- }
- return
- }
- // Add 添加
- func (s *pluginsManage) Add(ctx context.Context, req *dao.PluginsManageAddReq) (err error) {
- _, err = dao.PluginsManage.Ctx(ctx).Insert(req)
- return
- }
- // Edit 修改
- func (s *pluginsManage) Edit(ctx context.Context, req *dao.PluginsManageEditReq) error {
- _, err := dao.PluginsManage.Ctx(ctx).FieldsEx(dao.PluginsManage.Columns.Id).Where(dao.PluginsManage.Columns.Id, req.Id).
- Update(req)
- return err
- }
- // DeleteByIds 删除
- func (s *pluginsManage) DeleteByIds(ctx context.Context, ids []int) (err error) {
- if len(ids) == 0 {
- err = gerror.New("参数错误")
- return
- }
- _, err = dao.PluginsManage.Ctx(ctx).Delete(dao.PluginsManage.Columns.Id+" in (?)", ids)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("删除失败")
- }
- return
- }
- // ChangeStatus 修改状态
- func (s *pluginsManage) ChangeStatus(ctx context.Context, req *dao.PluginsManageStatusReq) error {
- _, err := dao.PluginsManage.Ctx(ctx).Where(dao.PluginsManage.Columns.StoreId, req.PluginId).Update(g.Map{
- dao.PluginsManage.Columns.Status: req.Status,
- })
- return err
- }
- //同步插件商城中的插件
- func (s *pluginsManage) syncFromStore(req *dao.PluginsManageSearchReq) (total, page int, csPluginList []*dao.CsPluginListRes, err error) {
- storeUrl := g.Cfg().GetString("plugin.serverUrl") + "/codeStore/pluginList"
- res := (*ghttp.ClientResponse)(nil)
- if req.PageNum == 0 {
- req.PageNum = 1
- }
- page = req.PageNum
- res, err = g.Client().Ctx(req.Ctx).Get(storeUrl, g.MapStrAny{
- "pageNum": req.PageNum,
- "PageSize": req.PageSize,
- "pluginName": req.PTitle,
- })
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("获取插件数据失败")
- return
- }
- defer res.Close()
- var data map[string]interface{}
- b := res.ReadAll()
- err = json.Unmarshal(b, &data)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("获取插件数据失败")
- return
- }
- if gconv.Int(data["code"]) == 0 {
- err = gconv.Structs((data["data"].(g.Map))["list"], &csPluginList)
- if err != nil {
- return
- }
- csPluginList, err = s.updatePlugins(req.Ctx, csPluginList)
- if err != nil {
- return
- }
- total = gconv.Int((data["data"].(g.Map))["total"])
- } else {
- err = gerror.New(data["msg"].(string))
- return
- }
- return
- }
- // 更新插件数据
- func (s *pluginsManage) updatePlugins(ctx context.Context, csList []*dao.CsPluginListRes) (newList []*dao.CsPluginListRes, err error) {
- ids := make([]uint, len(csList))
- for k, v := range csList {
- ids[k] = v.PluginId
- }
- //查询插件信息
- var pluginList []*model.PluginsManage
- err = dao.PluginsManage.Ctx(ctx).Where(dao.PluginsManage.Columns.StoreId+" in(?)", ids).Scan(&pluginList)
- if err != nil {
- return
- }
- hasIds := garray.NewArraySize(len(pluginList), 100)
- gmp := gmap.New()
- for k, v := range pluginList {
- hasIds.Set(k, v.StoreId)
- gmp.Set(v.StoreId, v)
- }
- for _, v := range csList {
- pluginId := gconv.Int(v.PluginId)
- if hasIds.Len() > 0 && hasIds.Contains(pluginId) {
- plugin := gmp.Get(pluginId).(*model.PluginsManage)
- //修改
- version := plugin.Version
- if plugin.IsInstall == 0 && len(v.PluginInfo) > 0 {
- version = v.PluginInfo[0].InfoVersion
- }
- err = s.Edit(ctx, &dao.PluginsManageEditReq{
- Id: plugin.Id,
- StoreId: pluginId,
- PName: v.CodeName,
- PTitle: v.PluginName,
- PDescription: v.Description,
- PAuth: v.MemName,
- Status: plugin.Status,
- Version: version,
- Price: v.PluginPrice,
- DownloadTimes: gconv.Uint(v.DownloadTimes),
- IsInstall: plugin.IsInstall,
- })
- v.Status = plugin.Status
- v.Version = version
- v.IsInstall = plugin.IsInstall
- v.PluginPriceStr = s.Int64ToDecimal(gconv.Int64(v.PluginPrice))
- } else {
- //新增
- version := ""
- if len(v.PluginInfo) > 0 {
- version = v.PluginInfo[0].InfoVersion
- }
- err = s.Add(ctx, &dao.PluginsManageAddReq{
- StoreId: pluginId,
- PName: v.CodeName,
- PTitle: v.PluginName,
- PDescription: v.Description,
- PAuth: v.MemName,
- Status: 0,
- Version: version,
- Price: v.PluginPrice,
- DownloadTimes: gconv.Uint(v.DownloadTimes),
- IsInstall: 0,
- })
- v.Status = 0
- v.Version = version
- v.IsInstall = 0
- v.PluginPriceStr = s.Int64ToDecimal(gconv.Int64(v.PluginPrice))
- }
- if err != nil {
- return
- }
- }
- newList = csList
- return
- }
- // DecimalToInt64 元转分
- func (s *pluginsManage) DecimalToInt64(decimal string) (i int64) {
- pos := gstr.PosR(decimal, ".")
- integer := gconv.Int64(gstr.SubStr(decimal, 0, pos)) * 100
- dec := int64(0)
- if pos > -1 {
- dec = gconv.Int64(gstr.SubStr(decimal, pos+1, 2))
- }
- i = integer + dec
- return
- }
- // Int64ToDecimal 分转元
- func (s *pluginsManage) Int64ToDecimal(i int64) (decimal string) {
- b := []byte(gconv.String(i))
- for {
- if len(b) >= 2 {
- break
- }
- b = append([]byte{'0'}, b...)
- }
- integer := b[:len(b)-2]
- if len(integer) == 0 {
- integer = []byte{'0'}
- }
- dec := b[len(b)-2:]
- decimal = fmt.Sprintf("%s.%s", integer, dec)
- return
- }
- // Install 插件安装
- func (s *pluginsManage) Install(ctx context.Context, req *dao.PluginsManageInstallReq) (err error) {
- //生成下载链接
- storeUrl := g.Cfg().GetString("plugin.serverUrl") + "/codeStoreFrontAdmin/getDownloadInfo"
- res := (*ghttp.ClientResponse)(nil)
- res, err = g.Client().Ctx(ctx).Get(fmt.Sprintf("%s?pluginId=%d&version=%s&token=%s", storeUrl, req.PluginId, req.Version,
- gurl.RawEncode(req.RToken)))
- if err != nil {
- return
- }
- defer res.Close()
- var data map[string]interface{}
- b := res.ReadAll()
- err = json.Unmarshal(b, &data)
- if err != nil {
- return
- }
- if gconv.Int(data["code"]) == 0 {
- url := fmt.Sprintf("%s/%s&token=%s", g.Cfg().GetString("plugin.serverUrl"),
- (data["data"]).(string), gurl.RawEncode(req.RToken))
- //下载插件并安装
- err = s.downloadAndInstall(ctx, url)
- } else {
- err = gerror.New(data["msg"].(string))
- }
- return
- }
- // GetCaptcha 获取验证码
- func (s *pluginsManage) GetCaptcha(ctx context.Context) (idKeyC, base64stringC string, err error) {
- storeUrl := g.Cfg().GetString("plugin.serverUrl") + "/captcha/get"
- res := (*ghttp.ClientResponse)(nil)
- res, err = g.Client().Ctx(ctx).Get(storeUrl)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("获取验证码失败")
- return
- }
- defer res.Close()
- var data map[string]interface{}
- b := res.ReadAll()
- err = json.Unmarshal(b, &data)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("获取插件数据失败")
- return
- }
- if gconv.Int(data["code"]) == 0 {
- data = (data["data"]).(g.Map)
- idKeyC = gconv.String(data["idKeyC"])
- base64stringC = gconv.String(data["base64stringC"])
- } else {
- err = gerror.New(data["msg"].(string))
- }
- return
- }
- // LoginR 登录
- func (s *pluginsManage) LoginR(ctx context.Context, loginReq *dao.PluginRLoginFormReq) (userInfo g.Map, err error) {
- storeUrl := g.Cfg().GetString("plugin.serverUrl") + "/codeStoreFrontAdmin/login"
- res := (*ghttp.ClientResponse)(nil)
- res, err = g.Client().Ctx(ctx).Post(storeUrl, loginReq)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("获取验证码失败")
- return
- }
- defer res.Close()
- var data map[string]interface{}
- b := res.ReadAll()
- err = json.Unmarshal(b, &data)
- if err != nil {
- g.Log().Error(err)
- err = gerror.New("登录失败")
- return
- }
- if gconv.Int(data["code"]) == 0 {
- userInfo = (data["data"]).(g.Map)
- } else {
- err = gerror.New(data["msg"].(string))
- }
- return
- }
- // 下载并安装插件
- func (s *pluginsManage) downloadAndInstall(ctx context.Context, url string) error {
- res, err := g.Client().Ctx(ctx).Get(url)
- if err != nil {
- return err
- }
- defer res.Close()
- ct := res.Header.Get("Content-Type")
- if gstr.ContainsI(ct, "json") {
- var data map[string]interface{}
- b := res.ReadAll()
- err = json.Unmarshal(b, &data)
- if err != nil {
- return err
- }
- if gconv.Int(data["code"]) != 0 {
- err = gerror.New(data["msg"].(string))
- }
- return err
- } else {
- //安装
- //获取插件名称
- fileName := res.Header.Get("content-disposition")
- fileName = gstr.SubStr(fileName, gstr.PosR(fileName, "=")+1,
- gstr.PosR(fileName, ".")-gstr.PosR(fileName, "=")-1)
- err = s.InstallFile(ctx, res.ReadAll(), fileName)
- if err != nil {
- return err
- }
- }
- return nil
- }
- // InstallFile 安装插件文件
- func (s *pluginsManage) InstallFile(ctx context.Context, data []byte, fileName string) (err error) {
- //获取插件下载路径
- downloadPath := library.GetExcPath() + "/data/installPlugins"
- if !gfile.IsDir(downloadPath) {
- err = gfile.Mkdir(downloadPath)
- if err != nil {
- return
- }
- }
- g.Log().Debug(downloadPath, fileName)
- // 删除安装临时文件
- defer gfile.Remove(downloadPath + "/" + fileName)
- err = gcompress.UnZipContent(data, downloadPath)
- if err != nil {
- return
- }
- //获取插件配置信息
- var installCfg *gjson.Json
- installCfg, err = gjson.Load(downloadPath + "/" + fileName + "/install.json")
- if err != nil {
- return
- }
- mustGfastVersion := installCfg.GetString("minGfastVersion")
- if gstr.CompareVersion(mustGfastVersion, global.Version) > 0 {
- err = gerror.New(fmt.Sprintf("您的gfast版本过低,此插件要求gfast版本为:%s", mustGfastVersion))
- return
- }
- //获取本项目安装情况
- var plugin *model.PluginsManage
- err = dao.PluginsManage.Ctx(ctx).Where(dao.PluginsManage.Columns.PName, fileName).Limit(1).Scan(&plugin)
- if err != nil {
- return
- }
- if plugin == nil {
- err = gerror.New("插件信息不存在,请刷新页面后再安装。")
- return
- }
- //复制插件文件到对应目录
- //1.后端
- err = gfile.Copy(downloadPath+"/"+fileName+"/go/", library.GetExcPath())
- if err != nil {
- return
- }
- //2.前端
- fontRoot := g.Cfg().GetString("gen.frontDir")
- if !gfile.IsDir(fontRoot) {
- err = gerror.New("前端路径不存在,请配置gen.frontDir")
- return
- }
- err = gfile.Copy(downloadPath+"/"+fileName+"/vue/", fontRoot+"/src")
- if err != nil {
- return
- }
- // 安装成功后修改插件安装状态及安装路径
- _, err = dao.PluginsManage.Ctx(ctx).WherePri(plugin.Id).Update(g.Map{
- dao.PluginsManage.Columns.IsInstall: 1,
- dao.PluginsManage.Columns.Status: 1,
- dao.PluginsManage.Columns.InstallPath: installCfg.GetString("installPath"),
- dao.PluginsManage.Columns.Version: installCfg.GetString("version"),
- })
- return
- }
- // PluginIsExists 判断插件是否存在
- func (s *pluginsManage) PluginIsExists(ctx context.Context, name string) error {
- info := (*model.PluginsManage)(nil)
- err := dao.PluginsManage.Ctx(ctx).Where(dao.PluginsManage.Columns.PName, name).Limit(1).
- Fields(dao.PluginsManage.Columns.Id).Scan(&info)
- if err != nil {
- return err
- }
- if info == nil {
- return gerror.New("不属于官方插件,无法安装。")
- }
- return nil
- }
|