From a74511ad4d49e7d518b7d1fe3f1552150e7f6b40 Mon Sep 17 00:00:00 2001 From: silenceqi Date: Fri, 25 Dec 2020 16:15:15 +0800 Subject: [PATCH] fullfill document CURD preview --- api/index_management/document.go | 136 +++ api/index_management/index.go | 74 +- api/init.go | 8 +- config/config.go | 10 +- main.go | 4 +- search-center.yml | 2 +- ui.go | 4 +- web/config/router.config.js | 4 +- web/src/pages/DataManagement/Document.js | 960 +++++++----------- web/src/pages/DataManagement/Index.js | 610 +++++++++++ web/src/pages/DataManagement/Query.js | 141 --- .../pages/DataManagement/models/document.js | 208 ++++ web/src/pages/SearchManage/dict/Pro.js | 143 ++- web/src/pages/SearchManage/models/dict.js | 99 +- web/src/services/doc.js | 44 + 15 files changed, 1540 insertions(+), 907 deletions(-) create mode 100644 api/index_management/document.go create mode 100644 web/src/pages/DataManagement/Index.js delete mode 100644 web/src/pages/DataManagement/Query.js create mode 100644 web/src/pages/DataManagement/models/document.js create mode 100644 web/src/services/doc.js diff --git a/api/index_management/document.go b/api/index_management/document.go new file mode 100644 index 00000000..75754c77 --- /dev/null +++ b/api/index_management/document.go @@ -0,0 +1,136 @@ +package index_management + +import ( + "fmt" + "net/http" + + httprouter "infini.sh/framework/core/api/router" + "infini.sh/framework/core/elastic" + "infini.sh/framework/core/util" +) + +type docReqBody struct { + Index string `json:"index"` + Action string `json:"action"` + Payload map[string]interface{} `json:"payload"` + PageIndex int `json:"pageIndex"` + PageSize int `json:"pageSize"` + Filter string `json:"filter"` + Cluster string `json:"cluster"` +} + +func (handler APIHandler) HandleDocumentAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { + client := elastic.GetClient(handler.Config.Elasticsearch) + reqBody := docReqBody{} + resResult := map[string]interface{}{ + "errno": "0", + "errmsg": "", + "payload": nil, + } + err := handler.DecodeJSON(req, &reqBody) + if err != nil { + panic(err) + } + indexName := ps.ByName("index") + var id string + if val, ok := reqBody.Payload["id"]; ok { + id = val.(string) + } + if _, ok := reqBody.Payload["_index"]; ok { + delete(reqBody.Payload, "_index") + } + switch reqBody.Action { + case "ADD": + id = util.GetUUID() + //security problem + _, err := client.Index(indexName, id, reqBody.Payload) + if err != nil { + panic(err) + } + reqBody.Payload["id"] = id + resResult["payload"] = reqBody.Payload + handler.WriteJSON(w, resResult, http.StatusOK) + case "SAVE": + if id == "" { + panic("empty id") + } + resp, err := client.Get(indexName, id) + if err != nil { + panic(err) + } + source := resp.Source + for k, v := range reqBody.Payload { + source[k] = v + } + _, err = client.Index(indexName, id, source) + if err != nil { + panic(err) + } + handler.WriteJSON(w, resResult, http.StatusOK) + + case "DELETE": + if id == "" { + panic("empty id") + } + _, err = client.Delete(indexName, id) + if err != nil { + resResult["errmsg"] = err.Error() + resResult["errno"] = "E100003" + handler.WriteJSON(w, resResult, http.StatusOK) + return + } + handler.WriteJSON(w, resResult, http.StatusOK) + default: + var ( + pageSize = 10 + pageIndex = 1 + ) + if reqBody.PageSize > 0 { + pageSize = reqBody.PageSize + } + if reqBody.PageIndex > 0 { + pageIndex = reqBody.PageIndex + } + from := (pageIndex - 1) * pageSize + filter := `{"match_all": {}}` + if reqBody.Filter != "" { + filter = reqBody.Filter + } + query := fmt.Sprintf(`{"from":%d, "size": %d, "query": %s}`, from, pageSize, filter) + var reqBytes = []byte(query) + resp, err := client.SearchWithRawQueryDSL(indexName, reqBytes) + if err != nil { + panic(err) + } + + result := formatESSearchResult(resp) + + handler.WriteJSON(w, map[string]interface{}{ + "errno": "0", + "errmsg": "", + "payload": result, + }, http.StatusOK) + } +} + +func formatESSearchResult(esResp *elastic.SearchResponse) map[string]interface{} { + total := esResp.Hits.Total + if len(esResp.Hits.Hits) == 0 { + return map[string]interface{}{ + "total": total, + "data": nil, + } + } + dataArr := make([]interface{}, 0, len(esResp.Hits.Hits)) + for _, hit := range esResp.Hits.Hits { + if _, ok := hit.Source["id"]; !ok { + hit.Source["id"] = hit.ID + } + hit.Source["_index"] = hit.Index + dataArr = append(dataArr, hit.Source) + } + return map[string]interface{}{ + "total": total, + "data": dataArr, + } +} diff --git a/api/index_management/index.go b/api/index_management/index.go index e8061231..0e40ac3f 100644 --- a/api/index_management/index.go +++ b/api/index_management/index.go @@ -10,10 +10,12 @@ import ( httprouter "infini.sh/framework/core/api/router" "infini.sh/framework/core/orm" "infini.sh/framework/core/util" + "infini.sh/search-center/config" model2 "infini.sh/search-center/model" ) type APIHandler struct { + Config *config.AppConfig api.Handler } @@ -44,37 +46,22 @@ func (handler APIHandler) GetDictListAction(w http.ResponseWriter, req *http.Req func (handler APIHandler) CreateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { //id := ps.ByName("id") - jq, err := handler.GetJSON(req) - if err != nil { - handler.Error(w, err) - return - } - name, err := jq.String("name") - if err != nil { - handler.Error(w, err) - return - } - tags, err := jq.ArrayOfStrings("tags") - if err != nil { - handler.Error(w, err) - return - } - - content, err := jq.String("content") - if err != nil { - handler.Error(w, err) - return - } createdAt := time.Now() dict := model2.Dict{ ID: util.GetUUID(), - Name: name, - Tags: tags, - Content: []byte(content), CreatedAt: createdAt, UpdatedAt: createdAt, } + err := handler.DecodeJSON(req, &dict) + if err != nil { + handler.WriteJSON(w, map[string]interface{}{ + "payload": nil, + "errno": "E100001", + "errmsg": err.Error(), + }, http.StatusOK) + return + } err = orm.Save(dict) if err != nil { @@ -103,41 +90,18 @@ func (handler APIHandler) DeleteDictItemAction(w http.ResponseWriter, req *http. } func (handler APIHandler) UpdateDictItemAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params) { - jq, err := handler.GetJSON(req) + dict := model2.Dict{} + err := handler.DecodeJSON(req, &dict) if err != nil { - handler.Error(w, err) + handler.WriteJSON(w, map[string]interface{}{ + "payload": nil, + "errno": "E100002", + "errmsg": err.Error(), + }, http.StatusOK) return - } - id, err := jq.String("id") - if err != nil { - handler.Error(w, err) - return - } - name, err := jq.String("name") - if err != nil { - handler.Error(w, err) - return - } - tags, err := jq.ArrayOfStrings("tags") - if err != nil { - handler.Error(w, err) - return - } - content, err := jq.String("content") - if err != nil { - handler.Error(w, err) - return - } - updatedAt := time.Now() - - dict := model2.Dict{ - ID: id, - Name: name, - Tags: tags, - Content: []byte(content), - UpdatedAt: updatedAt, } + dict.UpdatedAt = time.Now() err = orm.Update(dict) if err != nil { diff --git a/api/init.go b/api/init.go index 518c6ed3..9a170c3a 100644 --- a/api/init.go +++ b/api/init.go @@ -4,10 +4,13 @@ import ( "infini.sh/framework/core/api" "infini.sh/framework/core/ui" "infini.sh/search-center/api/index_management" + "infini.sh/search-center/config" ) -func Init() { - handler := index_management.APIHandler{} +func Init(cfg *config.AppConfig) { + handler := index_management.APIHandler{ + Config: cfg, + } //ui.HandleUIMethod(api.POST, "/api/get_indices",index_management.API1) ui.HandleUIMethod(api.GET, "/api/dict/_search", handler.GetDictListAction) ui.HandleUIMethod(api.POST, "/api/dict/_create", handler.CreateDictItemAction) @@ -15,4 +18,5 @@ func Init() { ui.HandleUIMethod(api.DELETE, "/api/dict/:id", handler.DeleteDictItemAction) //ui.HandleUIMethod(api.DELETE, "/api/dict/", handler.DeleteDictItemAction2) ui.HandleUIMethod(api.POST, "/api/dict/_update", handler.UpdateDictItemAction) + ui.HandleUIMethod(api.POST, "/api/doc/:index", handler.HandleDocumentAction) } diff --git a/config/config.go b/config/config.go index cbf93610..22721f80 100644 --- a/config/config.go +++ b/config/config.go @@ -1,9 +1,9 @@ package config type AppConfig struct { - IndexName string `config:"index_name"` - ElasticConfig string `config:"elastic_config"` - UILocalPath string `config:"ui_path"` - UILocalEnabled bool `config:"ui_local"` - UIVFSEnabled bool `config:"ui_vfs"` + IndexName string `config:"index_name"` + Elasticsearch string `config:"elasticsearch"` + UILocalPath string `config:"ui_path"` + UILocalEnabled bool `config:"ui_local"` + UIVFSEnabled bool `config:"ui_vfs"` } diff --git a/main.go b/main.go index bcacfae7..ec2d2cb2 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,7 @@ func main() { modules.Register() appConfig = &config.AppConfig{ - ElasticConfig: "default", + Elasticsearch: "default", UILocalPath: ".public", UIVFSEnabled: true, UILocalEnabled: true, @@ -62,7 +62,7 @@ func main() { } //load web UI files - appUI = &UI{config: appConfig} + appUI = &UI{Config: appConfig} appUI.InitUI() //start each module, with enabled provider diff --git a/search-center.yml b/search-center.yml index c9438bd1..375b1c84 100644 --- a/search-center.yml +++ b/search-center.yml @@ -2,7 +2,7 @@ elasticsearch: - name: default enabled: true endpoint: http://localhost:9200 - index_prefix: infini- + index_prefix: basic_auth: username: elastic password: ZBdkVQUUdF1Sir4X4BGB diff --git a/ui.go b/ui.go index 44673adf..a6bb53a9 100644 --- a/ui.go +++ b/ui.go @@ -15,7 +15,7 @@ import ( type UI struct { api.Handler - config *config.AppConfig + Config *config.AppConfig } func (h UI) InitUI() { @@ -24,7 +24,7 @@ func (h UI) InitUI() { ui.HandleUI("/", vfs.FileServer(vfs.VFS())) - uiapi.Init() + uiapi.Init(h.Config) ui.HandleUIFunc("/api/", func(w http.ResponseWriter, req *http.Request) { log.Warn("api: ", req.URL, " not implemented") diff --git a/web/config/router.config.js b/web/config/router.config.js index da6519f2..cb3bd601 100644 --- a/web/config/router.config.js +++ b/web/config/router.config.js @@ -90,7 +90,7 @@ export default [ }, { path: '/data/indices/doc', - component: './DataManagement/Document', + component: './DataManagement/Index', }, { path: '/data/indices/template', @@ -129,7 +129,7 @@ export default [ },{ path: '/data/doc', name: 'query', - component: './DataManagement/Query', + component: './DataManagement/Document', }, ] }, diff --git a/web/src/pages/DataManagement/Document.js b/web/src/pages/DataManagement/Document.js index b2c386e2..c4d20be4 100644 --- a/web/src/pages/DataManagement/Document.js +++ b/web/src/pages/DataManagement/Document.js @@ -1,610 +1,392 @@ -import React, { PureComponent, Fragment } from 'react'; +import React, { Component } from 'react'; import { connect } from 'dva'; -import { - Row, - Col, - Card, - Form, - Input, - Button, - Modal, - message, - Divider, - Drawer, - Tabs, - Descriptions, - Menu, - Dropdown, - Icon -} from 'antd'; -import StandardTable from '@/components/StandardTable'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import { Col, Form, Row,Select, Input, Card,Icon, Table, InputNumber, Popconfirm, + Divider,Button,Tooltip, Cascader } from 'antd'; +const {Option} = Select; -import styles from '../List/TableList.less'; -import JSONPretty from 'react-json-prettify'; +const EditableContext = React.createContext(); -const FormItem = Form.Item; -const { TextArea } = Input; -const {TabPane} = Tabs; - -class JSONWrapper extends PureComponent { - state ={ - height: 400, - } - componentDidMount(){ - - let getElementTop = (elem)=>{ -   var elemTop=elem.offsetTop; -   elem=elem.offsetParent; - -   while(elem!=null){ -     elemTop+=elem.offsetTop; -     elem=elem.offsetParent; -   } - -   return elemTop; - +class EditableCell extends React.Component { + getInput = () => { + let {record, dataIndex} = this.props; + if (typeof record[dataIndex] === 'number') { + return ; } - console.log(getElementTop(this.refs.jsonw)); - this.setState({height: window.innerHeight - getElementTop(this.refs.jsonw) -50}); - } - render(){ - return ( -
{console.log(document.getElementById('jsonw').offsetTop)}} style={{overflow:"scroll", height: this.state.height}}> {this.props.children}
- ) - } -} - -const CreateForm = Form.create()(props => { - const { modalVisible, form, handleAdd, handleModalVisible } = props; - const okHandle = () => { - form.validateFields((err, fieldsValue) => { - if (err) return; - form.resetFields(); - handleAdd(fieldsValue); - }); - }; - return ( - handleModalVisible()} - > - - {form.getFieldDecorator('index', { - rules: [{ required: true, message: '请输入至少五个字符的名称!', min: 5 }], - })()} - - - {form.getFieldDecorator('settings', { - rules: [{ required: true }], - })(