diff --git a/web/client/src/components/setup.jsx b/web/client/src/components/setup.jsx
index 41d8792..ce0a719 100644
--- a/web/client/src/components/setup.jsx
+++ b/web/client/src/components/setup.jsx
@@ -5,12 +5,13 @@ import {
Checkbox,
} from "@douyinfe/semi-ui";
-function Setup (props) {
+function Setup(props) {
const {
close,
tableType,
tableList,
- length
+ length,
+ objWidth
} = props;
const [check, setCheck] = useState([]);
@@ -22,7 +23,7 @@ function Setup (props) {
setCheck(checkItem ? JSON.parse(checkItem) : [])
ischeck();
}, []);
- function ischeck (value) {
+ function ischeck(value) {
if (check.length >= length) {
if (check.includes(value)) {
return false;
@@ -57,7 +58,7 @@ function Setup (props) {
}
visible={true}
- style={{ width: 600 }}
+ style={{ width: objWidth?.modalWidth || 600 }}
onOk={() => {
localStorage.setItem(tableType, JSON.stringify(check));
close();
@@ -82,7 +83,7 @@ function Setup (props) {
{item.title}
-
+
{item.list?.map((itm) => {
return (
{
+ const { dispatch, actions } = props
+ const { } = actions;
+ const [keywordTarget, setKeywordTarget] = useState('contractNo');
+ const [keyword, setKeyword] = useState('');//搜索内容
+ const [limits, setLimits] = useState()//每页实际条数
+ const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
+ const [tableData, setTableData] = useState([]);
+ const [importModalV, setImportModalV] = useState(false);
- const columns = [
- {
- title: '序号',
- dataIndex: 'index',
- render: (text, record, index) => index + 1
- },
- ];
- const data = [];
+ const [setup, setSetup] = useState(false);//表格设置是否显现
+ const [setupp, setSetupp] = useState([]);//实际显示的表格列表
+ const CONTRACTDETAILS = "contractDetails";
+ const renderColumns = (columnKeys) => {
+ let columns = [];
+ Object.keys(columnKeys).map(key => {
+ tableList[0].list.push({ name: columnKeys[key], value: key });
+ switch (key) {
+ default:
+ columns.push({
+ title: columnKeys[key], dataIndex: key, key: key,
+ render: (text, record) => text === 0 ? text : text ? text : '—', width: 32 + columnKeys[key].length * 16
+ });
+ break;
+ }
+ })
+ return columns;
+ }
+ const tableList = [{
+ title: '基础信息',
+ list: []
+ }];
+ const columns = renderColumns(contractDetailsColumnKeys);
+ function seachValueChange(value) {
+ setKeyword(value)
+ }
+ useEffect(() => {
+ localStorage.getItem(CONTRACTDETAILS) == null
+ ? localStorage.setItem(
+ CONTRACTDETAILS,
+ JSON.stringify(['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a10', 'a11', 'a12', 'a13', 'a14', 'a15', 'a16'])
+ )
+ : "";
+ attribute();
+ }, []);
+ //获取表格属性设置
+ function attribute() {
+ const arr = localStorage.getItem(CONTRACTDETAILS)
+ ? JSON.parse(localStorage.getItem(CONTRACTDETAILS))
+ : [];
+ let newColumns = [];
+ for (let i = 0; i < columns.length; i++) {
+ if (arr.indexOf(columns[i].key) > -1) {
+ newColumns.push(columns[i]);
+ }
+ }
+ setSetupp(newColumns);
+ }
+ useEffect(() => {
+
+ }, [query])
+ function handleRow(record, index) {// 给偶数行设置斑马纹
+ if (index % 2 === 0) {
+ return {
+ style: {
+ background: '#FAFCFF',
+ }
+ };
+ } else {
+ return {};
+ }
+ }
+ const scroll = useMemo(() => ({}), []);
return (
<>
@@ -23,11 +91,116 @@ const ContractDetails = (props) => {
/
合同明细表
-
+
+
+
+
+
合同明细表
+
CONTRACT DETAILS
+
+
+
+
+
+
+
+
+
+ }
+ showClear
+ placeholder='请输入关键词搜索'
+ value={keyword}
+ style={{ width: 346 }}
+ onChange={seachValueChange}>
+
+
+
+
+
+
setSetup(true)}
+ />
+
{ setImportModalV(true); }}>
+ 导入
+
+
+ 导出全部
+
+
+
+
+
+ s)}
+ dataSource={tableData}
+ bordered={false}
+ empty="暂无数据"
+ pagination={false}
+
+ onRow={handleRow}
+ scroll={scroll}
+ />
+
+
+
+
+
+
+ 共{limits}条信息
+
+
{
+ setQuery({ limit: pageSize, page: currentPage - 1 });
+ page.current = currentPage - 1
+ }}
+ />
+
+
+
+
+
+ {
+ importModalV ? {
+ setImportModalV(false);
+ }} /> : ''
+ }
+ {setup ? (
+ {
+ setSetup(false);
+ attribute();
+ }}
+ />
+ ) : (
+ ""
+ )}
>
)
}
diff --git a/web/client/src/sections/business/containers/performanceReport/importContractDetailsModal.js b/web/client/src/sections/business/containers/performanceReport/importContractDetailsModal.js
new file mode 100644
index 0000000..a3b22c9
--- /dev/null
+++ b/web/client/src/sections/business/containers/performanceReport/importContractDetailsModal.js
@@ -0,0 +1,175 @@
+'use strict';
+import React, { useState, useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+import XLSX from 'xlsx';
+import { contractDetailsColumnKeys } from '../../constants/index';
+//下载模板和上传文件读取
+const ImportContractDetailsModal = props => {
+ const { dispatch, actions, onCancel } = props;
+ const { humanAffairs } = actions;
+ const [msg, setMsg] = useState('');
+ const [loading, setLoading] = useState('');
+ const [postData, setPostData] = useState([]);
+ //初始化
+ useEffect(() => {
+ }, []);
+
+ const confirm = () => {
+ if (postData.length) {
+ setLoading(true)
+ // dispatch(humanAffairs.addSalesMemberBulk(postData)).then(res => {
+ // if (res.success) {
+ // onCancel()
+ // }
+ // setLoading(false)
+ // })
+ } else {
+ Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 })
+ }
+ }
+
+ const dldCsvMb = () => {
+ //表头
+ let head = [];
+ Object.keys(contractDetailsColumnKeys).map(key => {
+ head.push(contractDetailsColumnKeys[key]);
+ })
+ head = head.join(',') + "\n";
+ //数据
+ //let data = 1 + ',' + 2 + ',' + 3 + ',' + 4 + ',' + 5
+ let templateCsv = "data:text/csv;charset=utf-8,\ufeff" + head;
+ //创建一个a标签
+ let link = document.createElement("a");
+ //为a标签设置属性
+ link.setAttribute("href", templateCsv);
+ link.setAttribute("download", "合同明细表导入模板.csv");
+ //点击a标签
+ link.click();
+ }
+ const download = () => {
+ dldCsvMb();
+ }
+
+ const fileLimit = '.csv';
+
+ const getFileBlob = (url) => {
+ return new Promise((resolve, reject) => {
+ let request = new XMLHttpRequest()
+ request.open("GET", url, true)
+ request.responseType = "blob"
+ request.onreadystatechange = e => {
+ if (request.readyState == 4) {
+ if (request.status == 200) {
+ if (window.FileReader) {
+ let reader = new FileReader();
+ reader.readAsBinaryString(request.response);
+ reader.onload = event => {
+ try {
+ const { result } = event.target;
+ // 以二进制流方式读取得到整份excel表格对象
+ const workbook = XLSX.read(result, {
+ type: "binary",
+ cellDates: true,//设为true,将天数的时间戳转为时间格式
+ codepage: 936//解决了乱码问题
+ });
+ let data = []; // 存储获取到的数据
+ // 遍历每张工作表进行读取(这里默认只读取第一张表)
+ for (const sheet in workbook.Sheets) {
+ if (workbook.Sheets.hasOwnProperty(sheet)) {
+ data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
+ }
+ }
+ resolve(data);//导出数据
+ } catch (e) {
+ reject("失败");
+ }
+ }
+ }
+ }
+ }
+ }
+ request.send();
+ })
+ }
+
+
+ const judgeNull = (value) => {
+ return value ? String(value).trim().replace(/\s*/g, "") : null;
+ }
+
+ return (
+ {
+ setMsg('')
+ setLoading(false)
+ setPostData([])
+ onCancel()
+ }}
+ >
+
+ {
+ setMsg('');
+ setPostData([]);
+ }}
+ customRequest={(data) => {
+ const { file, onSuccess, onError } = data
+ getFileBlob(file.url).then(res => {
+ const error = (msg) => {
+ setMsg(msg)
+ onError({ message: msg })
+ }
+ if (res.length > 1000) {
+ error('一次性上传数据行数应小于1000行,请分批上传')
+ return
+ }
+ if (!res.length) {
+ error('请填写至少一行数据')
+ return
+ }
+ let postData = [];
+ for (let i = 0; i < res.length; i++) {
+ let d = res[i];
+ let obj = {};
+ Object.keys(contractDetailsColumnKeys).map(key => {
+ obj[key] = d[contractDetailsColumnKeys[key]] || '';
+ })
+ postData.push(obj);
+ }
+ setPostData(postData)
+ let msg = '文件解析完成,点击确定按钮上传保存!'
+ setMsg(msg)
+ onSuccess({ message: msg })
+ })
+ }}>
+ } theme="light">
+ 请选择文件
+
+
+ {msg}
+ 最大不超过200M,导入文件需与
+ download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板
+ 一致
+
+
+ )
+}
+
+function mapStateToProps(state) {
+ const { auth, global } = state;
+ return {
+ user: auth.user,
+ actions: global.actions,
+ }
+}
+
+export default connect(mapStateToProps)(ImportContractDetailsModal);
\ No newline at end of file
diff --git a/web/client/src/sections/business/containers/performanceReport/importInvoicingDetailsModal.js b/web/client/src/sections/business/containers/performanceReport/importInvoicingDetailsModal.js
new file mode 100644
index 0000000..cba870b
--- /dev/null
+++ b/web/client/src/sections/business/containers/performanceReport/importInvoicingDetailsModal.js
@@ -0,0 +1,175 @@
+'use strict';
+import React, { useState, useEffect } from 'react';
+import { connect } from 'react-redux';
+import { Modal, Form, Button, Notification } from '@douyinfe/semi-ui';
+import { IconUpload } from '@douyinfe/semi-icons';
+import XLSX from 'xlsx';
+import { invoicingDetailsColumnKeys } from '../../constants/index';
+//下载模板和上传文件读取
+const ImportInvoicingDetailsModal = props => {
+ const { dispatch, actions, onCancel } = props;
+ const { humanAffairs } = actions;
+ const [msg, setMsg] = useState('');
+ const [loading, setLoading] = useState('');
+ const [postData, setPostData] = useState([]);
+ //初始化
+ useEffect(() => {
+ }, []);
+
+ const confirm = () => {
+ if (postData.length) {
+ setLoading(true)
+ dispatch(humanAffairs.addSalesMemberBulk(postData)).then(res => {
+ if (res.success) {
+ onCancel()
+ }
+ setLoading(false)
+ })
+ } else {
+ Notification.warning({ content: '没有数据可以提交,请上传数据文件', duration: 2 })
+ }
+ }
+
+ const dldCsvMb = () => {
+ //表头
+ let head = [];
+ Object.keys(invoicingDetailsColumnKeys).map(key => {
+ head.push(invoicingDetailsColumnKeys[key]);
+ })
+ head = head.join(',') + "\n";
+ //数据
+ //let data = 1 + ',' + 2 + ',' + 3 + ',' + 4 + ',' + 5
+ let templateCsv = "data:text/csv;charset=utf-8,\ufeff" + head;
+ //创建一个a标签
+ let link = document.createElement("a");
+ //为a标签设置属性
+ link.setAttribute("href", templateCsv);
+ link.setAttribute("download", "开票明细表导入模板.csv");
+ //点击a标签
+ link.click();
+ }
+ const download = () => {
+ dldCsvMb();
+ }
+
+ const fileLimit = '.csv';
+
+ const getFileBlob = (url) => {
+ return new Promise((resolve, reject) => {
+ let request = new XMLHttpRequest()
+ request.open("GET", url, true)
+ request.responseType = "blob"
+ request.onreadystatechange = e => {
+ if (request.readyState == 4) {
+ if (request.status == 200) {
+ if (window.FileReader) {
+ let reader = new FileReader();
+ reader.readAsBinaryString(request.response);
+ reader.onload = event => {
+ try {
+ const { result } = event.target;
+ // 以二进制流方式读取得到整份excel表格对象
+ const workbook = XLSX.read(result, {
+ type: "binary",
+ cellDates: true,//设为true,将天数的时间戳转为时间格式
+ codepage: 936//解决了乱码问题
+ });
+ let data = []; // 存储获取到的数据
+ // 遍历每张工作表进行读取(这里默认只读取第一张表)
+ for (const sheet in workbook.Sheets) {
+ if (workbook.Sheets.hasOwnProperty(sheet)) {
+ data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
+ }
+ }
+ resolve(data);//导出数据
+ } catch (e) {
+ reject("失败");
+ }
+ }
+ }
+ }
+ }
+ }
+ request.send();
+ })
+ }
+
+
+ const judgeNull = (value) => {
+ return value ? String(value).trim().replace(/\s*/g, "") : null;
+ }
+
+ return (
+ {
+ setMsg('')
+ setLoading(false)
+ setPostData([])
+ onCancel()
+ }}
+ >
+
+ {
+ setMsg('');
+ setPostData([]);
+ }}
+ customRequest={(data) => {
+ const { file, onSuccess, onError } = data
+ getFileBlob(file.url).then(res => {
+ const error = (msg) => {
+ setMsg(msg)
+ onError({ message: msg })
+ }
+ if (res.length > 1000) {
+ error('一次性上传数据行数应小于1000行,请分批上传')
+ return
+ }
+ if (!res.length) {
+ error('请填写至少一行数据')
+ return
+ }
+ let postData = [];
+ for (let i = 0; i < res.length; i++) {
+ let d = res[i];
+ let obj = {};
+ Object.keys(invoicingDetailsColumnKeys).map(key => {
+ obj[key] = d[invoicingDetailsColumnKeys[key]] || '';
+ })
+ postData.push(obj);
+ }
+ setPostData(postData)
+ let msg = '文件解析完成,点击确定按钮上传保存!'
+ setMsg(msg)
+ onSuccess({ message: msg })
+ })
+ }}>
+ } theme="light">
+ 请选择文件
+
+
+ {msg}
+ 最大不超过200M,导入文件需与
+ download()} style={{ cursor: 'pointer', color: '#0066FF' }}>导入模板
+ 一致
+
+
+ )
+}
+
+function mapStateToProps(state) {
+ const { auth, global } = state;
+ return {
+ user: auth.user,
+ actions: global.actions,
+ }
+}
+
+export default connect(mapStateToProps)(ImportInvoicingDetailsModal);
\ No newline at end of file
diff --git a/web/client/src/sections/business/containers/performanceReport/invoicingDetails.jsx b/web/client/src/sections/business/containers/performanceReport/invoicingDetails.jsx
index 34660cf..e677485 100644
--- a/web/client/src/sections/business/containers/performanceReport/invoicingDetails.jsx
+++ b/web/client/src/sections/business/containers/performanceReport/invoicingDetails.jsx
@@ -1,18 +1,86 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useRef, useMemo } from 'react';
import { connect } from 'react-redux';
-import { Table } from '@douyinfe/semi-ui';
+import { Select, Input, Button, Table, Pagination, Skeleton } from '@douyinfe/semi-ui';
+import { SkeletonScreen, Setup } from "$components";
+import { IconSearch } from '@douyinfe/semi-icons';
+import ImportInvoicingDetailsModal from './importInvoicingDetailsModal';
+import { invoicingDetailsColumnKeys } from '../../constants/index';
import '../../style.less';
+import moment from 'moment'
const InvoicingDetails = (props) => {
+ const { dispatch, actions } = props
+ const { } = actions;
+ const [keywordTarget, setKeywordTarget] = useState('contractNo');
+ const [keyword, setKeyword] = useState('');//搜索内容
+ const [limits, setLimits] = useState()//每页实际条数
+ const [query, setQuery] = useState({ limit: 10, page: 0 }); //页码信息
+ const [tableData, setTableData] = useState([]);
+ const [importModalV, setImportModalV] = useState(false);
- const columns = [
- {
- title: '序号',
- dataIndex: 'index',
- render: (text, record, index) => index + 1
- },
- ];
- const data = [];
+ const [setup, setSetup] = useState(false);//表格设置是否显现
+ const [setupp, setSetupp] = useState([]);//实际显示的表格列表
+ const INVOICINGDETAILS = "invoicingDetails";
+ const renderColumns = (columnKeys) => {
+ let columns = [];
+ Object.keys(columnKeys).map(key => {
+ tableList[0].list.push({ name: columnKeys[key], value: key });
+ switch (key) {
+ default:
+ columns.push({
+ title: columnKeys[key], dataIndex: key, key: key,
+ render: (text, record) => text === 0 ? text : text ? text : '—', width: 32 + columnKeys[key].length * 16
+ });
+ break;
+ }
+ })
+ return columns;
+ }
+ const tableList = [{
+ title: '基础信息',
+ list: []
+ }];
+ const columns = renderColumns(invoicingDetailsColumnKeys);
+ function seachValueChange(value) {
+ setKeyword(value)
+ }
+ useEffect(() => {
+ localStorage.getItem(INVOICINGDETAILS) == null
+ ? localStorage.setItem(
+ INVOICINGDETAILS,
+ JSON.stringify(['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a10', 'a11', 'a13'])
+ )
+ : "";
+ attribute();
+ }, []);
+ //获取表格属性设置
+ function attribute() {
+ const arr = localStorage.getItem(INVOICINGDETAILS)
+ ? JSON.parse(localStorage.getItem(INVOICINGDETAILS))
+ : [];
+ let newColumns = [];
+ for (let i = 0; i < columns.length; i++) {
+ if (arr.indexOf(columns[i].key) > -1) {
+ newColumns.push(columns[i]);
+ }
+ }
+ setSetupp(newColumns);
+ }
+ useEffect(() => {
+
+ }, [query])
+ function handleRow(record, index) {// 给偶数行设置斑马纹
+ if (index % 2 === 0) {
+ return {
+ style: {
+ background: '#FAFCFF',
+ }
+ };
+ } else {
+ return {};
+ }
+ }
+ const scroll = useMemo(() => ({}), []);
return (
<>
@@ -23,11 +91,114 @@ const InvoicingDetails = (props) => {
/
开票明细表
-
+
+
+
+
+
开票明细表
+
INVOICING DETAILS
+
+
+
+
+
+
+
+
+
+ }
+ showClear
+ placeholder='请输入关键词搜索'
+ value={keyword}
+ style={{ width: 346 }}
+ onChange={seachValueChange}>
+
+
+
+
+
+
setSetup(true)}
+ />
+
{ setImportModalV(true); }}>
+ 导入
+
+
+ 导出全部
+
+
+
+
+
+ s)}
+ dataSource={tableData}
+ bordered={false}
+ empty="暂无数据"
+ pagination={false}
+
+ onRow={handleRow}
+ scroll={scroll}
+ />
+
+
+
+
+
+
+ 共{limits}条信息
+
+
{
+ setQuery({ limit: pageSize, page: currentPage - 1 });
+ page.current = currentPage - 1
+ }}
+ />
+
+
+
+
+
+ {
+ importModalV ? {
+ setImportModalV(false);
+ }} /> : ''
+ }
+ {setup ? (
+ {
+ setSetup(false);
+ attribute();
+ }}
+ />
+ ) : (
+ ""
+ )}
>
)
}