60 changed files with 2556 additions and 731 deletions
			
			
		@ -0,0 +1,59 @@ | 
				
			|||
'use strict'; | 
				
			|||
const moment = require('moment') | 
				
			|||
const request = require('superagent') | 
				
			|||
 | 
				
			|||
function videoList (opts) { | 
				
			|||
    return async function (ctx) { | 
				
			|||
        try { | 
				
			|||
            const { models, } = ctx.fs.dc; | 
				
			|||
            const { app, yingshiTokenRes } = ctx | 
				
			|||
 | 
				
			|||
            let yingshiToken = '' | 
				
			|||
            if (yingshiTokenRes && yingshiTokenRes.token && yingshiTokenRes.expire && moment().isBefore(moment(yingshiTokenRes.expire))) { | 
				
			|||
                yingshiToken = yingshiTokenRes.token | 
				
			|||
            } else { | 
				
			|||
                const tokenRes = await app.fs.yingshiRequest.post(`lapp/token/get`, { | 
				
			|||
                    query: { | 
				
			|||
                        appKey: opts.yingshiKey, | 
				
			|||
                        appSecret: opts.yingshiSecret | 
				
			|||
                    } | 
				
			|||
                }) | 
				
			|||
                if (tokenRes.code == 200 && tokenRes.data) { | 
				
			|||
                    const { accessToken, expireTime } = tokenRes.data | 
				
			|||
 | 
				
			|||
                    ctx.yingshiTokenRes = { | 
				
			|||
                        token: accessToken, | 
				
			|||
                        expire: expireTime | 
				
			|||
                    } | 
				
			|||
                    yingshiToken = accessToken | 
				
			|||
                } else { | 
				
			|||
                    throw '未能获取进行萤石鉴权' | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            const deviceRes = await app.fs.yingshiRequest.post(`lapp/device/list`, { | 
				
			|||
                query: { | 
				
			|||
                    accessToken: yingshiToken, | 
				
			|||
                } | 
				
			|||
            }) | 
				
			|||
 | 
				
			|||
            ctx.status = 200; | 
				
			|||
            ctx.body = (deviceRes.data || []).map(item => { | 
				
			|||
                return { | 
				
			|||
                    ...item, | 
				
			|||
                    token: yingshiToken, | 
				
			|||
                } | 
				
			|||
            }) | 
				
			|||
        } catch (error) { | 
				
			|||
            ctx.fs.logger.error(`path: ${ctx.path}, error: error`); | 
				
			|||
            ctx.status = 400; | 
				
			|||
            ctx.body = { | 
				
			|||
                message: typeof error == 'string' ? error : undefined | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
module.exports = { | 
				
			|||
    videoList | 
				
			|||
}; | 
				
			|||
@ -0,0 +1,65 @@ | 
				
			|||
'use strict'; | 
				
			|||
 | 
				
			|||
async function getDepUsers(ctx) { | 
				
			|||
    try { | 
				
			|||
        const models = ctx.fs.dc.models; | 
				
			|||
        //所有部门
 | 
				
			|||
        const departments = await models.Department.findAll({ | 
				
			|||
            attributes: ['id', 'name', 'dependence'], | 
				
			|||
            order: [['id', 'asc']], | 
				
			|||
            where: { | 
				
			|||
                delete: false, | 
				
			|||
            }, | 
				
			|||
        }) | 
				
			|||
        //所有用户
 | 
				
			|||
        const allusers = await models.User.findAll({ | 
				
			|||
            attributes: ['id', 'name', 'username', 'department_id'], | 
				
			|||
            order: [['id', 'asc']], | 
				
			|||
            where: { | 
				
			|||
                delete: false, | 
				
			|||
            }, | 
				
			|||
        }) | 
				
			|||
        const employees = [...new Set(allusers)] | 
				
			|||
        function collectEmployees(departments, employees) { | 
				
			|||
            const result = []; | 
				
			|||
            const processDepartment = (department) => { | 
				
			|||
                const departmentData = { | 
				
			|||
                    depId: department.id, | 
				
			|||
                    depName: department.name, | 
				
			|||
                    users: [], | 
				
			|||
                    expanded: false, // 初始状态折叠
 | 
				
			|||
                }; | 
				
			|||
                const departmentEmployees = employees.filter(employee => | 
				
			|||
                    //console.log('employee.dataVaules.department_id', employee.department_id)
 | 
				
			|||
                    employee.dataValues.department_id === department.id | 
				
			|||
                ); | 
				
			|||
                departmentData.users.push(...departmentEmployees); | 
				
			|||
                departments.forEach(subDepartment => { | 
				
			|||
                    if (subDepartment.dependence === department.id) { | 
				
			|||
                        const subDepartmentData = processDepartment(subDepartment); | 
				
			|||
                        departmentData.users.push(...subDepartmentData.users); | 
				
			|||
                    } | 
				
			|||
                }); | 
				
			|||
                return departmentData; | 
				
			|||
            }; | 
				
			|||
            departments.forEach(department => { | 
				
			|||
                if (department.dependence === null) { | 
				
			|||
                    const departmentData = processDepartment(department); | 
				
			|||
                    result.push(departmentData); | 
				
			|||
                } | 
				
			|||
            }); | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
        const result = collectEmployees(departments, employees); | 
				
			|||
        ctx.status = 200; | 
				
			|||
        ctx.body = result | 
				
			|||
    } catch (error) { | 
				
			|||
        ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); | 
				
			|||
        ctx.status = 400; | 
				
			|||
        ctx.body = {} | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
module.exports = { | 
				
			|||
    getDepUsers | 
				
			|||
}; | 
				
			|||
@ -1,50 +0,0 @@ | 
				
			|||
'use strict'; | 
				
			|||
 | 
				
			|||
 const request = require('superagent'); | 
				
			|||
const buildUrl = (url,token) => { | 
				
			|||
    let connector = url.indexOf('?') === -1 ? '?' : '&'; | 
				
			|||
    return `${url}${connector}token=${token}`; | 
				
			|||
}; | 
				
			|||
  | 
				
			|||
 function factory(app, router, opts) { | 
				
			|||
     return async function (ctx, next) { | 
				
			|||
          | 
				
			|||
         const token = ctx.fs.api.token; | 
				
			|||
          | 
				
			|||
         //console.log(username,password)
 | 
				
			|||
         const req = { | 
				
			|||
             get: (url, query) => { | 
				
			|||
                 return request | 
				
			|||
                     .get(buildUrl(url,token)) | 
				
			|||
                     .query(query) | 
				
			|||
             }, | 
				
			|||
             post: (url, data, query) => { | 
				
			|||
                 return request | 
				
			|||
                     .post(buildUrl(url,token)) | 
				
			|||
                     .query(query) | 
				
			|||
                     //.set('Content-Type', 'application/json')
 | 
				
			|||
                     .send(data); | 
				
			|||
             }, | 
				
			|||
  | 
				
			|||
             put: (url, data) => { | 
				
			|||
                 return request | 
				
			|||
                     .put(buildUrl(url,token)) | 
				
			|||
                     //.set('Content-Type', 'application/json')
 | 
				
			|||
                     .send(data); | 
				
			|||
             }, | 
				
			|||
  | 
				
			|||
             delete: (url) => { | 
				
			|||
                 return request | 
				
			|||
                     .del(buildUrl(url,token)) | 
				
			|||
             }, | 
				
			|||
         }; | 
				
			|||
  | 
				
			|||
         app.business = app.business || {}; | 
				
			|||
         app.business.request = req; | 
				
			|||
  | 
				
			|||
         await next(); | 
				
			|||
     }; | 
				
			|||
 } | 
				
			|||
  | 
				
			|||
 module.exports = factory; | 
				
			|||
  | 
				
			|||
@ -0,0 +1,67 @@ | 
				
			|||
'use strict'; | 
				
			|||
const request = require('superagent') | 
				
			|||
 | 
				
			|||
class paasRequest { | 
				
			|||
   constructor(root, { query = {} } = {}, option) { | 
				
			|||
      this.root = root; | 
				
			|||
      this.query = query | 
				
			|||
      this.option = option | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   #buildUrl = (url) => { | 
				
			|||
      return `${this.root}/${url}`; | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   #resultHandler = (resolve, reject) => { | 
				
			|||
      return (err, res) => { | 
				
			|||
         if (err) { | 
				
			|||
            reject(err); | 
				
			|||
         } else { | 
				
			|||
            resolve(res[this.option.dataWord]); | 
				
			|||
         } | 
				
			|||
      }; | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   get = (url, { query = {}, header = {} } = {}) => { | 
				
			|||
      return new Promise((resolve, reject) => { | 
				
			|||
         request.get(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject)); | 
				
			|||
      }) | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   post = (url, { data = {}, query = {}, header = {} } = {}) => { | 
				
			|||
      return new Promise((resolve, reject) => { | 
				
			|||
         request.post(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject)); | 
				
			|||
      }) | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   put = (url, { data = {}, header = {}, query = {}, } = {}) => { | 
				
			|||
      return new Promise((resolve, reject) => { | 
				
			|||
         request.put(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject)); | 
				
			|||
      }) | 
				
			|||
   } | 
				
			|||
 | 
				
			|||
   delete = (url, { header = {}, query = {} } = {}) => { | 
				
			|||
      return new Promise((resolve, reject) => { | 
				
			|||
         request.delete(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject)); | 
				
			|||
      }) | 
				
			|||
   } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function factory (app, opts) { | 
				
			|||
   if (opts.pssaRequest) { | 
				
			|||
      try { | 
				
			|||
         for (let r of opts.pssaRequest) { | 
				
			|||
            if (r.name && r.root) { | 
				
			|||
               app.fs[r.name] = new paasRequest(r.root, { ...(r.params || {}) }, { dataWord: r.dataWord || 'body' }) | 
				
			|||
            } else { | 
				
			|||
               throw 'opts.pssaRequest 参数错误!' | 
				
			|||
            } | 
				
			|||
         } | 
				
			|||
      } catch (error) { | 
				
			|||
         console.error(error) | 
				
			|||
         process.exit(-1); | 
				
			|||
      } | 
				
			|||
   } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
module.exports = factory; | 
				
			|||
@ -0,0 +1,40 @@ | 
				
			|||
create table if not exists assess | 
				
			|||
( | 
				
			|||
    id                            serial not null | 
				
			|||
        constraint assess_pk | 
				
			|||
            primary key, | 
				
			|||
    unit                          varchar(64), | 
				
			|||
    month                         timestamp with time zone, | 
				
			|||
    total_points                  double precision, | 
				
			|||
    industry_points               double precision, | 
				
			|||
    industry_out_points           double precision, | 
				
			|||
    plus_or_subtract              double precision, | 
				
			|||
    "industry_deduction_reason "  varchar(1024), | 
				
			|||
    industry_out_deduction_reason varchar(1024), | 
				
			|||
    remark                        varchar(1024) | 
				
			|||
); | 
				
			|||
 | 
				
			|||
comment on table assess is '考核评分'; | 
				
			|||
 | 
				
			|||
comment on column assess.unit is '考核单位'; | 
				
			|||
 | 
				
			|||
comment on column assess.month is '考核月份'; | 
				
			|||
 | 
				
			|||
comment on column assess.total_points is '总分'; | 
				
			|||
 | 
				
			|||
comment on column assess.industry_points is '业内得分'; | 
				
			|||
 | 
				
			|||
comment on column assess.industry_out_points is '业外得分'; | 
				
			|||
 | 
				
			|||
comment on column assess.plus_or_subtract is '加减得分'; | 
				
			|||
 | 
				
			|||
comment on column assess."industry_deduction_reason " is '业内扣分原因 | 
				
			|||
'; | 
				
			|||
 | 
				
			|||
comment on column assess.industry_out_deduction_reason is '业外扣分原因'; | 
				
			|||
 | 
				
			|||
comment on column assess.remark is '备注'; | 
				
			|||
 | 
				
			|||
create unique index if not exists assess_id_uindex | 
				
			|||
    on assess (id); | 
				
			|||
 | 
				
			|||
| 
		 After Width: | Height: | Size: 1.4 MiB  | 
@ -0,0 +1,52 @@ | 
				
			|||
/** | 
				
			|||
 * 萤石视频直播(基于萤石云iframe模式,使用方式简单) | 
				
			|||
 * 官方参考:https://open.ys7.com/console/ezopenIframe.html
 | 
				
			|||
 */ | 
				
			|||
'use strict'; | 
				
			|||
 | 
				
			|||
import React from 'react'; | 
				
			|||
import { connect } from 'react-redux'; | 
				
			|||
 | 
				
			|||
const YSIframePlayer = props => { | 
				
			|||
 | 
				
			|||
    const { containerId, height, width, url, autoplay, audio, videoState, ysToken } = props; | 
				
			|||
    const at = ysToken | 
				
			|||
    if (!url || !at) return null; | 
				
			|||
    const src = `https://open.ys7.com/ezopen/h5/iframe?audio=${audio ? '1' : '0'}&url=${url}&autoplay=${autoplay || 1}&accessToken=${at}` | 
				
			|||
    // const src = `https://open.ys7.com/ezopen/h5/iframe?audio=1&url=${url}&autoplay=${autoplay || 1}&accessToken=${at}`
 | 
				
			|||
    return ( | 
				
			|||
        <div | 
				
			|||
            style={{ position: 'relative', height: '100%', width: '100%' }}> | 
				
			|||
            <iframe | 
				
			|||
                frameBorder="0" | 
				
			|||
                id={containerId || 'myPlayer'} | 
				
			|||
                src={src} | 
				
			|||
                // https://open.ys7.com/doc/zh/book/index/live_proto.html 单个播放器的长宽比例限制最小为{width: 400px;height: 300px;}
 | 
				
			|||
                width={width || 400} | 
				
			|||
                height={height || 300} | 
				
			|||
                allowFullScreen | 
				
			|||
                wmode="transparent" | 
				
			|||
            > | 
				
			|||
            </iframe> | 
				
			|||
            { | 
				
			|||
                videoState && videoState.status == 0 ? | 
				
			|||
                    <div style={{ | 
				
			|||
                        height: width || 300, width: width || 400, position: 'absolute', top: 0, background: '#000', | 
				
			|||
                        display: 'flex', justifyContent: 'center', alignItems: 'center', color: '#fff' | 
				
			|||
                    }}> | 
				
			|||
                        设备中断,正在处理中... | 
				
			|||
                    </div> | 
				
			|||
                    : '' | 
				
			|||
            } | 
				
			|||
        </div> | 
				
			|||
    ) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    const { auth, } = state; | 
				
			|||
    return { | 
				
			|||
        user: auth.user, | 
				
			|||
    }; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
export default connect(mapStateToProps)(YSIframePlayer); | 
				
			|||
@ -0,0 +1,14 @@ | 
				
			|||
import { basicAction } from '@peace/utils' | 
				
			|||
import { ApiTable } from '$utils' | 
				
			|||
 | 
				
			|||
export function getAllDepUsers(query) { | 
				
			|||
    return dispatch => basicAction({ | 
				
			|||
        type: 'get', | 
				
			|||
        dispatch: dispatch, | 
				
			|||
        query: query, | 
				
			|||
        actionType: 'GET_AllDEPUSERS', | 
				
			|||
        url: ApiTable.getAllDepUsers, | 
				
			|||
        msg: { option: '获取部门下的所有员工' },//子部门算在第一级部门下面
 | 
				
			|||
        reducer: { name: 'allDepUsers' } | 
				
			|||
    }); | 
				
			|||
} | 
				
			|||
@ -0,0 +1,108 @@ | 
				
			|||
import React, { useState, useEffect } from 'react'; | 
				
			|||
import { connect } from 'react-redux'; | 
				
			|||
import { Form, Input, Select, DatePicker, InputNumber, Button, Modal } from 'antd'; | 
				
			|||
import { unitList } from '../containers/assess' | 
				
			|||
import { getAssess, delAssess, editAssess } from '../actions/assess'; | 
				
			|||
import moment from 'moment'; | 
				
			|||
 | 
				
			|||
const { Option } = Select; | 
				
			|||
 | 
				
			|||
const AssessModal = ({ editData, check, visible, onCancel, dispatch }) => { | 
				
			|||
    const [form] = Form.useForm(); | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
        <Modal | 
				
			|||
            title="考核评分" | 
				
			|||
            open={visible} | 
				
			|||
            visible={visible} | 
				
			|||
            cancelButtonProps={{ | 
				
			|||
                disabled: check, | 
				
			|||
            }} | 
				
			|||
            onOk={() => { | 
				
			|||
                if (check) { | 
				
			|||
                    return onCancel() | 
				
			|||
                } | 
				
			|||
                form.validateFields().then(values => { | 
				
			|||
                    dispatch(editAssess({ | 
				
			|||
                        ...values, | 
				
			|||
                        month: moment(values.month).format('YYYY-MM-DD'), | 
				
			|||
                        assessId: editData ? editData.id : undefined | 
				
			|||
                    })).then(res => { | 
				
			|||
                        if (res.success) { | 
				
			|||
                            onCancel() | 
				
			|||
                        } | 
				
			|||
                    }) | 
				
			|||
                }) | 
				
			|||
            }} | 
				
			|||
            onCancel={() => { | 
				
			|||
                onCancel() | 
				
			|||
            }} | 
				
			|||
        > | 
				
			|||
            <Form | 
				
			|||
                form={form} | 
				
			|||
                initialValues={editData ? { | 
				
			|||
                    ...editData, | 
				
			|||
                    month: moment(editData.month), | 
				
			|||
                } : {}} | 
				
			|||
                disabled={check} | 
				
			|||
                labelCol={{ | 
				
			|||
                    span: 6, | 
				
			|||
                }} | 
				
			|||
                wrapperCol={{ | 
				
			|||
                    span: 18, | 
				
			|||
                }} | 
				
			|||
            > | 
				
			|||
                <Form.Item name="unit" label="管养责任单位" rules={[{ required: true, message: '请填写' }]}> | 
				
			|||
                    <Select> | 
				
			|||
                        { | 
				
			|||
                            unitList.map(item => ( | 
				
			|||
                                <Option value={item} key={item} /> | 
				
			|||
                            )) | 
				
			|||
                        } | 
				
			|||
                    </Select> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="month" label="考核月份" rules={[{ required: true, message: '请填写' }]}> | 
				
			|||
                    <DatePicker picker="month" /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="totalPoints" label="考核总分" rules={[{ required: true, message: '请填写' }]}> | 
				
			|||
                    <InputNumber step={0.1} precision={1} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="industryPoints" label="内业得分"> | 
				
			|||
                    <InputNumber step={0.1} precision={1} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="industryOutPoints" label="外业得分"> | 
				
			|||
                    <InputNumber step={0.1} precision={1} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="plusOrSubtract" label="加减分"> | 
				
			|||
                    <InputNumber step={0.1} precision={1} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="industryDeductionReason" label="内业扣分原因"> | 
				
			|||
                    <Input.TextArea rows={4} maxLength={1024} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="industryOutDeductionReason" label="外业扣分原因"> | 
				
			|||
                    <Input.TextArea rows={4} maxLength={1024} /> | 
				
			|||
                </Form.Item> | 
				
			|||
 | 
				
			|||
                <Form.Item name="remark" label="备注"> | 
				
			|||
                    <Input.TextArea rows={4} maxLength={1024} /> | 
				
			|||
                </Form.Item> | 
				
			|||
            </Form> | 
				
			|||
        </Modal> | 
				
			|||
    ); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    const { auth, assess } = state | 
				
			|||
    return { | 
				
			|||
        user: auth.user, | 
				
			|||
        assess: assess.data || [] | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(AssessModal); | 
				
			|||
@ -1,24 +1,167 @@ | 
				
			|||
import React, { useState, useEffect } from 'react'; | 
				
			|||
import { connect } from 'react-redux'; | 
				
			|||
import { getAssess, delAssess, editAssess } from '../actions/assess'; | 
				
			|||
import ProTable from '@ant-design/pro-table'; | 
				
			|||
import AssessModal from '../components/assessModal'; | 
				
			|||
import { Form, Space, DatePicker, Button, Select, Popconfirm } from 'antd' | 
				
			|||
import moment from 'moment'; | 
				
			|||
 | 
				
			|||
function Assess () { | 
				
			|||
export const unitList = [ | 
				
			|||
    '县道', | 
				
			|||
    '蒋巷镇', | 
				
			|||
    '三江镇', | 
				
			|||
    '塔城乡', | 
				
			|||
    '泾口乡', | 
				
			|||
    '八一乡', | 
				
			|||
    '冈上镇', | 
				
			|||
    '南新乡', | 
				
			|||
    '富山乡', | 
				
			|||
    '莲塘镇', | 
				
			|||
    '金湖管理处', | 
				
			|||
    '武阳镇', | 
				
			|||
    '向塘镇', | 
				
			|||
    '幽兰镇', | 
				
			|||
    '广福镇', | 
				
			|||
    '塘南镇', | 
				
			|||
    '银三角管委会', | 
				
			|||
    '黄马乡', | 
				
			|||
] | 
				
			|||
function Assess (props) { | 
				
			|||
    const { dispatch, assess } = props; | 
				
			|||
    const [assessModalVisible, setAssessModalVisible] = useState(false); | 
				
			|||
    const [editData, setEditData] = useState(null); | 
				
			|||
    const [query, setQuery] = useState({ page: 1, pageSize: 10 }) | 
				
			|||
    const [loading, setLoading] = useState(false); | 
				
			|||
    const [isCheck, setIsCheck] = useState(false) | 
				
			|||
 | 
				
			|||
    useEffect(() => { | 
				
			|||
 | 
				
			|||
        return () => { | 
				
			|||
        }; | 
				
			|||
        return () => { }; | 
				
			|||
    }, []); | 
				
			|||
 | 
				
			|||
    useEffect(() => { | 
				
			|||
        getData() | 
				
			|||
    }, [query]) | 
				
			|||
 | 
				
			|||
    const getData = () => { | 
				
			|||
        setLoading(true) | 
				
			|||
        dispatch(getAssess(query)).then(res => { | 
				
			|||
            setLoading(false) | 
				
			|||
        }) | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
        <div> | 
				
			|||
            <div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between' }}> | 
				
			|||
                <Form layout="inline" onFinish={(v) => { | 
				
			|||
                    setQuery({ ...query, unit: v.unit, month: v.month ? moment(v.month).format() : undefined }) | 
				
			|||
                }}> | 
				
			|||
                    <Form.Item name="unit" label="责任单位" > | 
				
			|||
                        <Select style={{ width: 200 }} placeholder="全部" allowClear> | 
				
			|||
                            { | 
				
			|||
                                unitList.map(item => ( | 
				
			|||
                                    <Option value={item} key={item} /> | 
				
			|||
                                )) | 
				
			|||
                            } | 
				
			|||
                        </Select> | 
				
			|||
                    </Form.Item> | 
				
			|||
 | 
				
			|||
                    <Form.Item name="month" label="考核月份"> | 
				
			|||
                        <DatePicker picker="month" style={{ width: 200 }} /> | 
				
			|||
                    </Form.Item> | 
				
			|||
 | 
				
			|||
                    <Form.Item> | 
				
			|||
                        <Button type="primary" htmlType="submit">搜索</Button> | 
				
			|||
                    </Form.Item> | 
				
			|||
                </Form> | 
				
			|||
 | 
				
			|||
                <Button type="primary" onClick={() => { | 
				
			|||
                    setAssessModalVisible(true) | 
				
			|||
                }}>新增</Button> | 
				
			|||
            </div> | 
				
			|||
            <ProTable | 
				
			|||
                columns={[{ | 
				
			|||
                    title: '责任单位', | 
				
			|||
                    dataIndex: 'unit', | 
				
			|||
                    key: 'unit', | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                    title: '考核月份', | 
				
			|||
                    dataIndex: 'month', | 
				
			|||
                    key: 'month', | 
				
			|||
                    render: (text, record) => ( | 
				
			|||
                        text ? moment(record.month).format('YYYY-MM') : '' | 
				
			|||
                    ) | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                    title: '考核得分', | 
				
			|||
                    dataIndex: 'totalPoints', | 
				
			|||
                    key: 'totalPoints', | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                    title: '操作', | 
				
			|||
                    key: 'action', | 
				
			|||
                    render: (text, record) => ( | 
				
			|||
                        <span> | 
				
			|||
                            <Button type="link" onClick={() => { | 
				
			|||
                                setAssessModalVisible(true) | 
				
			|||
                                setEditData(record) | 
				
			|||
                                setIsCheck(true) | 
				
			|||
                            }}>详情</Button> | 
				
			|||
                            <Button type="link" onClick={() => { | 
				
			|||
                                setAssessModalVisible(true) | 
				
			|||
                                setEditData(record) | 
				
			|||
                            }}>编辑</Button> | 
				
			|||
                            <Popconfirm | 
				
			|||
                                title="确定删除此条数据吗?" | 
				
			|||
                                onConfirm={() => { | 
				
			|||
                                    setLoading(true) | 
				
			|||
                                    dispatch(delAssess({ id: record.id })).then(res => { | 
				
			|||
                                        setLoading(false) | 
				
			|||
                                        if (res.success) { | 
				
			|||
                                            getData() | 
				
			|||
                                        } | 
				
			|||
                                    }) | 
				
			|||
                                }} | 
				
			|||
                            > | 
				
			|||
                                <Button type="link" danger>删除</Button> | 
				
			|||
                            </Popconfirm> | 
				
			|||
                        </span> | 
				
			|||
                    ), | 
				
			|||
                },]} | 
				
			|||
                dataSource={assess.rows || []} | 
				
			|||
                loading={loading} | 
				
			|||
                pagination={{ | 
				
			|||
                    total: assess?.count || 0, | 
				
			|||
                    pageSize: 10, | 
				
			|||
                    defaultPageSize: 10, | 
				
			|||
                    showSizeChanger: false, | 
				
			|||
                    onChange: (page, pageSize) => { | 
				
			|||
                        setQuery({ | 
				
			|||
                            ...query, | 
				
			|||
                            page, limit: pageSize | 
				
			|||
                        }) | 
				
			|||
                    } | 
				
			|||
                }} | 
				
			|||
                rowKey="key" | 
				
			|||
                toolBarRender={false} | 
				
			|||
                search={false} | 
				
			|||
            /> | 
				
			|||
            { | 
				
			|||
                assessModalVisible ? <AssessModal check={isCheck} visible={assessModalVisible} editData={editData} onCancel={() => { | 
				
			|||
                    getData() | 
				
			|||
                    setIsCheck(false) | 
				
			|||
                    setEditData(null) | 
				
			|||
                    setAssessModalVisible(false) | 
				
			|||
                }} /> : '' | 
				
			|||
            } | 
				
			|||
        </div> | 
				
			|||
    ); | 
				
			|||
} | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    const { auth } = state | 
				
			|||
    const { auth, assess } = state | 
				
			|||
    return { | 
				
			|||
        user: auth.user, | 
				
			|||
        assess: assess.data || [], | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(Assess); | 
				
			|||
@ -0,0 +1,41 @@ | 
				
			|||
'use strict'; | 
				
			|||
 | 
				
			|||
import React, { useState, useEffect } from 'react'; | 
				
			|||
import { connect } from 'react-redux'; | 
				
			|||
// import { Spin, Button, Popconfirm } from 'antd';
 | 
				
			|||
// import ProTable from '@ant-design/pro-table';
 | 
				
			|||
// //import './protable.less'
 | 
				
			|||
import moment from 'moment'; | 
				
			|||
// import { getRoadway, getProject, delRoadway, delProject } from "../actions/infor"
 | 
				
			|||
// import UserModal from './infor/details';
 | 
				
			|||
// import ProjectModal from './project/project';
 | 
				
			|||
 | 
				
			|||
const Building = (props) => { | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
        <div> | 
				
			|||
            hha | 
				
			|||
        </div> | 
				
			|||
    ) | 
				
			|||
} | 
				
			|||
function mapStateToProps(state) { | 
				
			|||
    const { auth, depMessage } = state; | 
				
			|||
    // const pakData = (dep) => {
 | 
				
			|||
    //     return dep.map((d) => {
 | 
				
			|||
    //         return {
 | 
				
			|||
    //             title: d.name,
 | 
				
			|||
    //             value: d.id,
 | 
				
			|||
    //             // children: d.type >= 2 ? [] : pakData(d.subordinate)
 | 
				
			|||
    //             children: pakData(d.subordinate)
 | 
				
			|||
    //         }
 | 
				
			|||
    //     })
 | 
				
			|||
    // }
 | 
				
			|||
    // let depData = pakData(depMessage.data || [])
 | 
				
			|||
    return { | 
				
			|||
        user: auth.user, | 
				
			|||
        // depMessage: depMessage.data || [],
 | 
				
			|||
        // depLoading: depMessage.isRequesting,
 | 
				
			|||
        // depData,
 | 
				
			|||
    }; | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(Building); | 
				
			|||
@ -0,0 +1,30 @@ | 
				
			|||
import React, { useState, useEffect } from 'react'; | 
				
			|||
import { connect } from 'react-redux'; | 
				
			|||
import { getAssess, delAssess, editAssess } from '../actions/assess'; | 
				
			|||
import ProTable from '@ant-design/pro-table'; | 
				
			|||
import AssessModal from '../components/assessModal'; | 
				
			|||
import { Form, Space, DatePicker, Button, Select, Popconfirm } from 'antd' | 
				
			|||
import moment from 'moment'; | 
				
			|||
 | 
				
			|||
function VideoCenter (props) { | 
				
			|||
    const { dispatch, vcmpWebUrl, vcmpMirrorId } = props; | 
				
			|||
 | 
				
			|||
    useEffect(() => { | 
				
			|||
        return () => { }; | 
				
			|||
    }, []); | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
        <div> | 
				
			|||
            <iframe  src={`${vcmpWebUrl}/callService?mid=${vcmpMirrorId}`}  style={{ height: 'calc(100vh - 142px)', width: '100%', display: 'block' }} frameBorder={0}></iframe> | 
				
			|||
        </div> | 
				
			|||
    ); | 
				
			|||
} | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    const { auth, global } = state | 
				
			|||
    return { | 
				
			|||
        user: auth.user, | 
				
			|||
        vcmpWebUrl: global.vcmpWebUrl, | 
				
			|||
        vcmpMirrorId: global.vcmpMirrorId, | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(VideoCenter); | 
				
			|||
@ -1,19 +1,30 @@ | 
				
			|||
import React from 'react' | 
				
			|||
import React, { useEffect, useState } from 'react' | 
				
			|||
import Left from './left' | 
				
			|||
import Right from './right' | 
				
			|||
import CenterLeft from "./centerLeft" | 
				
			|||
import Centerright from "./centerRight" | 
				
			|||
import { connect } from 'react-redux' | 
				
			|||
import { getNearestAssessData, getVideoCenterList } from "../../../actions/example" | 
				
			|||
 | 
				
			|||
const Leadership = (props) => { | 
				
			|||
    const { dispatch } = props | 
				
			|||
 | 
				
			|||
    useEffect(() => { | 
				
			|||
        dispatch(getVideoCenterList()) | 
				
			|||
    }, []) | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
        <> | 
				
			|||
            <Left dispatch={dispatch} /> | 
				
			|||
            <CenterLeft dispatch={dispatch} /> | 
				
			|||
            <Right dispatch={dispatch} /> | 
				
			|||
            {/* <Centerright /> */} | 
				
			|||
 | 
				
			|||
        </> | 
				
			|||
    ) | 
				
			|||
} | 
				
			|||
export default Leadership | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    return { | 
				
			|||
 | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(Leadership) | 
				
			|||
@ -0,0 +1,202 @@ | 
				
			|||
import React, { Component } from 'react'; | 
				
			|||
import './left.less'; | 
				
			|||
import { connect } from 'react-redux' | 
				
			|||
import { YSIframePlayer } from '../../../../../../components' | 
				
			|||
 | 
				
			|||
class ReactCarousel extends Component { | 
				
			|||
    chunk (arr, size) { | 
				
			|||
        var arr1 = new Array(); | 
				
			|||
        for (var i = 0; i < Math.ceil(arr.length / size); i++) { | 
				
			|||
            arr1[i] = new Array(); | 
				
			|||
        } | 
				
			|||
        var j = 0; | 
				
			|||
        var x = 0; | 
				
			|||
        for (var i = 0; i < arr.length; i++) { | 
				
			|||
            if (!((i % size == 0) && (i != 0))) { | 
				
			|||
                arr1[j][x] = arr[i]; | 
				
			|||
                x++; | 
				
			|||
            } else { | 
				
			|||
                j++; | 
				
			|||
                x = 0; | 
				
			|||
                arr1[j][x] = arr[i]; | 
				
			|||
                x++; | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
        return arr1; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    constructor() { | 
				
			|||
        super(); | 
				
			|||
        this.state = { | 
				
			|||
            imgs: [], | 
				
			|||
            showIndex: 0, //显示第几个图片
 | 
				
			|||
            timer: null,  // 定时器
 | 
				
			|||
            show: false,   // 前后按钮显示
 | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    renderVideo = (item, index) => { | 
				
			|||
        return <YSIframePlayer | 
				
			|||
            containerId={`yingshiPlay_lu_${index}`} | 
				
			|||
            height='100%' | 
				
			|||
            width="100%" | 
				
			|||
            url={`ezopen://open.ys7.com/${item.deviceSerial}/${item.channelNo || '1'}.live`} | 
				
			|||
            audio="0" | 
				
			|||
            ysToken={item.token} | 
				
			|||
            videoState={{ | 
				
			|||
                status: item.status | 
				
			|||
            }} | 
				
			|||
        /> | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    render () { | 
				
			|||
        console.log(this.props); | 
				
			|||
        const { imgs } = this.state | 
				
			|||
        return ( | 
				
			|||
            <div className="ReactCarousel" style={{ width: "100%", height: "100%" }}> | 
				
			|||
                <div className="contain" | 
				
			|||
                    onMouseEnter={() => { this.stop() }} //鼠标进入停止自动播放
 | 
				
			|||
                    onMouseLeave={() => { this.start() }}  //鼠标退出自动播放
 | 
				
			|||
                > | 
				
			|||
                    <ul className="ul"> | 
				
			|||
                        { | 
				
			|||
                            this.state.imgs.map((value, index) => { | 
				
			|||
                                return ( | 
				
			|||
                                    <li style={{ position: "relative", left: "8%", width: "100%", height: "100%", top: "-5%", fontSize: "12px" }} className={index === this.state.showIndex ? 'show' : ''} | 
				
			|||
                                        key={index} | 
				
			|||
                                    > | 
				
			|||
                                        { | 
				
			|||
                                            imgs.map((value, index) => { | 
				
			|||
                                                if (index == 0) { | 
				
			|||
                                                    return value?.deviceSerial ? <div style={{ width: "45%", height: "40%", backgroundSize: 'cover', position: "absolute", left: "-3%", top: "5%" }}> | 
				
			|||
                                                        {this.renderVideo(value, index)} | 
				
			|||
                                                        <div style={{ width: "100%", height: "100%", position: "absolute", top: "80%" }}> | 
				
			|||
                                                            <div style={{ width: "100%", height: "20%", backgroundColor: "rgba(0,0,0,0.6)", overflow: "hiddden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}> | 
				
			|||
                                                                <img src='/assets/images/leadership/weizhis.png' style={{ width: "6%", height: "80%", marginLeft: "3%", marginRight: "3%" }} /> | 
				
			|||
                                                                {value?.deviceName} | 
				
			|||
                                                            </div> | 
				
			|||
                                                        </div> | 
				
			|||
                                                    </div> : '' | 
				
			|||
                                                } else if (index == 1) { | 
				
			|||
                                                    return value?.deviceSerial ? <div style={{ width: "45%", height: "40%", backgroundSize: 'cover', position: "absolute", left: "45%", top: "5%" }}> | 
				
			|||
                                                        {this.renderVideo(value, index)} | 
				
			|||
                                                        <div style={{ width: "100%", height: "100%", position: "absolute", top: "80%" }}> | 
				
			|||
                                                            <div style={{ width: "100%", height: "20%", backgroundColor: "rgba(0,0,0,0.6)", overflow: "hiddden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}> | 
				
			|||
                                                                <img src='/assets/images/leadership/weizhis.png' style={{ width: "6%", height: "80%", marginLeft: "3%", marginRight: "3%" }} /> | 
				
			|||
                                                                {value?.deviceName} | 
				
			|||
                                                            </div> | 
				
			|||
                                                        </div> | 
				
			|||
                                                    </div> : "" | 
				
			|||
                                                } else if (index == 2) { | 
				
			|||
                                                    return value?.deviceSerial ? <div style={{ width: "45%", height: "40%", backgroundSize: 'cover', position: "absolute", left: "-3%", top: "49%" }}> | 
				
			|||
                                                        {this.renderVideo(value, index)} | 
				
			|||
                                                        <div style={{ width: "100%", height: "100%", position: "absolute", top: "80%" }}> | 
				
			|||
                                                            <div style={{ width: "100%", height: "20%", backgroundColor: "rgba(0,0,0,0.6)", overflow: "hiddden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}> | 
				
			|||
                                                                <img src='/assets/images/leadership/weizhis.png' style={{ width: "6%", height: "80%", marginLeft: "3%", marginRight: "3%" }} /> | 
				
			|||
                                                                {value?.deviceName} | 
				
			|||
                                                            </div> | 
				
			|||
                                                        </div> | 
				
			|||
                                                    </div> : "" | 
				
			|||
                                                } else if (index == 3) { | 
				
			|||
                                                    return value?.deviceSerial ? <div style={{ width: "45%", height: "40%", backgroundSize: 'cover', position: "absolute", left: "45%", top: "49%" }}> | 
				
			|||
                                                        {this.renderVideo(value, index)} | 
				
			|||
                                                        <div style={{ width: "100%", height: "100%", position: "absolute", top: "80%" }}> | 
				
			|||
                                                            <div style={{ width: "100%", height: "20%", backgroundColor: "rgba(0,0,0,0.6)", overflow: "hiddden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}> | 
				
			|||
                                                                <img src='/assets/images/leadership/weizhis.png' style={{ width: "6%", height: "80%", marginLeft: "3%", marginRight: "3%" }} /> | 
				
			|||
                                                                {value?.deviceName} | 
				
			|||
                                                            </div> | 
				
			|||
                                                        </div> | 
				
			|||
                                                    </div> : "" | 
				
			|||
                                                } else { | 
				
			|||
                                                    return undefined | 
				
			|||
                                                } | 
				
			|||
                                            }) | 
				
			|||
                                        } | 
				
			|||
                                    </li> | 
				
			|||
                                ) | 
				
			|||
                            }) | 
				
			|||
                        } | 
				
			|||
                    </ul> | 
				
			|||
                    {/* <div className="control" style={{ width: "100%", height: "10%" }}> | 
				
			|||
                        <span style={{ position: "absolute", top: "86%", width: "3%", height: "8%" }} className="left" onClick={(e) => { this.previous(e) }}> | 
				
			|||
                            <img src='/assets/images/leadership/zuofanye.png' style={{ width: "100%", height: "100%" }} /> | 
				
			|||
                        </span> | 
				
			|||
                        <span style={{ position: "absolute", top: "86%", width: "3%", height: "8%", right: "6%" }} className="right" onClick={(e) => { this.next(e) }}> | 
				
			|||
                            <img src='/assets/images/leadership/youofanye.png' style={{ width: "100%", height: "100%" }} /> | 
				
			|||
                        </span> | 
				
			|||
                    </div> */} | 
				
			|||
                </div> | 
				
			|||
            </div> | 
				
			|||
        ) | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    componentWillReceiveProps (nextProps, oldProps) { | 
				
			|||
        if (nextProps.videoCenterList && nextProps.videoCenterList.length && (!oldProps.videoCenterList || !oldProps.videoCenterList.length)) { | 
				
			|||
            this.setState({ | 
				
			|||
                imgs: nextProps.videoCenterList.slice(-4) | 
				
			|||
            }) | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
    componentDidMount () { //一开始自动播放
 | 
				
			|||
        setTimeout(() => { | 
				
			|||
            this.start(); | 
				
			|||
        }, 0) | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    componentWillUnmount () { //销毁前清除定时器
 | 
				
			|||
        this.stop(); | 
				
			|||
    } | 
				
			|||
    stop = () => { //暂停
 | 
				
			|||
        let { timer } = this.state; | 
				
			|||
        clearInterval(timer); | 
				
			|||
    } | 
				
			|||
    start = () => { //开始
 | 
				
			|||
        let { timer } = this.state; | 
				
			|||
        timer = setInterval(() => { | 
				
			|||
            this.next(); | 
				
			|||
        }, 300000); | 
				
			|||
        this.setState({ | 
				
			|||
            timer | 
				
			|||
        }) | 
				
			|||
    } | 
				
			|||
    change = (index) => { //点击下面的按钮切换当前显示的图片
 | 
				
			|||
        let { showIndex } = this.state; | 
				
			|||
        showIndex = index; | 
				
			|||
        this.setState({ | 
				
			|||
            showIndex | 
				
			|||
        }) | 
				
			|||
    } | 
				
			|||
    previous = (e) => { //上一张
 | 
				
			|||
        let ev = e || window.event; | 
				
			|||
        let { showIndex, imgs } = this.state; | 
				
			|||
        if (showIndex <= 0) { | 
				
			|||
            showIndex = imgs.length - 1; | 
				
			|||
        } else { | 
				
			|||
            showIndex--; | 
				
			|||
        } | 
				
			|||
        this.setState({ | 
				
			|||
            showIndex | 
				
			|||
        }) | 
				
			|||
    } | 
				
			|||
    next = (e) => { //下一张
 | 
				
			|||
        let ev = e || window.event; | 
				
			|||
        let { showIndex, imgs } = this.state; | 
				
			|||
        if (showIndex >= imgs.length - 1) { | 
				
			|||
            showIndex = 0; | 
				
			|||
        } else { | 
				
			|||
            showIndex++; | 
				
			|||
        } | 
				
			|||
        this.setState({ | 
				
			|||
            showIndex | 
				
			|||
        }) | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function mapStateToProps (state) { | 
				
			|||
    const { videoCenterList } = state | 
				
			|||
 | 
				
			|||
    return { | 
				
			|||
        videoCenterList: videoCenterList.data || [] | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
export default connect(mapStateToProps)(ReactCarousel) | 
				
			|||
					Loading…
					
					
				
		Reference in new issue