知识库文件接口联调

This commit is contained in:
zhaofengchao 2024-01-15 14:28:48 +08:00
parent cf4a0417b7
commit e094f99344
23 changed files with 435 additions and 1039 deletions

View file

@ -0,0 +1,72 @@
import { connect } from 'umi';
import i18n from 'i18next';
import { useTranslation, Trans } from 'react-i18next'
import { Input, Modal, Form } from 'antd'
import { rsaPsw } from '@/utils'
import styles from './index.less';
type FieldType = {
name?: string;
};
const Index = ({ kFModel, dispatch, getKfList, kb_id }) => {
const { isShowCEFwModal } = kFModel
const { t } = useTranslation()
const handleCancel = () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowCEFwModal: false
}
});
};
const [form] = Form.useForm()
const handleOk = async () => {
try {
const values = await form.validateFields();
dispatch({
type: 'kFModel/document_create',
payload: {
name: values.name,
kb_id
},
callback: () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowCEFwModal: false
}
});
getKfList && getKfList()
}
});
} catch (errorInfo) {
console.log('Failed:', errorInfo);
}
};
return (
<Modal title="Basic Modal" open={isShowCEFwModal} onOk={handleOk} onCancel={handleCancel}>
<Form
form={form}
name="validateOnly"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
style={{ maxWidth: 600 }}
autoComplete="off"
>
<Form.Item<FieldType>
label="文件名"
name="name"
rules={[{ required: true, message: 'Please input name!' }]}
>
<Input />
</Form.Item>
</Form>
</Modal >
);
}
export default connect(({ kFModel, loading }) => ({ kFModel, loading }))(Index);

View file

