Parcourir la source

Merge branch 'develop'

gaozhan il y a 5 ans
Parent
commit
f408486834

+ 13 - 13
src/conf/config.js

@@ -1,20 +1,20 @@
-let dc = '/back-apit/api';
-let tc = '/back-apit/api';
-let us = '/back-apit/api';
-const apiCdn = 'http://cdn01t.weipaitang.com/img/';
-let auth = '/back-autht/api';
-const hostDev = `${window.location.protocol}//${window.location.host}`;
-const sTaskJobLog = 'http://ms-trace.weipaitang.com'; // 定时任务日志跳转
-let thanos = '/thanos-admint/api';
+let dc = '/back-apit/api'
+let tc = '/back-apit/api'
+let us = '/back-apit/api'
+const apiCdn = 'http://cdn01t.weipaitang.com/img/'
+let auth = '/back-autht/api'
+const hostDev = `${window.location.protocol}//${window.location.host}`
+const sTaskJobLog = 'http://ms-trace.weipaitang.com' // 定时任务日志跳转
+let thanos = '/thanos-admint/api'
 // let thanos = 'http://localhost:7070'
 
 if (document.domain === 'back-admin.weipaitang.com') {
-  dc = '/back-api/api';
-  tc = '/back-api/api';
-  auth = '/back-auth/api';
-  us = '/back-api/api';
+  dc = '/back-api/api'
+  tc = '/back-api/api'
+  auth = '/back-auth/api'
+  us = '/back-api/api'
   // sTaskJobLog = '/ms-trace/api' // 定时任务日志跳转
-  thanos = '/thanos-admin/api';
+  thanos = '/thanos-admin/api'
 }
 
 export { dc, tc, us, apiCdn, auth, hostDev, sTaskJobLog, thanos };

+ 1 - 1
src/conf/proxyMap.js

