nili
5 months ago
30 changed files with 441 additions and 30 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@ |
|||
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["15.a664eb81.async.js",15],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["p__MoneyManagement.4138f9c6.async.js",190],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.4594a64b.async.js",301],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.c61abcd9.async.js",371],["390.41467286.async.js",390],["393.38316f72.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.dec1a716.async.js",455],["p__Proxy__ProxyUserManagement.3e781dae.async.js",526],["531.35af34f5.async.js",531],["539.290aefb9.async.js",539],["p__AdvRecordListV2.93e34297.async.js",542],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.8a884f26.async.js",635],["p__App__AppManagement.6464403a.async.js",731],["761.f7bbde11.async.js",761],["p__AdminManagement.22b52ba3.async.js",816],["841.614ef4c0.async.js",841],["p__AdvRecordList.fc092f59.async.js",857],["p__UserManagement.0ef1f876.async.js",903],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930],["931.c2d40e0b.async.js",931],["p__Proxy__ProxyAdvRecordListV2.20a0f4c8.async.js",990]],"r":{"/*":[19,27],"/":[1,5,6,18,20,27],"/welcome":[1,2,3,10,18,28,5,6,20,27],"/super":[0,1,2,12,14,15,27,28,29,5,6,18,20],"/adminList":[0,1,2,14,15,22,23,27,5,6,18,20],"/bind":[1,2,10,11,17,18,28,5,6,20,27],"/appList":[1,2,11,14,15,21,27,28,29,5,6,18,20],"/advList/:code":[1,2,14,15,18,24,25,27,28,5,6,20],"/advListV2/:code":[0,1,2,14,15,16,18,24,27,28,5,6,20],"/user/:code":[0,1,2,14,15,26,27,28,5,6,18,20],"/money/:code":[0,1,2,4,14,15,27,28,5,6,18,20],"/app/:code":[1,2,8,14,15,18,24,27,28,5,6,20],"/user/login":[1,2,7,14],"/proxy/advListV2/:code":[0,1,2,14,15,18,24,27,28,30,5,6,20],"/proxy/user/:code":[0,1,2,13,14,15,27,28,5,6,18,20]}},{publicPath:"https://apks.bzgames.cn/matrix_fe/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}(); |
@ -1 +0,0 @@ |
|||
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["p__MoneyManagement.6438f0bb.async.js",190],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.4594a64b.async.js",301],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.c61abcd9.async.js",371],["390.41467286.async.js",390],["393.38316f72.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.579fe948.async.js",455],["p__Proxy__ProxyUserManagement.9b5c45a4.async.js",526],["531.35af34f5.async.js",531],["539.290aefb9.async.js",539],["p__AdvRecordListV2.185cc304.async.js",542],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.20e45f05.async.js",635],["p__App__AppManagement.c08f72ac.async.js",731],["761.f7bbde11.async.js",761],["p__AdminManagement.3439b2cb.async.js",816],["841.614ef4c0.async.js",841],["p__AdvRecordList.fc092f59.async.js",857],["p__UserManagement.98f62b33.async.js",903],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930],["931.c2d40e0b.async.js",931],["971.677bb358.async.js",971],["p__Proxy__ProxyAdvRecordListV2.8a4ba9c6.async.js",990]],"r":{"/*":[18,26],"/":[0,4,5,17,19,26],"/welcome":[0,1,2,9,17,27,4,5,19,26],"/super":[0,1,11,13,14,26,27,28,4,5,17,19],"/adminList":[0,1,13,14,21,22,26,29,4,5,17,19],"/bind":[0,1,9,10,16,17,27,4,5,19,26],"/appList":[0,1,10,13,14,20,26,27,28,4,5,17,19],"/advList/:code":[0,1,13,14,17,23,24,26,27,4,5,19],"/advListV2/:code":[0,1,13,14,15,17,23,26,27,4,5,19],"/user/:code":[0,1,13,14,25,26,27,29,4,5,17,19],"/money/:code":[0,1,3,13,14,26,27,4,5,17,19],"/app/:code":[0,1,7,13,14,17,23,26,27,4,5,19],"/user/login":[0,1,6,13],"/proxy/advListV2/:code":[0,1,13,14,17,23,26,27,30,4,5,19],"/proxy/user/:code":[0,1,12,13,14,26,27,29,4,5,17,19]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}(); |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,172 @@ |
|||
import { innerUserList } from '@/services/matrix/superAdmin'; |
|||
import { SearchOutlined } from '@ant-design/icons'; |
|||
import { ProColumns, ProTable } from '@ant-design/pro-components'; |
|||
import { Button, Form, Input, InputNumber, Modal, Space } from 'antd'; |
|||
import { useEffect, useState } from 'react'; |
|||
|
|||
import { saveInnerUser } from '../../services/matrix/superAdmin'; |
|||
import UserInfo from '../User/UserInfo'; |
|||
|
|||
const InnerUserManagement = () => { |
|||
const [visible, setVisible] = useState(false); |
|||
|
|||
const [whiteUserArr, setWhiteUserArr] = useState<API.WhiteUserBo[]>([]); |
|||
const [filteredArr, setFilteredArr] = useState<API.WhiteUserBo[]>([]); |
|||
const [form] = Form.useForm(); |
|||
|
|||
const fetchApp = async () => { |
|||
const res = await innerUserList(); |
|||
if (res.data) { |
|||
setWhiteUserArr(res.data); |
|||
setFilteredArr(res.data); |
|||
} |
|||
}; |
|||
|
|||
const columns: ProColumns<API.WhiteUserBo>[] = [ |
|||
{ |
|||
title: '应用名', |
|||
dataIndex: 'appName', |
|||
copyable: true, |
|||
hideInSearch: true, |
|||
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => ( |
|||
<div style={{ padding: 8 }}> |
|||
<Input |
|||
placeholder="搜索应用" |
|||
value={selectedKeys[0]} |
|||
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])} |
|||
onPressEnter={() => confirm()} |
|||
style={{ marginBottom: 8, display: 'block' }} |
|||
/> |
|||
<Space> |
|||
<Button onClick={() => confirm()} type="primary"> |
|||
搜索 |
|||
</Button> |
|||
<Button onClick={() => clearFilters && clearFilters()} type="link"> |
|||
清除 |
|||
</Button> |
|||
</Space> |
|||
</div> |
|||
), |
|||
onFilter: (value, record) => { |
|||
if (typeof value === 'string' && typeof record?.appName === 'string') { |
|||
return record.appName.includes(value); |
|||
} |
|||
return false; |
|||
}, |
|||
filterIcon: (filtered) => ( |
|||
<SearchOutlined |
|||
style={{ color: filtered ? '#1890ff' : undefined }} |
|||
onPointerOverCapture={undefined} |
|||
onPointerMoveCapture={undefined} |
|||
/> |
|||
), |
|||
}, |
|||
{ |
|||
title: '用户', |
|||
dataIndex: 'user', |
|||
hideInSearch: true, |
|||
render: (_, r) => <UserInfo data={r.user || {}} />, |
|||
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => { |
|||
const selectedUserId = selectedKeys[0] ? String(selectedKeys[0]) : ''; |
|||
return ( |
|||
<div style={{ padding: 8 }}> |
|||
<InputNumber |
|||
placeholder="搜索 userId" |
|||
value={selectedUserId} |
|||
onChange={(value) => setSelectedKeys(value ? [value] : [])} |
|||
onPressEnter={() => confirm()} |
|||
style={{ marginBottom: 8, display: 'block', width: 200 }} |
|||
/> |
|||
<Space> |
|||
<Button onClick={() => confirm()} type="primary"> |
|||
搜索 |
|||
</Button> |
|||
<Button onClick={() => clearFilters && clearFilters()} type="link"> |
|||
清除 |
|||
</Button> |
|||
</Space> |
|||
</div> |
|||
); |
|||
}, |
|||
onFilter: (value, record) => { |
|||
return record.user?.id === value; |
|||
}, |
|||
filterIcon: (filtered) => ( |
|||
<SearchOutlined |
|||
style={{ color: filtered ? '#1890ff' : undefined }} |
|||
onPointerOverCapture={undefined} |
|||
onPointerMoveCapture={undefined} |
|||
/> |
|||
), |
|||
}, |
|||
{ |
|||
title: '创建时间', |
|||
hideInSearch: true, |
|||
dataIndex: 'createdAt', |
|||
valueType: 'dateTime', |
|||
}, |
|||
{ |
|||
title: '修改时间', |
|||
hideInSearch: true, |
|||
dataIndex: 'updatedAt', |
|||
valueType: 'dateTime', |
|||
}, |
|||
]; |
|||
|
|||
useEffect(() => { |
|||
fetchApp(); |
|||
}, []); |
|||
|
|||
return ( |
|||
<> |
|||
<Button |
|||
style={{ marginBottom: '20px' }} |
|||
onClick={() => { |
|||
setVisible(true); |
|||
form.resetFields(); |
|||
}} |
|||
> |
|||
添加内部用户 |
|||
</Button> |
|||
|
|||
<ProTable |
|||
search={false} |
|||
onReset={() => { |
|||
setFilteredArr(whiteUserArr); |
|||
}} |
|||
columns={columns} |
|||
dataSource={filteredArr} |
|||
/> |
|||
|
|||
<Modal |
|||
title="编辑" |
|||
visible={visible} |
|||
onOk={() => { |
|||
form.submit(); |
|||
setVisible(false); |
|||
}} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
}} |
|||
> |
|||
<Form |
|||
labelCol={{ span: 4 }} |
|||
wrapperCol={{ span: 18 }} |
|||
form={form} |
|||
onFinish={async ({ userId }) => { |
|||
if (userId) { |
|||
await saveInnerUser({ userId: userId }); |
|||
fetchApp(); |
|||
} |
|||
}} |
|||
> |
|||
<Form.Item label="userId" name="userId"> |
|||
<InputNumber style={{ width: 200 }} /> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
</> |
|||
); |
|||
}; |
|||
|
|||
export default InnerUserManagement; |
@ -0,0 +1,164 @@ |
|||
import { appList } from '@/services/matrix/admin'; |
|||
import { addScheduleV2, scheduleListV2 } from '@/services/matrix/superAdmin'; |
|||
import { formatIncome } from '@/utils/numberUtils'; |
|||
import { Button, DatePicker, Form, Input, Modal, Select, Table, Tag, message } from 'antd'; |
|||
import { ColumnsType } from 'antd/es/table'; |
|||
import moment, { Moment } from 'moment'; |
|||
import { useEffect, useState } from 'react'; |
|||
|
|||
const MockScheduleManagement = () => { |
|||
const [visible, setVisible] = useState(false); |
|||
const [appArr, setAppArr] = useState<API.MatrixApp[]>([]); |
|||
const [scheduleArr, setScheduleArr] = useState<API.MatrixMockSchedule[]>([]); |
|||
const [scheduleForm] = Form.useForm(); |
|||
|
|||
const fetchApp = async () => { |
|||
const res = await appList(); |
|||
if (res.data) { |
|||
setAppArr(res.data); |
|||
} |
|||
}; |
|||
|
|||
const getAppNameById = (appId: number) => { |
|||
const app = appArr.find((app) => app.id === appId); |
|||
return app ? app.name : ''; |
|||
}; |
|||
|
|||
const fetchScheduleList = async () => { |
|||
const res = await scheduleListV2(); |
|||
if (res.data) { |
|||
setScheduleArr(res.data); |
|||
} |
|||
}; |
|||
|
|||
const sColumns: ColumnsType<API.MatrixMockScheduleV2> = [ |
|||
{ |
|||
title: '应用', |
|||
dataIndex: 'appId', |
|||
render: (appId) => ( |
|||
<Tag color="blue" key={appId}> |
|||
{getAppNameById(appId)} |
|||
</Tag> |
|||
), |
|||
}, |
|||
{ |
|||
title: '目标金额', |
|||
dataIndex: 'incomeYuan', |
|||
}, |
|||
{ |
|||
title: '已刷金额', |
|||
dataIndex: 'mockIncome', |
|||
render: (r: number) => { |
|||
return formatIncome(r); |
|||
}, |
|||
}, |
|||
{ |
|||
title: '开始时间', |
|||
dataIndex: 'scheduleTime', |
|||
render: (r: string) => { |
|||
return moment(r).format('YYYY-MM-DD HH:mm'); |
|||
}, |
|||
}, |
|||
{ |
|||
title: '状态', |
|||
dataIndex: 'status', |
|||
render: (r: number) => { |
|||
switch (r) { |
|||
case 0: |
|||
return '未开始'; |
|||
case 1: |
|||
return '进行中'; |
|||
case 2: |
|||
return '已完成'; |
|||
} |
|||
return r; |
|||
}, |
|||
}, |
|||
{ |
|||
title: '创建时间', |
|||
dataIndex: 'createdAt', |
|||
render: (r: string) => { |
|||
return moment(r).format('YYYY-MM-DD HH:mm'); |
|||
}, |
|||
}, |
|||
{ |
|||
title: '更新时间', |
|||
dataIndex: 'updatedAt', |
|||
render: (r: string) => { |
|||
return moment(r).format('YYYY-MM-DD HH:mm'); |
|||
}, |
|||
}, |
|||
]; |
|||
|
|||
useEffect(() => { |
|||
fetchApp(); |
|||
fetchScheduleList(); |
|||
}, []); |
|||
|
|||
const addScheduleTask = () => { |
|||
scheduleForm.resetFields(); // 重置表单字段
|
|||
setVisible(true); |
|||
}; |
|||
|
|||
return ( |
|||
<> |
|||
<div> |
|||
<Button onClick={addScheduleTask}>添加任务</Button> |
|||
<Table columns={sColumns} dataSource={scheduleArr} /> |
|||
|
|||
<Modal |
|||
title="添加任务" |
|||
visible={visible} |
|||
onOk={() => { |
|||
scheduleForm.submit(); |
|||
}} |
|||
onCancel={() => { |
|||
setVisible(false); |
|||
}} |
|||
> |
|||
<Form |
|||
labelCol={{ span: 6 }} |
|||
wrapperCol={{ span: 18 }} |
|||
form={scheduleForm} |
|||
onFinish={async (params) => { |
|||
const { scheduleTime, ...otherValues } = params; |
|||
if (!scheduleTime) { |
|||
message.error('请选择开始时间'); |
|||
return; |
|||
} |
|||
const timeStamps = scheduleTime.map((x: { time: Moment }) => { |
|||
return x.valueOf(); |
|||
}); |
|||
try { |
|||
await addScheduleV2({ scheduleTime: timeStamps, ...otherValues }); // 将时间戳作为参数传递给后端
|
|||
} catch { |
|||
return; |
|||
} |
|||
message.success('任务提交成功'); |
|||
fetchScheduleList(); |
|||
setVisible(false); |
|||
}} |
|||
> |
|||
<Form.Item label="应用" name="appId"> |
|||
<Select |
|||
mode="multiple" |
|||
options={appArr.map((app) => ({ |
|||
label: app.name, |
|||
value: app.id, |
|||
}))} |
|||
></Select> |
|||
</Form.Item> |
|||
<Form.Item name="incomeYuan" label="金额(元)"> |
|||
<Input /> |
|||
</Form.Item> |
|||
<Form.Item name="scheduleTime" label="开始时间"> |
|||
<DatePicker multiple format="YYYY-MM-DD HH:mm" showTime={{ format: 'HH:mm' }} /> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
</div> |
|||
</> |
|||
); |
|||
}; |
|||
|
|||
export default MockScheduleManagement; |
Loading…
Reference in new issue