王文博 5 yıl önce
ebeveyn
işleme
4c0561966c

+ 2 - 2
src/layouts/mainLayout/index.js

@@ -88,8 +88,8 @@ export default class MainLayout extends React.PureComponent {
                   </span>}>
                 <Menu.Item key="/dc/data" onClick={() => { router.push('/dc/data') }}>UA数据管理</Menu.Item>
                 <Menu.Item key="/dc/list" onClick={() => { router.push('/dc/list') }}>UA数据报表</Menu.Item>
-                <Menu.Item key="/dc/sub-rule"  onClick={() => { router.push('/dc/subscribe/rule') }}>订阅数据管理</Menu.Item>
-                <Menu.Item key="/dc/sub-job"  onClick={() => { router.push('/dc/subscribe/job')}}>订阅数据报表</Menu.Item>
+                <Menu.Item key="/dc/subscribe/data"  onClick={() => { router.push('/dc/subscribe/data') }}>订阅数据管理</Menu.Item>
+                <Menu.Item key="/dc/subscribe"  onClick={() => { router.push('/dc/subscribe/job')}}>订阅数据报表</Menu.Item>
               </SubMenu>
             </Menu>
           </Sider>

+ 142 - 0
src/pages/dc/subscribe/components/Edit/index.js

@@ -0,0 +1,142 @@
+import React, { Component } from 'react'
+import { Modal, Input, Icon, Select, Radio } from 'antd'
+import { FormItem } from 'wptpc-design'
+import s from './index.less'
+import CheckBox from 'rc-checkbox'
+
+export default class Index extends Component {
+  constructor (props) {
+    super(props)
+    this.state = {
+      params: {}
+    }
+    this.formSetting = [
+    //   {
+    //   label: '规则名',
+    //   type: 'input',
+    //   key: 'rule',
+    //   isRequired: true,
+    //   placeholder: '请输入'
+    // },
+    // {
+    //   label: '接口名',
+    //   type: 'input',
+    //   key: 'url',
+    //   isRequired: true,
+    //   placeholder: '请输入'
+    // },
+    // {
+    //   label: '状态',
+    //   type: 'select',
+    //   key: 'status',
+    //   options: [
+    //     { value: 1, label: '可运行' },
+    //     { value: 2, label: '停止' }
+    //   ],
+    //   style: { width: '100%' },
+    //   isRequired: true,
+    //   placeholder: '请输入'
+    // }, {
+    //   label: '描述',
+    //   type: 'input',
+    //   key: 'desc',
+    //   isRequired: true,
+    //   placeholder: '请输入'
+    // },
+    {
+      label: 'JSON',
+      render: () => {
+        const { fieldsJson } = this.state.params
+        return <div>
+          <div><Icon type="plus" onClick={() => {
+            fieldsJson.push({})
+            this.onParamsChange('fieldsJson', fieldsJson)
+          }}/></div>
+          <div className={s.spanMargin}>
+            <span>* 订阅描述</span>
+            <span>* 查询名</span>
+            <span>* 唯一标识</span>
+            <span>* 返回数据字段</span>
+            <span>* 订阅类型</span>
+            <span>* 缓存类型-天</span>
+            <span>* 缓存类型-小时</span>
+          </div>
+          <div>
+            {fieldsJson.map((f, index) => <div>
+              <Input value={f.key} onChange={(e) => {
+                fieldsJson[index].key = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <Input value={f.description} onChange={(e) => {
+                fieldsJson[index].description = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <Input value={f.name} onChange={(e) => {
+                fieldsJson[index].name = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <Input value={f.uniqueId} onChange={(e) => {
+                fieldsJson[index].uniqueId = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <Input value={f.fields} onChange={(e) => {
+                fieldsJson[index].fields = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <Select style={{width:130}}>
+                <Select.Option value="1" selected>自增</Select.Option>
+                <Select.Option value="1">变量增加</Select.Option>
+              </Select>
+              <Input value={f.type} onChange={(e) => {
+                fieldsJson[index].type = e.target.value
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} style={{ width: 130, marginRight: 10 }}/>
+              <CheckBox>按天缓存</CheckBox>
+              <CheckBox>按小时缓存</CheckBox>
+              <Icon onClick={(e) => {
+                fieldsJson.splice(index, 1)
+                this.onParamsChange('fieldsJson', fieldsJson)
+              }} type="close"/></div>)}
+          </div>
+        </div>
+      }
+    }]
+  }
+
+  // 组件挂在的时候调用的生命周期函数
+  componentDidMount () {
+    const params = { ...this.props.params }
+    this.setState({ params })
+  }
+
+  onOk = () => {
+    const params = { ...this.state.params }
+    this.props.onOk(params)
+  }
+
+  // 表单里面的控件修改的时候出发onchange事件
+  onParamsChange = (key, value) => {
+    const params = { ...this.state.params }
+    params[key] = value
+    this.setState({ params })
+  }
+
+  render () {
+    const { showModal, onCancel, loading } = this.props
+    const { params } = this.state
+
+    return (
+      <Modal
+        title={params.id ? '编辑' : '创建'}
+        visible={showModal}
+        onOk={this.onOk}
+        onCancel={onCancel}
+        // 确认按钮点击后,发起接口会处罚loading值的变化,从而控制确认按钮的状态(disable or enable)
+        okButtonProps={{ disabled: loading }}
+        width={1800}
+      >
+        <FormItem formSetting={this.formSetting} params={params} onChange={this.onParamsChange} />
+      </Modal>
+    )
+  }
+}

+ 7 - 0
src/pages/dc/subscribe/components/Edit/index.less

@@ -0,0 +1,7 @@
+.spanMargin > span {
+    display: inline-flex;;
+    width: 175px;
+    font-weight: bold;
+    text-align: center;
+  }
+  

+ 248 - 0
src/pages/dc/subscribe/data.js

@@ -0,0 +1,248 @@
+import React from 'react'
+import { connect } from 'dva'
+import { Divider, message, Popconfirm } from 'antd'
+import { FilterTable } from 'wptpc-design'
+import s from './data.less'
+import Edit from './components/Edit'
+import { dc } from '@/conf/config'
+
+const apiUrl = `${dc}/dc/web/get-sub-rule-list`
+
+@connect(({ loading }) => ({
+  // 添加或者编辑接口触发的loading属性,可以用于控制接口请求阶段让对话框的”确定“按钮不可点击
+  actionLoading: loading.effects['template/_addItem'] || loading.effects['ugc/_editItem']
+}))
+class Index extends React.PureComponent {
+  state = {
+    // 这两个state字段用来进行表单显示、隐藏控制以及表单里面的数据
+    showModal: false,
+    params: {}
+  }
+
+  // filtertable的搜索项配置
+  filterSetting = {
+    isClearSearch: true,
+    // 这个数组里面的每一个元素就是一个搜索项
+    formFields: [
+      // { label: '账户ID:', type: 'input', key: 'developerId', placeholder: '请输入账户ID' },
+      // {
+      //   label: '性别:',
+      //   type: 'select',
+      //   option: [
+      //     { value: '0', label: '不限' },
+      //     { value: '1', label: '男' },
+      //     { value: '2', label: '女' }
+      //   ],
+      //   key: 'sex'
+      // },
+      // { label: '出生日期:', type: 'datePicker', key: 'date' }
+    ],
+    // 在接口请求前,可以修改给接口的入参
+    beforeSearchFunc: params => {
+      params.pageSize = params.pageNum
+    }
+  }
+
+  // filtertable的列表配置
+  tableSetting = {
+    rowKey: 'id',
+    pagination: {
+      pageSize: 10
+    },
+    columnConfig: [
+      {
+        title: '序号',
+        dataIndex: 'id'
+      },
+      {
+        title: '订阅描述',
+        dataIndex: 'description'
+      },
+      {
+        title: '订阅主题',
+        dataIndex: 'topic'
+      },
+      {
+        title: '回调地址',
+        dataIndex: 'url'
+      },
+      {
+        title:'订阅数据库',
+        dataIndex:'subDb'
+      },
+      {
+        title:'订阅数据表',
+        dataIndex:'subTable'
+      },
+      {
+        title:'订阅事件',
+        dataIndex:'subEvent'
+      },
+      {
+        title:'订阅字段',
+        dataIndex:'subFields'
+      },
+      {
+        title:'过滤条件',
+        dataIndex:'subFilter'
+      },
+      {
+        title:'回调参数',
+        dataIndex:'params'
+      },
+      {
+        title: '操作',
+        dataIndex: 'actions',
+        // 所有需要弹窗操作的都可以用编辑的逻辑;所有不需要弹窗的操作,比如上架、发布等,都可以用”删除“的逻辑
+        render: (text, record) => <span><a onClick={() => this.editItem(record)}>编辑</a>
+        <Divider type="vertical"/><a onClick={()=> this.editJob(record)}>新增统计任务</a><Divider
+          type="vertical"/><Popconfirm
+          title="确定删除"
+          onConfirm={() => this.delItem(record)}>
+          <a>删除</a>
+        </Popconfirm><Divider type="vertical"/><Popconfirm
+          title="确定执行"
+          onConfirm={() => this.execItem(record)}>
+          <a>执行</a>
+        </Popconfirm></span>
+      }
+    ],
+    // 通过这个函数可以获取列表的刷新的函数,编辑、删除后可以用它来刷新列表
+    getRefresh: refresh => {
+      this.refresh = refresh
+    },
+    // 筛选和列表的中间位置如果有批量操作按钮,可以放在这个位置
+    batchBtns: [
+      {
+        label: '创建',
+        type: 'primary',
+        onClick: () => this.editItem({ fieldsJson: '{}' })
+      }
+    ]
+  }
+
+  // 点击编辑数据统计处理
+  editJob (record) {
+    const fields = JSON.parse(record.fieldsJson)
+    const fieldsJson = Object.keys(fields).map(f => ({
+      key: f,
+      description: fields[f].description,
+      name: fields[f].name,
+      uniqueId: fields[f].uniqueId,
+      fields:fields[f].fields,
+      type:fields[f].type,
+      cacheDay:fields[f].cacheDay,
+      cacheHour:fields[f].cacheHour
+    }))
+    this.setState({
+      showModal: true,
+      params: {
+        ...record,
+        fieldsJson
+      }
+    })
+  }
+  
+
+  // 点击编辑按钮时的事件处理函数
+  editItem (record) {
+    const fields = JSON.parse(record.fieldsJson)
+    const fieldsJson = Object.keys(fields).map(f => ({
+      key: f,
+      desc: fields[f].desc,
+      column: fields[f].column
+    }))
+    this.setState({
+      showModal: true,
+      params: {
+        ...record,
+        fieldsJson
+      }
+    })
+  }
+
+  // 点击删除按钮时的事件处理函数
+  delItem ({ id }) {
+    this.props.dispatch({
+      type: 'template/_delItem',
+      payload: { id },
+      callback: res => {
+        const { code } = res || {}
+        if (code === 0) {
+          message.success('删除成功')
+          this.refresh()
+        }
+      }
+    })
+  }
+
+  execItem ({ id }) {
+    this.props.dispatch({
+      type: 'template/_execItem',
+      payload: { id },
+      callback: res => {
+        const { code } = res || {}
+        if (code === 0) {
+          message.success('执行成功')
+          this.refresh()
+        }
+      }
+    })
+  }
+
+  // 点击新建、编辑对话框的取消按钮的事件处理函数
+  onModalCancel = () => {
+    this.setState({ showModal: false })
+  }
+
+  // 点击新建、编辑对话框的确定按钮的事件处理函数
+  onModalOk = (params) => {
+    // 在触发action调用接口前,可以做一些前端校验工作,比如下面的:
+    // if (!params.developerName) {
+    //   // 如果developerName不存在或者为空字符,那么给用户一个warning提示,同时return阻止后面的接口调用
+    //   message.warning('公司名称必填')
+    //   return
+    // }
+
+    const fieldsJson = params.fieldsJson.reduce((t, { key, desc, column }) => {
+      t[key] = {
+        desc,
+        column
+      }
+      return t
+    }, {})
+    console.log(fieldsJson, 1)
+    params.fieldsJson = JSON.stringify(fieldsJson)
+    console.log(params, 2)
+    const type = !params.id ? 'template/_addItem' : 'template/_editItem'
+    this.props.dispatch({
+      type,
+      payload: params,
+      callback: res => {
+        const { code } = res || {}
+        if (code === 0) {
+          const msg = params.id ? '编辑成功' : '添加成功'
+          message.success(msg)
+          this.setState({ showModal: false })
+          this.refresh()
+        }
+      }
+    })
+  }
+
+  render () {
+    const { showModal, params } = this.state
+    const { actionLoading } = this.props
+
+    return (
+      <div className={s.templatePage}>
+        <FilterTable filterSetting={this.filterSetting} tableSetting={this.tableSetting} apiUrl={apiUrl}
+          isPage={false}/>
+        {showModal && <Edit showModal={showModal} params={params} onCancel={this.onModalCancel} onOk={this.onModalOk}
+          loading={actionLoading}/>}
+      </div>
+    )
+  }
+}
+
+export default Index

+ 2 - 0
src/pages/dc/subscribe/data.less

@@ -0,0 +1,2 @@
+.templatePage {
+}

+ 136 - 0
src/pages/dc/subscribe/index.js

@@ -0,0 +1,136 @@
+import React from 'react'
+import { connect } from 'dva'
+import { message, Divider, Popconfirm } from 'antd'
+import { FilterTable } from 'wptpc-design'
+import s from './index.less'
+import Edit from './components/Edit'
+const apiUrl = 'tabledata'
+
+@connect(({ loading }) => ({
+  // 添加或者编辑接口触发的loading属性,可以用于控制接口请求阶段让对话框的”确定“按钮不可点击
+  actionLoading: loading.effects['template/_addItem'] || loading.effects['ugc/_editItem']
+}))
+class Index extends React.PureComponent {
+  state = {
+    // 这两个state字段用来进行表单显示、隐藏控制以及表单里面的数据
+    showModal: false,
+    params: {}
+  }
+
+  // filtertable的搜索项配置
+  filterSetting = {
+    isClearSearch: true,
+    // 这个数组里面的每一个元素就是一个搜索项
+    formFields: [ 
+      { label: '账户ID:', type: 'input', key: 'developerId', placeholder: '请输入账户ID' },
+      {
+        label: '性别:',
+        type: 'select',
+        option: [
+          { value: '0', label: '不限' },
+          { value: '1', label: '男' },
+          { value: '2', label: '女' }
+        ],
+        key: 'sex'
+      },
+      { label: '出生日期:', type: 'datePicker', key: 'date' }
+    ],
+    // 在接口请求前,可以修改给接口的入参
+    beforeSearchFunc: params => {
+      params.pageSize = params.pageNum
+    }
+  }
+
+  // filtertable的列表配置
+  tableSetting = {
+    // rowKey: 'id', // 如果使用rowKey,需要每行的数据rowKey对应的值都是唯一的
+    columnConfig: [
+      {
+        title: '创建时间',
+        dataIndex: 'createTime'
+      },
+      { title: '公司名称', dataIndex: 'developerName' },
+      { title: '联系手机', dataIndex: 'contactPhone' },
+      {
+        title: '操作',
+        dataIndex: 'actions',
+        // 所有需要弹窗操作的都可以用编辑的逻辑;所有不需要弹窗的操作,比如上架、发布等,都可以用”删除“的逻辑
+        render: (text, record) => <span><a onClick={() => this.editItem(record)}>编辑</a><Divider type="vertical" /><Popconfirm
+          title="确定删除"
+          onConfirm={() => this.delItem(record)}
+        >
+          <a>删除</a>
+        </Popconfirm></span>
+      }
+    ],
+    // 通过这个函数可以获取列表的刷新的函数,编辑、删除后可以用它来刷新列表
+    getRefresh: refresh => {
+      this.refresh = refresh
+    },
+    // 筛选和列表的中间位置如果有批量操作按钮,可以放在这个位置
+    batchBtns: [{ label: '创建', type: 'primary', onClick: () => this.editItem({}) }]
+  }
+
+  // 点击编辑按钮时的事件处理函数
+  editItem (record) {
+    this.setState({ showModal: true, params: { ...record } })
+  }
+
+  // 点击删除按钮时的事件处理函数
+  delItem ({ id }) {
+    this.props.dispatch({
+      type: 'template/_delItem',
+      payload: { id },
+      callback: res => {
+        const { code } = res || {}
+        if (code === 0) {
+          message.success('删除成功')
+          this.refresh()
+        }
+      }
+    })
+  }
+
+  // 点击新建、编辑对话框的取消按钮的事件处理函数
+  onModalCancel = () => {
+    this.setState({ showModal: false })
+  }
+
+  // 点击新建、编辑对话框的确定按钮的事件处理函数
+  onModalOk = (params) => {
+    // 在触发action调用接口前,可以做一些前端校验工作,比如下面的:
+    if (!params.developerName) {
+      // 如果developerName不存在或者为空字符,那么给用户一个warning提示,同时return阻止后面的接口调用
+      message.warning('公司名称必填');
+      return;
+    }
+    const type = params.id ? 'template/_addItem' : 'template/_editItem'
+    this.props.dispatch({
+      type,
+      payload: params,
+      callback: res => {
+        const { code } = res || {}
+        if (code === 0) {
+          const msg = !params.id ? '编辑用户成功' : '添加用户成功'
+          message.success(msg);
+          this.setState({ showModal: false });
+          this.refresh();
+        }
+      }
+    })
+  }
+
+  render () {
+    const { showModal, params } = this.state
+    const { actionLoading } = this.props
+
+    return (
+      <div className={s.templatePage}>
+        <FilterTable filterSetting={this.filterSetting} tableSetting={this.tableSetting} apiUrl={apiUrl} />
+        { showModal && <Edit showModal={showModal} params={params} onCancel={this.onModalCancel} onOk={this.onModalOk} loading={actionLoading} /> }
+      </div>
+    )
+  }
+}
+
+export default Index

+ 2 - 0
src/pages/dc/subscribe/index.less

@@ -0,0 +1,2 @@
+.templatePage {
+}

+ 17 - 0
src/pages/dc/subscribe/model.js

@@ -0,0 +1,17 @@
+import {
+  addItem
+} from './service'
+
+export default {
+  namespace: 'template',
+  state: {},
+  effects: {
+    * _addItem({ payload, callback }, { call }) {
+      const res = yield call(addItem, payload)
+      if (res) {
+        if (callback) callback(res)
+      }
+    },
+  },
+  reducers: {}
+}

+ 11 - 0
src/pages/dc/subscribe/service.js

@@ -0,0 +1,11 @@
+import { fetchApi } from '@/apis/'
+
+export async function addItem (params) {
+  const url = 'tabledata'
+  return fetchApi(url, params)
+}
+
+export async function testpost (body) {
+  const url = 'tabledata'
+  return fetchApi(url, { method: 'POST', body })
+}