@@ -3,7 +3,7 @@ module.exports = {
   '/back-apit/api': 'http://back-apit.weipaitang.com',
   '/back-autht/api': 'https://back-autht.weipaitang.com',
   '/ms-tracet/api': 'http://10.3.7.11:16686',
-  '/thanos-admint/api': 'http://thanos-admint.wpt.la',
+  '/thanos-admint/api': 'http://10.3.7.22:7070',
   // 生产环境
   '/back-auth/api': 'https://back-auth.weipaitang.com',
   '/back-api/api': 'http://back-api.weipaitang.com',

+ 38 - 0
src/pages/fengkong/biz/components/bind.js

@@ -0,0 +1,38 @@
+import React, { Component } from 'react'
+import { Modal } from 'antd'
+import { FormItem } from 'wptpc-design'
+
+export default class Bind extends Component {
+  render () {
+    const { showModal, params, onChange, onOk, onCancel, fetching } = this.props
+    const formSetting = [{
+      label: '分类名称',
+      type: 'input',
+      key: 'name',
+      disabled: true
+    },
+    {
+      label: '分类描述',
+      type: 'textarea',
+      key: 'description',
+      disabled: true
+    },
+    {
+      label: '绑定决策',
+      type: 'input',
+      key: 'bind',
+      placeholder: '多个决策以逗号连接'
+    }]
+    return (
+      <Modal
+        title={'决策绑定'}
+        visible={showModal}
+        onOk={onOk}
+        onCancel={onCancel}
+        okButtonProps={{ disabled: fetching }}
+      >
+        <FormItem formSetting={formSetting} params={params} onChange={onChange}/>
+      </Modal>
+    )
+  }
+}

+ 31 - 0
src/pages/fengkong/biz/components/biz.js

@@ -0,0 +1,31 @@
+import React, { Component } from 'react'
+import { Modal } from 'antd'
+import { FormItem } from 'wptpc-design'
+
+export default class Biz extends Component {
+  render () {
+    const { showModal, params, onChange, onOk, onCancel, fetching } = this.props
+    const formSetting = [{
+      label: '分类名称',
+      type: 'input',
+      key: 'name'
+    },
+    {
+      label: '分类描述',
+      type: 'textarea',
+      key: 'description'
+    }]
+    return (
+      <Modal
+        title={'新建分类'}
+        visible={showModal}
+        onOk={onOk}
+        onCancel={onCancel}
+        okButtonProps={{ disabled: fetching }}
+        destroyOnClose
+      >
+        <FormItem formSetting={formSetting} params={params} onChange={onChange} />
+      </Modal>
+    )
+  }
+}

+ 160 - 0
src/pages/fengkong/biz/index.js

@@ -0,0 +1,160 @@
+import React from 'react'
+import { FilterTable } from 'wptpc-design'
+import { thanos } from '@/conf/config'
+import { Divider, message, Button, Popconfirm } from 'antd'
+import { connect } from 'dva'
+import { create, del, bind as bd } from './service.js'
+import Biz from './components/biz'
+import Bind from './components/bind'
+const apiUrl = `${thanos}/thanos-admin/api/v1/classify/list`
+
+@connect(({ user }) => ({
+  currentUser: user.currentUser
+}))
+class BizList extends React.PureComponent {
+  state = {
+    showModal: false,
+    params: {}
+  }
+
+  filterSetting = {
+    rfBtnsJsx: <Button onClick={() => this.addBiz()}>添加分类</Button>,
+    isClearSearch: true,
+    formFields: [
+      {
+        label: '描述:',
+        type: 'input',
+        key: 'queryName',
+        placeholder: '分类名称'
+      }
+    ]
+  }
+
+  // filtertable的列表配置
+  tableSetting = {
+    rowKey: 'id',
+    pagination: {
+      pageSize: 10
+    },
+    columnConfig: [
+      {
+        title: '名称',
+        dataIndex: 'name',
+        render: (text, record) => (
+          <a href={'/fengkong/strategies/bizBind?binds=' + encodeURIComponent(record.bind) + '&name=' + encodeURIComponent(text)}>
+            {text}
+          </a>
+        )
+      },
+      {
+        title: '描述',
+        dataIndex: 'description'
+      },
+      {
+        title: 'operator',
+        dataIndex: 'operator'
+      },
+      {
+        title: '操作',
+        dataIndex: 'actions',
+        // 所有需要弹窗操作的都可以用编辑的逻辑;所有不需要弹窗的操作,比如上架、发布等,都可以用”删除“的逻辑
+        render: (text, record) => (
+          <span>
+            <a onClick={() => this.bindBiz(record)}>绑定</a>
+            <Divider type="vertical"/>
+            <Popconfirm
+              title="确定删除"
+              onConfirm={() => this.deleteBind(record)}>
+              <a>删除</a>
+            </Popconfirm>
+          </span>)
+      }
+    ],
+    getRefresh: refresh => {
+      this.refresh = refresh
+    }
+  }
+
+  bindBiz (params) {
+    this.setState({ showBindModal: true, params: params })
+  }
+
+  deleteBind (params) {
+    del({ name: params.name }).then(res => {
+      if (res.code === 0) {
+        message.success('删除成功')
+        this.refresh()
+      }
+    })
+  }
+
+  addBiz = () => {
+    this.setState({ showBizModal: true, params: {} })
+  }
+
+  onParamsChange = (key, value) => {
+    const params = { ...this.state.params }
+    params[key] = value
+    this.setState({ params })
+  }
+
+  onBizOk = () => {
+    const { name, description } = this.state.params
+    const m = {
+      name: name,
+      description: description,
+      operator: this.props.currentUser.name
+    }
+    create(m).then(res => {
+      console.log('data:' + JSON.stringify(res))
+      if (res != null && res.code === 0) {
+        message.success('处理成功')
+        this.refresh()// 刷新列表
+        this.onBizCancel()// 关闭弹窗
+      } else {
+        message.error('处理失败: ' + res.msg)
+      }
+    })
+  }
+
+  onBindOk = () => {
+    const { name, description, bind } = this.state.params
+    const m = {
+      name: name,
+      description: description,
+      bind: bind,
+      operator: this.props.currentUser.name
+    }
+    bd(m).then(res => {
+      console.log('data:' + JSON.stringify(res))
+      if (res != null && res.code === 0) {
+        message.success('处理成功')
+        this.refresh()// 刷新列表
+        this.onBindCancel()// 关闭弹窗
+      } else {
+        message.error('处理失败: ' + res.msg)
+      }
+    })
+  }
+
+  onBizCancel = () => {
+    this.setState({ showBizModal: false })
+  }
+
+  onBindCancel = () => {
+    this.setState({ showBindModal: false })
+  }
+
+  render () {
+    const { showBizModal, showBindModal, params } = this.state
+    return (
+      <div>
+        <FilterTable filterSetting={this.filterSetting} tableSetting={this.tableSetting} apiUrl={apiUrl} />
+        <Biz showModal={showBizModal} params={params} onChange={this.onParamsChange} onOk={this.onBizOk} onCancel={this.onBizCancel} />
+        <Bind showModal={showBindModal} params={params} onChange={this.onParamsChange} onOk={this.onBindOk} onCancel={this.onBindCancel} />
+      </div>
+    )
+  }
+}
+
+export default BizList

+ 30 - 0
src/pages/fengkong/biz/service.js

@@ -0,0 +1,30 @@
+import { fetchApi, fetchApi_get as fetchApiGet } from '@/apis/'
+import { thanos } from '@/conf/config'
+
+// 创建业务分类
+export async function create (params) {
+  const url = `${thanos}/thanos-admin/api/v1/classify/create`
+  return fetchApi(url, params)
+}
+
+// 更新模型
+export async function bind (params) {
+  const url = `${thanos}/thanos-admin/api/v1/classify/bind`
+  return fetchApi(url, params)
+}
+
+// 模型删除
+export async function del (params) {
+  const url = `${thanos}/thanos-admin/api/v1/classify/delete`
+  return fetchApiGet(url, params)
+}
+
+export async function back (params) {
+  const url = `${thanos}/thanos-admin/api/v1/model/back`
+  return fetchApi(url, params)
+}
+
+export async function versions (params) {
+  const url = `${thanos}/thanos-admin/api/v1/model/versions`
+  return fetchApi(url, params)
+}

+ 1 - 1
src/pages/fengkong/namelist/blackuserlist/index.js

@@ -31,7 +31,7 @@ class BlackIpList extends React.PureComponent {
   }
 
   filterSetting = {
-    rfBtnsJsx: <div><Button type="primary" onClick={() => this.addBatchItem()}>批量导入</Button><Button type="primary" onClick={() => this.addItem()}>添加用户Id</Button></div>,
+    rfBtnsJsx: <div><Button type="primary" onClick={() => this.addBatchItem()}>批量导入</Button> <Button type="primary" onClick={() => this.addItem()}>添加用户Id</Button></div>,
     isClearSearch: true,
     formFields: [
       {

+ 1 - 1
src/pages/fengkong/namelist/whiteuserlist/index.js

@@ -31,7 +31,7 @@ class BlackIpList extends React.PureComponent {
   }
 
   filterSetting = {
-    rfBtnsJsx: <div><Button type="primary" onClick={() => this.addBatchItem()}>批量导入</Button><Button type="primary" onClick={() => this.addItem()}>添加用户Id</Button></div>,
+    rfBtnsJsx: <div><Button type="primary" onClick={() => this.addBatchItem()}>批量导入</Button> <Button type="primary" onClick={() => this.addItem()}>添加用户Id</Button></div>,
     isClearSearch: true,
     formFields: [
       {

+ 197 - 0
src/pages/fengkong/strategies/bizBind.js

@@ -0,0 +1,197 @@
+import React from 'react'
+import { FilterTable } from 'wptpc-design'
+import { Link } from 'dva/router'
+import { thanos } from '@/conf/config'
+import { Divider, message, Popconfirm } from 'antd'
+import { delItem, unBind } from './service.js'
+import router from 'umi/router'
+
+const apiUrl = `${thanos}/thanos-admin/api/v1/classify/biz/binds`
+
+const parseQueryString = (url) => {
+  // 先将字符串通过 split 方法,以 "?" 为分割符将其分割成数组;
+  // 该数组有两个元素,第一个为空字符串,第二个为 url 参数字符串
+  const arr = url.split('?')
+  if (arr.length === 1) {
+    return null
+  }
+  // 将参数字符串以 "&" 符号为分隔符进行分割
+  const params = arr[1].split('&')
+  // 定义一个数组用于存储参数
+  const obj = {}
+  // 通过循环将参数以键值对的形式存储在变量 obj 中
+  for (let i = 0; i < params.length; i++) {
+    const arrParams = params[i].split('=')
+    obj[arrParams[0]] = arrParams[1]
+  }
+  return obj
+}
+
+class GroupList extends React.PureComponent {
+  state = {
+    showModal: false,
+    params: {},
+    bizName: ''
+  }
+
+  filterSetting = {
+    beforeSearchFunc: params => {
+      params.queryName = decodeURIComponent(parseQueryString(window.location.href).binds)
+    }
+  }
+
+  onParamsChange = (key, value) => {
+    const params = { ...this.state.params }
+    params[key] = value
+    this.setState({ params })
+  }
+
+  // filtertable的列表配置
+  tableSetting = {
+    rowKey: 'id',
+    // isFrontPagination: true,
+    pagination: {
+      pageSize: 10
+    },
+    columnConfig: [
+      // {
+      //   title: 'ID',
+      //   dataIndex: 'id'
+      // },
+      {
+        title: '分组名称',
+        dataIndex: 'name'
+      },
+      {
+        title: '描述',
+        dataIndex: 'description'
+      },
+      {
+        title: '类型',
+        dataIndex: 'type',
+        render: (text) => {
+          if (text === 0) {
+            return '策略'
+          }
+          if (text === 1) {
+            return '流程'
+          }
+          if (text === 2) {
+            return '模型'
+          }
+          if (text === 3) {
+            return '调度'
+          }
+          if (text === 4) {
+            return '规则'
+          }
+        }
+      },
+      {
+        title: '决策是否启用',
+        dataIndex: 'enabled',
+        render: (text) => text === true ? '是' : '否'
+      },
+      {
+        title: '创建人',
+        dataIndex: 'createUser'
+      },
+      {
+        title: '修改人',
+        dataIndex: 'updateUser'
+      },
+      {
+        title: '操作',
+        dataIndex: 'actions',
+        // 所有需要弹窗操作的都可以用编辑的逻辑;所有不需要弹窗的操作,比如上架、发布等,都可以用”删除“的逻辑
+        render: (text, record) => (
+          <span>
+            <Link
+              to={{
+                pathname: './note/' + record.name,
+                state: record
+              }}
+            >记录</Link>
+            <Divider type="vertical"/>
+            <Link
+              to={{
+                pathname: './edit/' + record.name,
+                state: record
+              }}
+            >编辑</Link>
+            <Divider type="vertical"/>
+            <Popconfirm
+              title="确定删除"
+              onConfirm={() => this.delItem(record)}>
+              <a>删除</a>
+            </Popconfirm>
+            <Divider type="vertical"/>
+            <Popconfirm
+              title="确定解绑"
+              onConfirm={() => this.unBind(record)}>
+              <a>解绑</a>
+            </Popconfirm>
+          </span>)
+      }
+    ],
+    getRefresh: refresh => {
+      this.refresh = refresh
+    }
+  }
+
+  // 点击编辑按钮时的事件处理函数
+  editItem (record) {
+    // const fields = JSON.parse(record.fieldsJson)
+    // console.log('=====', fields)
+    const { fields } = record
+    const fieldsJson = Object.keys(fields).map(f => ({
+      key: f,
+      desc: fields[f].desc,
+      column: fields[f].column
+    }))
+    console.log(fieldsJson)
+    this.setState({
+      showModal: true,
+      params: {
+        ...record,
+        fieldsJson
+      }
+    })
+  }
+
+  // 点击删除按钮时的事件处理函数
+  delItem = (record) => {
+    delItem({ id: record.id, name: record.name }).then(res => {
+      if (res.code === 0) {
+        message.success('删除成功')
+        this.refresh()
+      }
+    })
+  }
+
+  // 点击解绑按钮时的事件处理函数
+  unBind = (record) => {
+    unBind({ bizName: this.state.bizName, name: record.name }).then(res => {
+      if (res.code === 0) {
+        message.success('解绑成功')
+        router.push('/fengkong/strategies/bizBind?binds=' + encodeURIComponent(res.data.bind) + '&name=' + encodeURIComponent(this.state.bizName))
+        this.refresh()
+      }
+    })
+  }
+
+  render () {
+    const encodeName = parseQueryString(window.location.href).name
+    const name = decodeURIComponent(encodeName)
+    this.setState({ bizName: name })
+    return (
+      <div>
+        <p style={{ margin: '5px 10px' }}>{name}:</p>
+        <FilterTable filterSetting={this.filterSetting} tableSetting={this.tableSetting} apiUrl={apiUrl}
+        />
+      </div>
+    )
+  }
+}
+
+export default GroupList

+ 37 - 4
src/pages/fengkong/strategies/edit/$name.js

@@ -2,11 +2,12 @@ import React from 'react'
 import { Form, Input, Row, Col, Switch, Button, Modal, message, Select, Icon } from 'antd'
 import { connect } from 'dva'
 import AceEditor from 'react-ace'
-import { detail, test, update, groupList } from '../service'
+import {detail, test, update, groupList, createNote } from '../service'
 import { isJSON } from '@/utils/utils'
 
 import 'ace-builds/src-noconflict/mode-java'
 import 'ace-builds/src-noconflict/theme-monokai'
+import Nt from '@/pages/fengkong/strategies/note/note'
 
 const formItemLayout = {
   layout: 'vertical'
@@ -52,6 +53,38 @@ class Add extends React.PureComponent {
     })
   }
 
+  onNoteOk = () => {
+    const { content } = this.state.params
+    if (!content) {
+      message.warn('内容不能为空!')
+      return false
+    }
+    createNote({ name: this.props.match.params.name, content: content, operator: this.props.currentUser.name }).then(res => {
+      console.log('数据: ' + JSON.stringify(res))
+      if (res.data != null && res.code === 0) {
+        message.success('处理成功')
+        this.onNoteCancel()// 关闭弹窗
+        this.create()
+      } else {
+        message.error('处理失败: ' + res.msg)
+      }
+    })
+  }
+
+  onNoteCancel = () => {
+    this.setState({ showNote: false })
+  }
+
+  noteAndCreate = () => {
+    this.setState({ showNote: true, params: {} })
+  }
+
+  onParamsChange = (key, value) => {
+    const params = { ...this.state.params }
+    params[key] = value
+    this.setState({ params })
+  }
+
   create = () => {
     this.props.form.validateFields((err, values) => {
       if (!err) {
@@ -129,7 +162,7 @@ class Add extends React.PureComponent {
 
   render () {
     const { getFieldDecorator } = this.props.form
-    const { name, description, enabled, content } = this.state
+    const { name, description, enabled, content, params, showNote } = this.state
     return (
       <div>
         <h1>编辑决策</h1>
@@ -255,7 +288,7 @@ class Add extends React.PureComponent {
                 )
               }
               <Form.Item>
-                <Button type="primary" onClick={this.create}>提交</Button>&emsp;
+                <Button type="primary" onClick={this.noteAndCreate}>提交</Button>&emsp;
                 <Button onClick={() => this.setState({ showTest: true })}>测试</Button>
               </Form.Item>
             </Form>
@@ -306,7 +339,7 @@ class Add extends React.PureComponent {
 
           </Col>
         </Row>
-
+        <Nt showModal={showNote} params={params} onChange={this.onParamsChange} onOk={this.onNoteOk} onCancel={this.onNoteCancel} />
       </div>
     )
   }

+ 69 - 0
src/pages/fengkong/strategies/note/$name.js

@@ -0,0 +1,69 @@
+import React from 'react'
+import { connect } from 'dva'
+import { message, Table } from 'antd'
+import { queryNote } from '@/pages/fengkong/strategies/service'
+
+@connect(({ user }) => ({
+  currentUser: user.currentUser
+}))
+
+class NoteRecord extends React.PureComponent {
+  constructor () {
+    super()
+    this.state = {
+      dataSource: []
+    }
+  }
+
+  componentDidMount () {
+    queryNote({ name: this.props.match.params.name }).then(res => {
+      if (res.data != null && res.code === 0) {
+        this.setState({ dataSource: res.data })
+        message.success('处理成功')
+      } else {
+        message.error('处理失败: ' + res.msg)
+      }
+    })
+  }
+
+  render () {
+    let dataSource = []
+    if (this.state.dataSource.length > 0) {
+      dataSource = this.state.dataSource
+    }
+    const columns = [
+      {
+        title: '名称',
+        key: 'name',
+        dataIndex: 'name'
+      },
+      {
+        title: '变更记录',
+        key: 'content',
+        dataIndex: 'content'
+      },
+      {
+        title: 'operator',
+        key: 'operator',
+        dataIndex: 'operator'
+      },
+      {
+        title: '时间',
+        key: 'createTime',
+        dataIndex: 'createTime'
+      }
+    ]
+
+    return (
+      <div>
+        <Table
+          dataSource={dataSource}
+          columns={columns}
+          size="small"
+        />
+      </div>
+    )
+  }
+}
+
+export default NoteRecord

+ 28 - 0
src/pages/fengkong/strategies/note/note.js

@@ -0,0 +1,28 @@
+import React, { Component } from 'react'
+import { Modal } from 'antd'
+import { FormItem } from 'wptpc-design'
+
+export default class Note extends Component {
+  render () {
+    console.log('props:' + JSON.stringify(this.props))
+    const { showModal, params, onChange, onOk, onCancel, fetching } = this.props
+    const formSetting = [
+      {
+        label: '修改内容',
+        type: 'textarea',
+        key: 'content'
+      }
+    ]
+    return (
+      <Modal
+        title={'请填写本次修改记录'}
+        visible={showModal}
+        onOk={onOk}
+        onCancel={onCancel}
+        okButtonProps={{ disabled: fetching }}
+      >
+        <FormItem formSetting={formSetting} params={params} onChange={onChange}/>
+      </Modal>
+    )
+  }
+}

+ 15 - 0
src/pages/fengkong/strategies/service.js

@@ -1,6 +1,21 @@
 import { fetchApi, fetchApi_get as fetchApiGet } from '@/apis/'
 import { thanos } from '@/conf/config'
 
+export async function unBind (params) {
+  const url = `${thanos}/thanos-admin/api/v1/classify/unbind`
+  return fetchApiGet(url, params)
+}
+
+export function queryNote (params) {
+  const url = `${thanos}/thanos-admin/api/v1/notes/query`
+  return fetchApiGet(url, params)
+}
+
+export function createNote (params) {
+  const url = `${thanos}/thanos-admin/api/v1/notes/create`
+  return fetchApi(url, params)
+}
+
 // 新增策略
 export async function create (params) {
   const url = `${thanos}/thanos-admin/api/v1/dsl/create`

+ 7 - 0
src/pages/fengkong/strategies/strategies.js

@@ -139,6 +139,13 @@ class GroupList extends React.PureComponent {
         // 所有需要弹窗操作的都可以用编辑的逻辑;所有不需要弹窗的操作,比如上架、发布等,都可以用”删除“的逻辑
         render: (text, record) => (
           <span>
+            <Link
+              to={{
+                pathname: './note/' + record.name,
+                state: record
+              }}
+            >记录</Link>
+            <Divider type="vertical"/>
             <Link
               to={{
                 pathname: './edit/' + record.name,