9 changed files with 619 additions and 11 deletions
@ -0,0 +1,147 @@ |
|||
'use strict'; |
|||
const moment = require('moment') |
|||
|
|||
function getApproveList (opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
const models = ctx.fs.dc.models; |
|||
const { page, limit, applyAt, approveState, resourceName, applyBy, applyById } = ctx.query; |
|||
|
|||
let errMsg = { message: '获取消费审批列表失败' } |
|||
try { |
|||
|
|||
let option = { |
|||
where: {}, |
|||
order: [["id", "desc"]], |
|||
distinct: true, |
|||
include: [{ |
|||
model: models.User, |
|||
attributes: ['id', 'name'] |
|||
},] |
|||
} |
|||
if (resourceName) { |
|||
option.where.resourceName = { $iLike: `%${resourceName}%` } |
|||
} |
|||
if (applyBy) { |
|||
option.include[0].where = { '$user.name$': { $iLike: `%${applyBy}%` } } |
|||
} |
|||
if (applyById) { |
|||
option.where.applyBy = applyById |
|||
} |
|||
|
|||
if (limit) { |
|||
option.limit = Number(limit) |
|||
} |
|||
if (page && limit) { |
|||
option.offset = Number(page) * Number(limit) |
|||
} |
|||
|
|||
if (approveState) { |
|||
option.where.approveState = approveState |
|||
} |
|||
|
|||
if (applyAt) { |
|||
option.where.applyAt = { |
|||
$between: [ |
|||
moment(applyAt).startOf('day').format('YYYY-MM-DD HH:mm:ss'), |
|||
moment(applyAt).endOf('day').format('YYYY-MM-DD HH:mm:ss') |
|||
] |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
const res = await models.ResourceConsumption.findAndCount(option); |
|||
ctx.status = 200; |
|||
ctx.body = res; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = errMsg |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 新增模型
|
|||
function addModelManagement (opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
const models = ctx.fs.dc.models; |
|||
try { |
|||
const { attributeName, attributeCode, modelType } = ctx.request.body |
|||
const checkName = await models.MetaModel.findOne({ where: { attributeName, modelType } }); |
|||
const checkCode = await models.MetaModel.findOne({ where: { attributeCode, modelType } }); |
|||
if (checkName || checkCode) { |
|||
ctx.status = 400; |
|||
ctx.body = { message: checkName ? '该属性名称已存在' : "该属性代码已存在" } |
|||
} else { |
|||
let rslt = ctx.request.body; |
|||
await models.MetaModel.create(Object.assign({}, rslt)) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '新建模型成功' } |
|||
} |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '新建模型失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改模型
|
|||
function postApprove (opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
|
|||
const data = ctx.request.body; |
|||
const { id } = data |
|||
|
|||
await models.ResourceConsumption.update( |
|||
data, |
|||
{ where: { id: id, } } |
|||
) |
|||
ctx.status = 204; |
|||
|
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '消费审批失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除模型
|
|||
function deleteModelManagement (opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { id } = ctx.params; |
|||
await models.MetaModel.destroy({ |
|||
where: { |
|||
id: id |
|||
} |
|||
}) |
|||
ctx.status = 204; |
|||
ctx.body = { message: '删除模型成功' } |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = { message: '删除模型失败' } |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
module.exports = { |
|||
// getModelManagementList,
|
|||
// addModelManagement,
|
|||
// editModelManagement,
|
|||
// deleteModelManagement,
|
|||
getApproveList, |
|||
postApprove, |
|||
} |
@ -0,0 +1,23 @@ |
|||
'use strict'; |
|||
|
|||
const model = require('../../controllers/resourceConsumption/index'); |
|||
|
|||
module.exports = function (app, router, opts, AuthCode) { |
|||
|
|||
// app.fs.api.logAttr['POST/meta/model'] = { content: '增加模型信息', visible: true };
|
|||
// router.post('/meta/model', model.addModelManagement(opts))
|
|||
|
|||
// 修改模型信息
|
|||
app.fs.api.logAttr['POST/resource/approve'] = { content: '消费审批', visible: true }; |
|||
router.post('/resource/approve', model.postApprove(opts)) |
|||
|
|||
// // 删除模型信息
|
|||
// app.fs.api.logAttr['DEL/meta/model/:id'] = { content: '删除模型信息', visible: true };
|
|||
// router.del('/meta/model/:id', model.deleteModelManagement(opts))
|
|||
|
|||
//获取模型信息列表
|
|||
app.fs.api.logAttr['GET/resource/approve'] = { content: '获取消费审批列表', visible: true }; |
|||
router.get('/resource/approve', model.getApproveList(opts)); |
|||
|
|||
|
|||
}; |
@ -0,0 +1,29 @@ |
|||
'use strict'; |
|||
|
|||
import { basicAction } from '@peace/utils' |
|||
import { ApiTable } from '$utils' |
|||
|
|||
export function getApproveList (query = {}) { |
|||
return dispatch => basicAction({ |
|||
type: 'get', |
|||
query, |
|||
dispatch: dispatch, |
|||
actionType: 'GET_APPROVE_LIST', |
|||
url: `${ApiTable.approveList}`, |
|||
msg: { error: '获取资源消费列表失败' }, |
|||
reducer: { name: '' } |
|||
}); |
|||
} |
|||
|
|||
|
|||
export function postApprove (data = {}) { |
|||
return dispatch => basicAction({ |
|||
type: 'post', |
|||
data, |
|||
dispatch: dispatch, |
|||
actionType: 'POST_APPROVE', |
|||
url: `${ApiTable.approveList}`, |
|||
msg: { option: '资源审批' }, |
|||
reducer: { name: '' } |
|||
}); |
|||
} |
@ -1,7 +1,9 @@ |
|||
'use strict'; |
|||
|
|||
import * as example from './example' |
|||
import * as approve from './approve' |
|||
|
|||
export default { |
|||
...example, |
|||
...approve, |
|||
} |
@ -0,0 +1,94 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import moment from 'moment'; |
|||
import { v4 as uuidv4 } from 'uuid' |
|||
|
|||
import { Tabs, Form, Input, DatePicker, Button, Modal, Radio } from 'antd'; |
|||
|
|||
|
|||
function ApproveModal ({ loading, clientHeight, user, actions, dispatch, close, success, editData, }) { |
|||
|
|||
const { resourceConsumption } = actions |
|||
const [tabsKey, setTabsKey] = useState("stay") |
|||
const [query, setQuery] = useState({ page: 0, limit: 10 }); |
|||
const [proTableList, setProTableList] = useState({ rows: [], count: 0 }); |
|||
const [approve, setApprove] = useState() |
|||
|
|||
const [form] = Form.useForm(); |
|||
useEffect(() => { |
|||
|
|||
}, []) |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
return <> |
|||
<Modal title="数据消费审批" open={true} |
|||
onOk={e => { |
|||
form.validateFields().then(v => { |
|||
console.log(v); |
|||
dispatch(resourceConsumption.postApprove({ |
|||
id: editData?.id, ...v, |
|||
approveAt: moment().format('YYYY-MM-DD HH:mm:ss'), |
|||
approveBy: user?.id, |
|||
approveState: '已审批' |
|||
})).then(res => { |
|||
if (res.success) { |
|||
close() |
|||
success() |
|||
} |
|||
}) |
|||
}) |
|||
}} |
|||
onCancel={() => { |
|||
close() |
|||
}} |
|||
> |
|||
<Form |
|||
style={{ marginLeft: 20 }} |
|||
form={form} |
|||
onValuesChange={v => { |
|||
console.log(v); |
|||
if (v.approve) { |
|||
setApprove(v.approve) |
|||
} |
|||
// setFormData(v)
|
|||
}} |
|||
autoComplete="off" |
|||
> |
|||
<Form.Item label="审批意见" name="approve" rules={[{ required: true, message: '请选择审批意见' }]} > |
|||
<Radio.Group> |
|||
<Radio value="true"> 同意 </Radio> |
|||
<Radio value="false"> 不同意 </Radio> |
|||
</Radio.Group> |
|||
</Form.Item> |
|||
{!approve || approve == 'false' ? |
|||
<Form.Item label="意见内容" name="approveRemarks" rules={[{ required: true, message: '请输入意见内容' }]}> |
|||
<Input allowClear placeholder='请填写意见内容' style={{ width: 300, marginRight: 16 }} /> |
|||
</Form.Item> : ""} |
|||
{!approve || approve == 'true' ? <div style={{ position: 'relative' }}> |
|||
<Form.Item label="访问令牌" name="token" rules={[{ required: true, message: '请生成令牌' }]}> |
|||
<Input allowClear placeholder='生成令牌' disabled={true} style={{ width: 300, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Button type="primary" style={{ position: 'absolute', top: 0, right: 0 }} onClick={() => { |
|||
form.setFieldsValue({ token: uuidv4() }) |
|||
}}>生成</Button> |
|||
</div> : ""} |
|||
</Form> |
|||
</Modal > |
|||
|
|||
</> |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { global, auth, resourceCatalog } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
clientHeight: global.clientHeight, |
|||
// resourceCatalog: resourceCatalog?.data || [],
|
|||
// isRequesting: resourceCatalog.isRequesting
|
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(ApproveModal) |
@ -1,7 +1,188 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import moment from 'moment'; |
|||
import ApproveModal from '../components/approveModal'; |
|||
|
|||
function Approve (props) { |
|||
return <>数据消费审批</> |
|||
|
|||
import { Tabs, Form, Input, DatePicker, Button, Table } from 'antd'; |
|||
import { v1 } from 'uuid'; |
|||
|
|||
|
|||
function Approve ({ loading, clientHeight, actions, dispatch, }) { |
|||
|
|||
const { resourceConsumption } = actions |
|||
const [tabsKey, setTabsKey] = useState("stay") |
|||
const [query, setQuery] = useState({ page: 0, limit: 10 }); |
|||
const [proTableList, setProTableList] = useState({ rows: [], count: 0 }); |
|||
const [formData, setFormData] = useState({}) |
|||
const [approveModal, setApproveModal] = useState(false) |
|||
const [editData, setEditData] = useState({}) |
|||
const [column, setColumn] = useState([]) |
|||
|
|||
useEffect(() => { |
|||
resourceData() |
|||
}, []) |
|||
|
|||
|
|||
let resourceData = (params) => { |
|||
let data = params || query |
|||
dispatch(resourceConsumption.getApproveList({ approveState: tabsKey == 'stay' ? "审批中" : '已审批', ...formData, ...data, })).then(res => { |
|||
if (res.success) { |
|||
setProTableList(res.payload.data) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
|
|||
const columns = [{ |
|||
title: '资源名称', |
|||
dataIndex: 'resourceName', |
|||
}, { |
|||
title: '申请人', |
|||
dataIndex: 'applyBy', |
|||
render: (text, record) => record?.user?.name |
|||
}, { |
|||
title: '需求描述', |
|||
dataIndex: 'requirements', |
|||
}, { |
|||
title: '数据类型', |
|||
dataIndex: 'resourceType', |
|||
}, { |
|||
title: '令牌', |
|||
dataIndex: 'token', |
|||
render: (text, record) => text || '--' |
|||
}, { |
|||
title: '申请时间', |
|||
dataIndex: 'applyAt', |
|||
render: (text, record) => { |
|||
return moment(text).format('YYYY-MM-DD HH:mm:ss'); |
|||
}, |
|||
sorter: { |
|||
compare: (a, b) => moment(b?.applyAt).valueOf() - moment(a?.applyAt).valueOf(), |
|||
// multiple: 2,
|
|||
}, |
|||
}, { |
|||
title: '审批意见', |
|||
dataIndex: 'result', |
|||
render: (text, record) => record?.token ? "审批通过" : "审批不通过" |
|||
}, { |
|||
title: '意见内容', |
|||
dataIndex: 'approveRemarks', |
|||
render: (text, record) => text || '--' |
|||
}, { |
|||
title: '审批时间', |
|||
dataIndex: 'approveAt', |
|||
render: (text, record) => { |
|||
return moment(text).format('YYYY-MM-DD HH:mm:ss'); |
|||
}, |
|||
sorter: { |
|||
compare: (a, b) => moment(b?.approveAt).valueOf() - moment(a?.approveAt).valueOf(), |
|||
// multiple: 2,
|
|||
}, |
|||
}, { |
|||
title: '操作', |
|||
dataIndex: 'handle', |
|||
// ellipsis: true,
|
|||
render: (text, record) => <Button type="link" onClick={() => { |
|||
setEditData(record) |
|||
setApproveModal(true); |
|||
}}>审批</Button> |
|||
}, |
|||
]; |
|||
|
|||
useEffect(() => { |
|||
let data = [] |
|||
columns?.map(v => { |
|||
if (tabsKey == 'stay') { |
|||
if (v.dataIndex != 'token' |
|||
&& v.dataIndex != 'result' |
|||
&& v.dataIndex != 'approveRemarks' |
|||
&& v.dataIndex != 'approveAt') { |
|||
data?.push(v) |
|||
} |
|||
|
|||
} else { |
|||
if (v.dataIndex != 'handle') { |
|||
data?.push(v) |
|||
} |
|||
} |
|||
}) |
|||
setColumn(data) |
|||
}, [tabsKey]) |
|||
|
|||
return <> |
|||
<Tabs defaultActiveKey="stay" items={[{ key: 'stay', label: '待审批' }, { key: 'end', label: '已审批' }]} onTabClick={key => { |
|||
setTabsKey(key) |
|||
resourceData({ limit: 10, page: 0, approveState: key == 'stay' ? "审批中" : '已审批' }) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
}} /> |
|||
<Form |
|||
style={{ display: 'flex' }} |
|||
onFinish={v => { |
|||
|
|||
setFormData({ ...v, applyAt: v.applyAt ? moment(v.applyAt).format('YYYY-MM-DD HH:mm:ss') : "" }) |
|||
resourceData({ limit: 10, page: 0, ...v, applyAt: v.applyAt ? moment(v.applyAt).format('YYYY-MM-DD HH:mm:ss') : "" }) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
console.log(v); |
|||
}} |
|||
autoComplete="off" |
|||
> |
|||
<Form.Item label="资源名称" name="resourceName" > |
|||
<Input allowClear placeholder='资源名称关键字' style={{ width: 200, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item label="申请人" name="applyBy" > |
|||
<Input allowClear placeholder='申请人关键字' style={{ width: 140, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item label="申请日期" name="applyAt" > |
|||
<DatePicker style={{ width: 140, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item > |
|||
<Button type="primary" htmlType="submit"> 查询 </Button> |
|||
</Form.Item> |
|||
</Form> |
|||
|
|||
export default Approve |
|||
<Table |
|||
columns={column} |
|||
dataSource={proTableList?.rows || []} |
|||
scroll={{ scrollToFirstRowOnChange: true, y: clientHeight - 260 }} |
|||
pagination={{ |
|||
current: query?.page + 1, |
|||
pageSize: query?.limit, |
|||
total: proTableList?.count, |
|||
showSizeChanger: true, |
|||
// showQuickJumper: true,
|
|||
showTotal: (total) => { return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / query?.limit)}页,${total}项`}</span> }, |
|||
onChange: (page, pageSize) => { |
|||
setQuery({ limit: pageSize, page: page - 1 }); |
|||
resourceData({ limit: pageSize, page: page - 1 }); |
|||
} |
|||
}} |
|||
/> |
|||
{ |
|||
approveModal ? |
|||
<ApproveModal |
|||
editData={editData} |
|||
close={() => { |
|||
setApproveModal(false); |
|||
setEditData({}) |
|||
}} |
|||
success={() => { |
|||
resourceData({ limit: 10, page: 0 }) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
}} |
|||
/> : "" |
|||
} |
|||
|
|||
</> |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { global, auth, resourceCatalog } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
clientHeight: global.clientHeight, |
|||
// resourceCatalog: resourceCatalog?.data || [],
|
|||
// isRequesting: resourceCatalog.isRequesting
|
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(Approve) |
@ -1,7 +1,135 @@ |
|||
import React, { useEffect, useState } from 'react' |
|||
import { connect } from 'react-redux'; |
|||
import moment from 'moment'; |
|||
import ApproveModal from '../components/approveModal'; |
|||
|
|||
function MyApplication (props) { |
|||
return <>我的数据消费申请</> |
|||
|
|||
import { Tabs, Form, Input, DatePicker, Button, Table } from 'antd'; |
|||
import { v1 } from 'uuid'; |
|||
|
|||
|
|||
function MyApplication ({ loading, clientHeight, actions, dispatch, user }) { |
|||
|
|||
const { resourceConsumption } = actions |
|||
|
|||
const [query, setQuery] = useState({ page: 0, limit: 10 }); |
|||
const [proTableList, setProTableList] = useState({ rows: [], count: 0 }); |
|||
const [formData, setFormData] = useState({}) |
|||
|
|||
useEffect(() => { |
|||
resourceData() |
|||
}, []) |
|||
|
|||
|
|||
let resourceData = (params) => { |
|||
let data = params || query |
|||
dispatch(resourceConsumption.getApproveList({ applyById: user?.id, ...formData, ...data, })).then(res => { |
|||
if (res.success) { |
|||
setProTableList(res.payload.data) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
|
|||
export default MyApplication |
|||
const columns = [{ |
|||
title: '资源名称', |
|||
dataIndex: 'resourceName', |
|||
}, { |
|||
title: '申请人', |
|||
dataIndex: 'applyBy', |
|||
render: (text, record) => record?.user?.name |
|||
}, { |
|||
title: '需求描述', |
|||
dataIndex: 'requirements', |
|||
}, { |
|||
title: '数据类型', |
|||
dataIndex: 'resourceType', |
|||
}, { |
|||
title: '令牌', |
|||
dataIndex: 'token', |
|||
render: (text, record) => text || '--' |
|||
}, { |
|||
title: '申请时间', |
|||
dataIndex: 'applyAt', |
|||
render: (text, record) => text && moment(text).format('YYYY-MM-DD HH:mm:ss') || '--', |
|||
sorter: { |
|||
compare: (a, b) => moment(b?.applyAt).valueOf() - moment(a?.applyAt).valueOf(), |
|||
// multiple: 2,
|
|||
}, |
|||
}, { |
|||
title: '审批意见', |
|||
dataIndex: 'result', |
|||
render: (text, record) => record?.approveState == '审批中' ? record?.approveState : record?.approveState == '已审批' ? record?.token ? "审批通过" : "审批不通过" : "--" |
|||
}, { |
|||
title: '意见内容', |
|||
dataIndex: 'approveRemarks', |
|||
render: (text, record) => text || '--' |
|||
}, { |
|||
title: '审批时间', |
|||
dataIndex: 'approveAt', |
|||
render: (text, record) => text && moment(text).format('YYYY-MM-DD HH:mm:ss') || '--', |
|||
sorter: { |
|||
compare: (a, b) => moment(b?.approveAt).valueOf() - moment(a?.approveAt).valueOf(), |
|||
// multiple: 2,
|
|||
}, |
|||
}]; |
|||
|
|||
|
|||
|
|||
return <> |
|||
<Form |
|||
style={{ display: 'flex' }} |
|||
onFinish={v => { |
|||
|
|||
setFormData({ ...v, applyAt: v.applyAt ? moment(v.applyAt).format('YYYY-MM-DD HH:mm:ss') : "" }) |
|||
resourceData({ limit: 10, page: 0, ...v, applyAt: v.applyAt ? moment(v.applyAt).format('YYYY-MM-DD HH:mm:ss') : "" }) |
|||
setQuery({ limit: 10, page: 0 }); |
|||
console.log(v); |
|||
}} |
|||
autoComplete="off" |
|||
> |
|||
<Form.Item label="资源名称" name="resourceName" > |
|||
<Input allowClear placeholder='资源名称关键字' style={{ width: 200, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item label="申请人" name="applyBy" > |
|||
<Input allowClear placeholder='申请人关键字' style={{ width: 140, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item label="申请日期" name="applyAt" > |
|||
<DatePicker style={{ width: 140, marginRight: 16 }} /> |
|||
</Form.Item> |
|||
<Form.Item > |
|||
<Button type="primary" htmlType="submit"> 查询 </Button> |
|||
</Form.Item> |
|||
</Form> |
|||
|
|||
<Table |
|||
columns={columns} |
|||
dataSource={proTableList?.rows || []} |
|||
scroll={{ scrollToFirstRowOnChange: true, y: clientHeight - 260 }} |
|||
pagination={{ |
|||
current: query?.page + 1, |
|||
pageSize: query?.limit, |
|||
total: proTableList?.count, |
|||
showSizeChanger: true, |
|||
// showQuickJumper: true,
|
|||
showTotal: (total) => { return <span style={{ fontSize: 15 }}>{`共${Math.ceil(total / query?.limit)}页,${total}项`}</span> }, |
|||
onChange: (page, pageSize) => { |
|||
setQuery({ limit: pageSize, page: page - 1 }); |
|||
resourceData({ limit: pageSize, page: page - 1 }); |
|||
} |
|||
}} |
|||
/> |
|||
|
|||
</> |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { global, auth, resourceCatalog } = state; |
|||
return { |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
clientHeight: global.clientHeight, |
|||
// resourceCatalog: resourceCatalog?.data || [],
|
|||
// isRequesting: resourceCatalog.isRequesting
|
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(MyApplication) |
|||
|
Loading…
Reference in new issue