@ -1,110 +1,96 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { connect, useNavigate, useLocation } from 'umi'
import { Space, Table, Tag, Input, Button, Switch, Popover, Dropdown, } from 'antd';
import type { MenuProps } from 'antd';
import { PlusOutlined, DownOutlined } from '@ant-design/icons'
import { debounce } from 'lodash';
import type { ColumnsType } from 'antd/es/table';
import Upload from './upload'
import CreateEPModal from './createEFileModal'
import styles from './idnex.less'
interface DataType {
key: string;
name: string;
age: number;
address: string;
chunk_num: string;
token_num: number;
update_date: string;
size: string;
status: boolean;
id: string
}
const onChangeStatus = () => { }
const data: DataType[] = [
{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
status: true,
},
{
key: '2',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
status: true,
},
{
key: '3',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
status: true,
},
{
key: '4',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
status: true,
},
{
key: '5',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
status: true,
},
{
key: '6',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
status: true,
}, {
key: '7',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
status: true,
},
{
key: '8',
name: 'Jim Green',
age: 42,
address: 'London No. 1 Lake Park',
status: true,
},
{
key: '9',
name: 'Joe Black',
age: 32,
address: 'Sydney No. 1 Lake Park',
status: true,
},
];
const App: React.FC = () => {
const Index: React.FC = ({ kFModel, dispatch, id }) => {
const { data, loading } = kFModel
const [inputValue, setInputValue] = useState('')
const [loading, setLoading] = useState(false)
const [doc_id, setDocId] = useState('0')
const changeValue = (value: string) => {
{
console.log(value)
setLoading(false)
}
}
const getKfList = () => {
dispatch({
type: 'kFModel/getKfList',
payload: {
kb_id: id
}
});
}
useEffect(() => {
if (id) {
getKfList()
}
}, [id])
const debounceChange = debounce(changeValue, 300)
const debounceCallback = useCallback((value: string) => debounceChange(value), [])
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const value = e.target.value
setLoading(true)
setInputValue(value)
debounceCallback(e.target.value)
}
const onChangeStatus = (e, doc_id) => {
console.log(doc_id)
dispatch({
type: 'kFModel/updateDocumentStatus',
payload: {
doc_id,
status: Number(e)
},
callback() {
getKfList()
}
});
}
const onRmDocument = (doc_id) => {
dispatch({
type: 'kFModel/document_rm',
payload: {
doc_id
},
callback() {
getKfList()
}
});
}
const showCEFModal = () => {
dispatch({
type: 'kFModel/updateState',
payload: {
isShowCEFwModal: true
}
});
};
const actionItems: MenuProps['items'] = [
{
key: '1',
label: (
<div>
<Button type="link"></Button>
<Upload kb_id={id} getKfList={getKfList} />
</div>
),
@ -113,13 +99,36 @@ const App: React.FC = () => {
key: '2',
label: (
<div>
<Button type="link"> </Button>
<Button type="link" onClick={showCEFModal}> </Button>
</div>
),
// disabled: true,
},
];
const getItems = useCallback((id) => {
console.log(id)
return [
{
key: '1',
label: (
<div>
<Button type="link"> </Button>
</div>
),
},
{
key: '2',
label: (
<div>
<Button type="link" onClick={() => onRmDocument(id)}> </Button>
</div>
),
// disabled: true,
},
];
}, [])
const columns: ColumnsType<DataType> = [
{
title: '名称',
@ -130,14 +139,20 @@ const App: React.FC = () => {
},
{
title: '数据总量',
dataIndex: 'total',
key: 'total',
dataIndex: 'chunk_num',
key: 'chunk_num',
className: `${styles.column}`
},
{
title: 'Tokens',
dataIndex: 'tokens',
key: 'tokens',
dataIndex: 'token_num',
key: 'token_num',
className: `${styles.column}`
},
{
title: '文件大小',
dataIndex: 'size',
key: 'size',
className: `${styles.column}`
},
{
@ -145,9 +160,11 @@ const App: React.FC = () => {
key: 'status',
dataIndex: 'status',
className: `${styles.column}`,
render: (_, { status }) => (
render: (_, { status, id }) => (
<>
<Switch defaultChecked onChange={onChangeStatus} />
<Switch defaultChecked={status == 1} onChange={(e) => {
onChangeStatus(e, id)
}} />
</>
),
},
@ -157,8 +174,8 @@ const App: React.FC = () => {
className: `${styles.column}`,
render: (_, record) => (
<Space size="middle">
<Dropdown menu={{ items: actionItems }}>
<a>
<Dropdown menu={{ items: getItems(record.id) }}>
<a onClick={() => { setDocId(record.id) }}>
<DownOutlined />
</a>
</Dropdown>
@ -180,8 +197,9 @@ const App: React.FC = () => {
</div>
</div>
<Table columns={columns} dataSource={data} loading={loading} pagination={false} scroll={{ scrollToFirstRowOnChange: true, x: true }} />
<Table rowKey='id' columns={columns} dataSource={data} loading={loading} pagination={false} scroll={{ scrollToFirstRowOnChange: true, x: true }} />
<CreateEPModal getKfList={getKfList} kb_id={id} />
</>
};
export default App;
export default connect(({ kFModel, loading }) => ({ kFModel, loading }))(Index);

View file

@ -0,0 +1,111 @@
import { message } from 'antd';
import { addParam } from '@/utils';
import kbService from '@/services/kbService';
const Model = {
namespace: 'kFModel',
state: {
isShowCEFwModal: false,
isShowTntModal: false,
loading: false,
tenantIfo: {}
},
subscriptions: {
setup({ dispatch, history }) {
history.listen(location => {
});
}
},
effects: {
* createKf({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.createKb, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
}
},
* updateKf({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.updateKb, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
}
},
*getKfDetail({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.get_kb_detail, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
// localStorage.setItem('userInfo',res.)
callback && callback(res)
}
},
*getKfList({ payload = {} }, { call, put }) {
yield put({
type: 'updateState',
payload: {
loading: true
}
});
const { data, response } = yield call(kbService.get_document_list, payload);
const { retcode, data: res, retmsg } = data
yield put({
type: 'updateState',
payload: {
loading: false
}
});
if (retcode === 0) {
yield put({
type: 'updateState',
payload: {
data: res
}
});
}
},
*updateDocumentStatus({ payload = {}, callback }, { call, put }) {
yield put({
type: 'updateState',
payload: {
loading: true
}
});
const { data, response } = yield call(kbService.document_change_status, payload);
const { retcode, data: res, retmsg } = data
yield put({
type: 'updateState',
payload: {
loading: false
}
});
callback && callback()
},
*document_rm({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.document_rm, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
callback && callback()
}
},
*document_create({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.document_create, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
callback && callback()
}
},
},
reducers: {
updateState(state, { payload }) {
return {
...state,
...payload
};
}
}
};
export default Model;

View file

@ -0,0 +1,30 @@
import React from 'react';
import { UploadOutlined } from '@ant-design/icons';
import type { UploadProps } from 'antd';
import { Button, message, Upload } from 'antd';
import uploadService from '@/services/uploadService'
const App: React.FC = (props) => {
const { kb_id, getKfList } = props
console.log(kb_id)
const createRequest = async function ({ file, onSuccess, onError }) {
const { retcode, data } = await uploadService.uploadFile(file, kb_id);
if (retcode === 0) {
onSuccess(data, file);
} else {
onError(data);
}
getKfList && getKfList()
};
const uploadProps: UploadProps = {
customRequest: createRequest,
showUploadList: false,
};
return (<Upload {...uploadProps} >
<Button type="link"></Button>
</Upload>)
}
export default App;

View file

@ -44,35 +44,62 @@ const Index: React.FC = ({ settingModel, kSModel, dispatch, ...props }) => {
const { tenantIfo = {} } = settingModel
const { parser_ids = '', embd_id = '' } = tenantIfo
const { id = '' } = props
const [form] = Form.useForm();
useEffect(() => {
dispatch({
type: 'settingModel/getTenantInfo',
payload: {
}
});
}, [])
const [selectedTag, setSelectedTag] = useState('')
const onFinish = (values: any) => {
console.log(values);
if (id) {
dispatch({
type: 'kSModel/updateKb',
type: 'settingModel/getTenantInfo',
payload: {
...values,
parser_id: selectedTag,
kb_id: id
}
});
} else {
dispatch({
type: 'kSModel/createKb',
type: 'kSModel/getKbDetail',
payload: {
...values,
parser_id: selectedTag
kb_id: id
},
callback(detail) {
console.log(detail)
const { description, name, permission, embd_id } = detail
form.setFieldsValue({ description, name, permission, embd_id })
setSelectedTag(detail.parser_id)
}
});
}
}, [id])
const [selectedTag, setSelectedTag] = useState('')
const values = Form.useWatch([], form);
console.log(values, '......变化')
const onFinish = () => {
form.validateFields().then(
() => {
if (id) {
dispatch({
type: 'kSModel/updateKb',
payload: {
...values,
parser_id: selectedTag,
kb_id: id,
embd_id: undefined
}
});
} else {
dispatch({
type: 'kSModel/createKb',
payload: {
...values,
parser_id: selectedTag
}
});
}
},
() => {
},
);
};
@ -86,8 +113,8 @@ const Index: React.FC = ({ settingModel, kSModel, dispatch, ...props }) => {
return <Form
{...layout}
name="nest-messages"
onFinish={onFinish}
form={form}
name="validateOnly"
style={{ maxWidth: 1000, padding: 14 }}
>
<Form.Item name='name' label="知识库名称" rules={[{ required: true }]}>
@ -108,7 +135,7 @@ const Index: React.FC = ({ settingModel, kSModel, dispatch, ...props }) => {
hasFeedback
rules={[{ required: true, message: 'Please select your country!' }]}
>
<Select placeholder="Please select a country">
<Select placeholder="Please select a country" disabled={id}>
{embd_id.split(',').map(item => {
return <Option value={item} key={item}>{item}</Option>
})}
@ -145,7 +172,7 @@ const Index: React.FC = ({ settingModel, kSModel, dispatch, ...props }) => {
</div>
</div>
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
<Button type="primary" htmlType="submit">
<Button type="primary" onClick={onFinish}>
</Button>
<Button htmlType="button" style={{ marginLeft: '20px' }}>

View file

@ -33,43 +33,14 @@ const Model = {
}
},
*getUserInfo({ payload = {} }, { call, put }) {
const { data, response } = yield call(userService.user_info, payload);
*getKbDetail({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.get_kb_detail, payload);
const { retcode, data: res, retmsg } = data
const userInfo = {
avatar: res.avatar,
name: res.nickname,
email: res.email
};
localStorage.setItem('userInfo', JSON.stringify(userInfo))
if (retcode === 0) {
// localStorage.setItem('userInfo',res.)
callback && callback(res)
}
},
*getTenantInfo({ payload = {} }, { call, put }) {
yield put({
type: 'updateState',
payload: {
loading: true
}
});
const { data, response } = yield call(userService.get_tenant_info, payload);
const { retcode, data: res, retmsg } = data
yield put({
type: 'updateState',
payload: {
loading: false
}
});
if (retcode === 0) {
yield put({
type: 'updateState',
payload: {
tenantIfo: res
}
});
}
}
},
reducers: {
updateState(state, { payload }) {

View file

@ -20,52 +20,7 @@ const Model = {
}
},
effects: {
* createKb({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.createKb, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
}
},
*getUserInfo({ payload = {} }, { call, put }) {
const { data, response } = yield call(userService.user_info, payload);
const { retcode, data: res, retmsg } = data
const userInfo = {
avatar: res.avatar,
name: res.nickname,
email: res.email
};
localStorage.setItem('userInfo', JSON.stringify(userInfo))
if (retcode === 0) {
// localStorage.setItem('userInfo',res.)
}
},
*getTenantInfo({ payload = {} }, { call, put }) {
yield put({
type: 'updateState',
payload: {
loading: true
}
});
const { data, response } = yield call(userService.get_tenant_info, payload);
const { retcode, data: res, retmsg } = data
yield put({
type: 'updateState',
payload: {
loading: false
}
});
if (retcode === 0) {
yield put({
type: 'updateState',
payload: {
tenantIfo: res
}
});
}
}
},
reducers: {
updateState(state, { payload }) {

View file

@ -63,11 +63,19 @@ const Index: React.FC = ({ knowledgeModel, dispatch }) => {
<Popconfirm
title="Delete the task"
description="Are you sure to delete this task?"
onConfirm={() => { confirm(item.id) }}
onConfirm={(e) => {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation()
confirm(item.id)
}}
okText="Yes"
cancelText="No"
>
<DeleteOutlined />
<DeleteOutlined onClick={(e) => {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation()
}} />
</Popconfirm>
</span>

View file

@ -5,8 +5,6 @@ import kbService from '@/services/kbService';
const Model = {
namespace: 'knowledgeModel',
state: {
isShowPSwModal: false,
isShowTntModal: false,
loading: false,
data: []
},
@ -26,27 +24,6 @@ const Model = {
}
},
*setting({ payload = {}, callback }, { call, put }) {
const { data, response } = yield call(kbService.setting, payload);
const { retcode, data: res, retmsg } = data
if (retcode === 0) {
message.success('密码修改成功!');
callback && callback()
}
},
*getUserInfo({ payload = {} }, { call, put }) {
const { data, response } = yield call(kbService.user_info, payload);
const { retcode, data: res, retmsg } = data
const userInfo = {
avatar: res.avatar,
name: res.nickname,
email: res.email
};
localStorage.setItem('userInfo', JSON.stringify(userInfo))
if (retcode === 0) {
// localStorage.setItem('userInfo',res.)
}
},
*getList({ payload = {} }, { call, put }) {
yield put({
type: 'updateState',
@ -70,7 +47,7 @@ const Model = {
}
});
}
}
},
},
reducers: {
updateState(state, { payload }) {

View file

@ -1,33 +0,0 @@
import api from '@/utils/api';
import registerServer from '@/utils/registerServer';
import request from '@/utils/request';
const {
create_account,
update_account,
account_detail,
getUserDetail, } = api;
const chatService = registerServer(
{
createAccount: {
url: create_account,
method: 'post'
},
updateAccount: {
url: update_account,
method: 'post'
},
getAccountDetail: {
url: account_detail,
method: 'post'
},
getUserDetail: {
url: getUserDetail,
method: 'post'
}
},
request
);
export default chatService;

View file

@ -6,9 +6,8 @@ const {
create_kb,
update_kb,
rm_kb,
update_account,
account_detail,
kb_list, } = api;
get_kb_detail,
kb_list, get_document_list, document_change_status, document_rm, document_create } = api;
const kbService = registerServer(
{
@ -24,18 +23,31 @@ const kbService = registerServer(
url: rm_kb,
method: 'post'
},
updateAccount: {
url: update_account,
method: 'post'
},
getAccountDetail: {
url: account_detail,
method: 'post'
get_kb_detail: {
url: get_kb_detail,
method: 'get'
},
getList: {
url: kb_list,
method: 'get'
}
},
get_document_list: {
url: get_document_list,
method: 'get'
},
document_change_status: {
url: document_change_status,
method: 'post'
},
document_rm: {
url: document_rm,
method: 'post'
},
document_create: {
url: document_create,
method: 'post'
},
},
request
);

View file

@ -0,0 +1,21 @@
import request from '@/utils/request';
import api from '@/utils/api';
const { upload } = api;
const uploadService = {
uploadFile: function (file, kb_id) {
const formData = new FormData();
formData.append('file', file);
formData.append('kb_id', kb_id);
const options = {
method: 'post',
data: formData
};
return request(upload, options);
}
};
export default uploadService;

View file

@ -1,130 +0,0 @@
import { debounce } from 'lodash';
import semver from 'semver';
import merge from 'lodash/merge';
import isPlainObject from 'lodash/isPlainObject';
class StorageManager {
constructor(store, options) {
options = Object.assign(
{},
{
lazy: true,
namespace: 'STORAGE_MANAGER',
version: '0.0.0'
},
options
);
this.namespace = options.namespace;
this.isLazy = options.lazy;
this._store = store;
this.loaded = false;
this.version = options.version;
this.cache = {};
this.initStorage();
}
initStorage() {
if (!isPlainObject(this._store)) {
throw new Error('store should be a plain object');
}
if (this.checkStore()) {
this.setItem(this.namespace, this.buildData(this._store));
}
this.initStore();
if (!this.isLazy) {
this.fillCache();
}
}
initStore() {
const keys = Object.keys(this._store);
let i = keys.length;
while (i--) {
this.proxy(keys[i]);
}
}
proxy(key) {
Object.defineProperty(this, key, {
configurable: true,
enumerable: true,
get: () => {
if (!this.loaded && this.isLazy) {
this.fillCache();
}
return this.cache[key];
},
set: val => {
if (!this.loaded && this.isLazy) {
this.fillCache();
}
this.cache[key] = val;
}
});
}
observe(data) {
if (Object.prototype.toString.call(data) !== '[object Object]') {
return;
}
let keys = Object.keys(data);
for (let i = 0; i < keys.length; i++) {
this.defineReactive(data, keys[i], data[keys[i]]);
}
}
defineReactive(data, key, val) {
this.observe(val);
Object.defineProperty(data, key, {
configurable: true,
enumerable: true,
get: () => {
return val;
},
set: newVal => {
if (val === newVal) {
return;
}
val = newVal;
this.observe(newVal);
this.debounceSet();
}
});
}
fillCache() {
this.cache = merge({}, this._store, this.getItem(this.namespace).data);
this.loaded = true;
this.observe(this.cache);
}
checkStore() {
const item = this.getItem(this.namespace);
return !!(!item || semver.lt(item.version, this.version));
}
buildData(data) {
return {
version: this.version,
data
};
}
debounceSet() {
return debounce(this.setItem, 200)(this.namespace, this.buildData(this.cache));
}
setItem(key, value) {
window.localStorage.setItem(key, JSON.stringify(value));
}
getItem(key) {
try {
return JSON.parse(window.localStorage.getItem(key));
} catch (e) {
return null;
}
}
}
export default StorageManager;

View file

@ -1,4 +1,4 @@
import config from '@/utils/config';
let api_host = `/v1`;
@ -7,11 +7,7 @@ let api_host = `/v1`;
export { api_host };
export default {
icp: config.COPY_RIGHT_TEXT,
upload: `${api_host}/upload`,
uploadZip: `${api_host}/uploadZip`,
segment_upload: `${api_host}/uploadPopulation`,
// 用户
login: `${api_host}/user/login`,
@ -19,19 +15,19 @@ export default {
setting: `${api_host}/user/setting`,
user_info: `${api_host}/user/info`,
tenant_info: `${api_host}/user/tenant_info`,
user: `${api_host}/user/validate`,
getUrl: `${api_host}/requestGetUrl`,
getAdPermits: `${api_host}/adServer/getAdPermits`,
//知识库管理
kb_list: `${api_host}/kb/list`,
create_kb: `${api_host}/kb/create`,
update_kb: `${api_host}/kb/update`,
rm_kb: `${api_host}/kb/rm`,
update_account: `${api_host}/user/updateUserAccountSso`,
account_detail: `${api_host}/user/getUserDetail`,
getUserDetail: `${api_host}/user/getUserDetail`,
account_status: `${api_host}/user/updateAccountStatus`,
sign_agreement: `${api_host}/user/updateUserSignAgreement`,
get_kb_detail: `${api_host}/kb/detail`,
// 上传
upload: `${api_host}/document/upload`,
get_document_list: `${api_host}/document/list`,
document_change_status: `${api_host}/document/change_status`,
document_rm: `${api_host}/document/rm`,
document_create: `${api_host}/document/create`,
};

View file

@ -1,35 +0,0 @@
export default {
API_HOST: 'mpapi.martechlab.cn',
SSO_LOGIN_HOST: 'sso.martechlab.cn',
SYS_ADMIN_HOST: 'sysadmin.martechlab.cn',
PRODUCTION_HOST: 'adv.martechlab.cn',
EASY_REPORT_API_HOST: 'api.easyreport.fancydsp.com',
HIDE_MENU_IDS: [],
BROWSER_TITLE_TEXT: 'docgpt',
COPY_RIGHT_TEXT: '沪xxxxx',
HIDE_QRCODE: false,
HIDE_DOC: false,
HIDE_WEB_SITE: false,
HIDE_COPY_RIGHT: false,
HIDE_VERSION: false,
LOGO_WIDTH: '116px',
LOGO_HEIGHT: '19px',
UMI_PUBLIC_PATH_HOST: 'mpcdn.martechlab.cn',
WHITE_API: [
'api.easyreport.fancydsp.com',
'sso.martechlab.cn',
'test41-sso.amnetapi.com',
'test41-sysadmin.amnetapi.com',
'sysadmin.martechlab.cn'
],
pages: ['/login'],
};

View file

@ -1,241 +0,0 @@
import { Modal, Form } from 'antd';
import router from 'umi/router';
export function getMonospaceLength(content = '') {
let total = 0;
for (let c of content) {
if (/[\x00-\xff]/.test(c)) {
total += 0.5;
} else {
total += 1;
}
}
return total;
}
export const pickRecordFormList = function (list = [], ids = [], key = 'id') {
let results = [];
for (let id of ids) {
let find = list.find(record => record[key] === id);
if (find != null) {
results.push(find);
}
}
return results;
};
export function extractFieldsValues(fields) {
let results = {};
Object.keys(fields).forEach(key => {
results[key] = fields[key]?.value;
});
return results;
}
export function getTableData(response) {
const { code, data } = response;
const { count = 0, list = [] } = data || {};
if (code === 0) {
return {
total: count,
list
};
} else {
return {
total: 0,
list: []
};
}
}
export const getReportData = response => {
const { code, data } = response;
const { rows, total, aggregation = {} } = data || {};
if (code === 0 && rows.length > 0) {
return {
total,
list: [{ name: '合计', ...aggregation }, ...rows]
};
} else {
return {
total: 0,
list: []
};
}
};
/**
* 亿
* @param value
*/
export const bigNumberTransform = value => {
if (!value || parseInt(value) < 1000) {
return value;
}
const newValue = ['', '', ''];
let fr = 1000;
let num = 3;
let text1 = '';
let fm = 1;
while (value / fr >= 1) {
fr *= 10;
num += 1;
// console.log('数字', value / fr, 'num:', num)
}
if (num <= 4) {
// 千
newValue[0] = parseInt(value / 1000) + '';
newValue[1] = '千';
} else if (num <= 8) {
// 万
text1 = parseInt(num - 4) / 3 > 1 ? '千万' : '万';
// tslint:disable-next-line:no-shadowed-variable
fm = text1 === '万' ? 10000 : 10000000;
if (value % fm === 0) {
newValue[0] = parseInt(value / fm) + '';
} else {
newValue[0] = parseFloat(value / fm).toFixed(1) + '';
}
newValue[1] = text1;
} else if (num <= 16) {
// 亿
text1 = (num - 8) / 3 > 1 ? '千亿' : '亿';
text1 = (num - 8) / 4 > 1 ? '万亿' : text1;
text1 = (num - 8) / 7 > 1 ? '千万亿' : text1;
// tslint:disable-next-line:no-shadowed-variable
fm = 1;
if (text1 === '亿') {
fm = 100000000;
} else if (text1 === '千亿') {
fm = 100000000000;
} else if (text1 === '万亿') {
fm = 1000000000000;
} else if (text1 === '千万亿') {
fm = 1000000000000000;
}
if (value % fm === 0) {
newValue[0] = parseInt(value / fm) + '';
} else {
newValue[0] = parseFloat(value / fm).toFixed(1) + '';
}
newValue[1] = text1;
}
if (value < 1000) {
newValue[0] = value + '';
newValue[1] = '';
}
return newValue.join('');
};
export const handleCancel = route => {
Modal.confirm({
title: '确认返回?',
content: '当前处于编辑状态,返回无法保存当前已编辑内容',
okText: '确认',
cancelText: '取消',
onOk() {
if (route) {
router.push(route);
} else {
router.goBack();
}
},
onCancel() {}
});
};
export function createFormData(values) {
let formData = {};
Object.keys(values || {}).forEach(fieldName => {
formData[fieldName] = Form.createFormField({
value: values[fieldName]
});
});
return formData;
}
/**
* ...
* @param {String} text String
* @param {Number} limit Number
* @return {String} String
*/
const getShortString = (text, limit) => {
let _temp = text || '';
const _limit = parseInt(limit, 10);
if (_temp.length > _limit) {
_temp = _temp.slice(0, _limit) + '...';
}
return _temp;
};
export const FormatString = {
getShortString
};
export function GetQueryString(payload = {}) {
let newPayload = {};
Object.keys(payload)
.sort()
.forEach(key => {
newPayload[key] = payload[key];
});
return JSON.stringify(newPayload);
}
export function ParseQueryString(queryStr) {
let payload;
try {
payload = JSON.parse(queryStr);
} catch (e) {
payload = {};
}
return payload;
}
export function GetUrlQueryString(params = {}) {
return Object.keys(params)
.map(k => {
if (Array.isArray(params[k])) {
return params[k].map(v => `${encodeURIComponent(k)}[]=${v}`).join('&');
} else {
return encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
}
})
.join('&');
}
export function IsSameProperty(record, property) {
let isSame = true;
for (let key in property) {
if (record[key] !== property[key]) {
isSame = false;
break;
}
}
return isSame;
}
export function getFormContainer(ref) {
if (ref && ref.current && ref.current.closest) {
return ref.current.closest('form');
} else {
return document.getElementById('form-container');
}
}
export const toTransformSize = size => {
size = parseInt(size, 10);
if (typeof size !== 'number' || size === 0 || !size) return '-';
if (size < 1024) return `${size} B`;
const sizeKB = Math.floor(size / 1024);
if (sizeKB < 1024) return `${sizeKB} KB`;
const sizeMB = Math.floor(sizeKB / 1024);
if (sizeMB < 1024) return `${sizeMB} MB`;
const sizeGB = Math.floor(sizeMB / 1024);
return `${sizeGB} GB`;
};

View file

@ -4,150 +4,10 @@
* @return {Object}
*/
// import numeral from 'numeral';
import store from '@/utils/persistStore';
import JSEncrypt from 'jsencrypt';
import { Base64 } from 'js-base64';
export const parseQuery = (url = window.location.search, isNoCaseSensitive: boolean) => {
return window.g_history.location.query;
let arr, part;
const query = {};
//去掉首位空格
if (!(url || '').replace(/^\s+|\s+$/, '')) {
return {};
}
url = url.replace(/\S*\?/, '');
if (url) {
if (isNoCaseSensitive) {
url = url.toLocaleLowerCase();
}
arr = url.split('&');
for (let i in arr) {
part = arr[i].split('=');
query[part[0]] = decodeURIComponent(part[1]);
}
}
return query;
};
export const parseQueryForPath = url => {
if (!url) {
return {};
}
let arr, part;
const query = {};
//去掉首位空格
if (!(url || '').replace(/^\s+|\s+$/, '')) {
return {};
}
url = url.replace(/\S*\?/, '');
if (url) {
arr = url.split('&');
for (let i in arr) {
part = arr[i].split('=');
query[part[0]] = decodeURIComponent(part[1]);
}
}
return query;
};
export const param = paramObj => {
let str = [];
for (let i in paramObj) {
if (typeof paramObj[i] !== 'undefined') {
str.push(i + '=' + encodeURIComponent(paramObj[i]));
}
}
return str.join('&');
};
export const addParam = (url, params) => {
let SEARCH_REG = /\?([^#]*)/,
HASH_REG = /#(.*)/,
searchStr;
url = url || '';
let search = {},
searchMatch = url.match(SEARCH_REG);
if (searchMatch) {
search = parseQuery(searchMatch[0]);
}
//合并当前search参数
search = Object.assign(search, params);
searchStr = '?' + param(search);
//是否存在search
if (SEARCH_REG.test(url)) {
url = url.replace(SEARCH_REG, searchStr);
} else {
//是否存在hash
if (HASH_REG.test(url)) {
url = url.replace(HASH_REG, searchStr + '#' + url.match(HASH_REG)[1]);
} else {
url += searchStr;
}
}
return url;
};
const downloadWithIframe = (url: string) => {
const id = `downloadIframe${new Date().getTime()}`;
let iframe = document.createElement('iframe');
iframe.id = id;
iframe.onload = function () {
console.log('开始加载');
};
document.body.appendChild(iframe);
iframe.style.cssText = 'display:none';
const iframeDoc = iframe.contentWindow.document;
iframeDoc.open(); // 打开流
iframeDoc.write(`<iframe src="${url}"></iframe>`);
iframeDoc.write('<script>');
iframeDoc.write(
`window.onload = function() { setTimeout(function() {parent.document.body.removeChild(parent.document.getElementById("${id}"))}, 20000)}`
);
iframeDoc.write('</script>');
iframeDoc.close(); // 关闭流
};
export const getReportVersion = () => {
const erVersion = window.localStorage.getItem('EASY_REPORT_VERSION');
let version = undefined;
if (window.location.host === 'adv.martechlab.cn') {
version = '';
} else if (erVersion) {
version = erVersion;
}
return version;
};
export const delay = timeout => {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
};
export const formatRequestUrlByDomainPrefix = url => {
let prefix = store.domainPrefix || '';
if (prefix) {
prefix = `//mp${prefix}.`;
url = url.slice(2).split('.').slice(1).join('.');
}
return `${prefix}${url}`;
};
export const getWidth = () => {
return { width: window.innerWidth };
};
@ -161,8 +21,6 @@ export const rsaPsw = (password: string) => {
}
export default {
parseQuery,
downloadWithIframe,
formatRequestUrlByDomainPrefix,
getWidth
getWidth,
rsaPsw
};

View file

@ -1,51 +0,0 @@
import { formatMessage } from 'umi-plugin-react/locale';
import { check } from '@/components/Authorize/getAuth';
import memoize from 'lodash/memoize';
function formatter(data, parentName) {
if (!data) {
return null;
}
return data
.map(item => {
if (!item.name || !item.path) {
return null;
}
let locale = parentName ? `${parentName}.${item.name}` : `menu.${item.name}`;
const result = {
...item,
locale: formatMessage({
id: locale,
defaultMessage: item.name
})
};
if (item.routes) {
result.children = formatter(item.routes, locale);
}
delete result.routes;
return result;
})
.filter(item => item);
}
export const getMenuData = memoize(formatter);
const getSubMenu = item => {
// doc: add hideChildrenInMenu
if (item.children && item.children.some(child => child.name)) {
return {
...item,
children: getAuthorizedMenuData(item.children) // eslint-disable-line
};
}
return item;
};
export const getAuthorizedMenuData = (menuData, currentAuth) => {
return menuData.map(item => check(item.auth, currentAuth, getSubMenu(item))).filter(item => item);
};
export const getAuthorizeByHeader = (menuData, path) => {
const formatMenus = menuData.filter(d => d.path === path || path?.includes(d.extraKey));
return formatMenus;
};

View file

@ -1,35 +0,0 @@
import StorageManager from './StorageManager';
// 定义初始数据结构,发生改变时必须升级版本号否则会导致数据不一致
const store = {
token: '',
domainPrefix: '',
userInfo: {},
customColumns: {
campaignTable: [],
adUnitTable: [],
creativeTable: [],
vendorTable: [],
dashboardWapper: [],
toutiaoVendorTable: [],
toutiaoCampaignTable: [],
toutiaoAdUnitTable: [],
toutiaoCreativeTable: [],
materialVideosTable: [],
tencentCampaignTable: [],
tencentCreativeTable: [],
tencentAdUnitTable: [],
tencentVendorTable: []
},
vendorAuth: [],
warningRuleIds: [],
warningDate: '',
ksOldCreateTimer: '',
ttOldCreateTimer: '',
gdtCreateTimer: ''
};
// 数据结构改变时改变
const version = '1.1.1';
export default new StorageManager(store, { version });

View file

@ -1,11 +1,6 @@
/**
* request
* api : https://github.com/umijs/umi-request
*/
import { extend } from 'umi-request';
import { notification, message } from 'antd';
import store from '@/utils/persistStore';
import config from '@/utils/config';
import _ from 'lodash';
import api from '@/utils/api';

View file

@ -1,12 +0,0 @@
import { getMonospaceLength } from '@/utils/helper';
export const monospace = (rule, value, callback) => {
const length = getMonospaceLength(value);
if (rule.max > 0 && length > rule.max) {
callback(`长度不能超过${rule.max}!`);
} else if (rule.min > 0 && length < rule.min) {
callback(`长度不能小于${rule.min}!`);
} else {
callback();
}
};

View file

@ -1,40 +0,0 @@
const UpladFile = props => {
let { xhr, options } = props;
const { file, url, uploadData, headers, callback, getProgress } = options;
var form = new FormData(); // FormData 对象
form.append('file', file); // 文件对象
for (let key in uploadData) {
if (uploadData.hasOwnProperty(key)) {
form.append(key, uploadData[key]);
}
}
xhr = new XMLHttpRequest(); // XMLHttpRequest 对象
xhr.open('post', url, true); //post方式url为服务器请求地址true 该参数规定请求是否异步处理。
for (let key in headers) {
if (headers.hasOwnProperty(key)) {
xhr.setRequestHeader(key, headers[key]);
}
}
xhr.onload = evt => callback(true, JSON.parse(evt.target.response)); //请求完成
xhr.onerror = evt => callback(false, JSON.parse(evt.target.response)); //请求失败
xhr.upload.onprogress = evt => {
if (evt.lengthComputable) {
const rate = Math.round((evt.loaded / evt.total) * 100);
if (getProgress) getProgress(file.uid, rate);
}
};
xhr.send(form); //开
};
const cancleUploadFile = xhr => {
xhr.abort();
};
const upladFileProgress = props => {
const { file, url, uploadData, headers, callback, getProgress } = props;
let xhr;
UpladFile({ xhr, options: { file, url, uploadData, headers, callback, getProgress } });
};
export default upladFileProgress;

View file

@ -1,78 +0,0 @@
/* global VERSION */
import api from '@/utils/api';
import { extend } from 'umi-request';
import { notification, Button } from 'antd';
import config from '@/utils/config';
const { get_simple_version } = api;
const host = window.location.host;
const NOTIFICATION_KEY = 'VERSION';
// npm run build shiyi version
export const LOCAL_VERSION = VERSION;
/**
* extend一个request,request为同一个对象,
* */
const request = extend({
errorHandler: () => {} // 默认错误处理
});
let timer;
let timeLoad = () => {
timer = setInterval(async () => {
try {
const { code, publishVersion } = await request(get_simple_version);
code === 0 && publishVersion && checkVersion(publishVersion);
} catch (e) {}
}, 60000);
};
if (host === 'adv.martechlab.cn' || host === 'shiyi.martechlab.cn') {
if (!config.HIDE_VERSION) {
timeLoad();
}
}
/***
*
* @param publishVersion version
* @param LOCAL_VERSION versionwebpack会根据打包命令写入版本号
*/
//检查远端版本是否跟本地一致
const checkVersion = publishVersion => {
if (LOCAL_VERSION?.slice(0, 3) !== publishVersion?.slice(0, 3)) {
clearInterval(timer);
//不相等证明有弹窗提醒
notification.info({
key: NOTIFICATION_KEY,
top: 50,
duration: null,
message: <span></span>,
onClose: () => timeLoad(),
description: (
<div>
<div></div>
<div style={{ color: 'orange' }}></div>
</div>
),
btn: (
<div>
<Button
style={{ marginRight: 15 }}
onClick={() => {
notification.close(NOTIFICATION_KEY);
timeLoad();
}}
>
</Button>{' '}
<Button type="primary" onClick={() => history.go(0)}>
</Button>
</div>
)
});
}
};