Skip to content

Commit

Permalink
push
Browse files Browse the repository at this point in the history
  • Loading branch information
hfljzrxsj committed Feb 26, 2024
1 parent 30af8bc commit 92e9487
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 337 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4082,7 +4082,8 @@
"sass": "^1.63.6",
"sass-loader": "^12.6.0",
"scss-bundle": "^3.1.2",
"node-sass": "9.0.0"
"node-sass": "9.0.0",
"@rollup/plugin-commonjs": "20.0.0"
},
"devDependencies": {
"coffee-script": "^1.10.0",
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import { StrictMode } from 'react';
import MyRoute from './Route';
import { HashRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';
import SnackbarAlert from './components/SnackbarAlert';
import { CssBaseline, ScopedCssBaseline, StyledEngineProvider } from '@mui/material';
// import './history';
export const commonUseRequestParams = {
loadingDelay: 300,
throttleWait: 300,
Expand Down
2 changes: 2 additions & 0 deletions src/Route/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import OrderQuantityOfMobileTerminals from '@/pages/PurchaseQuantityMonitoring/O
import InventoryQuantity from '@/pages/InventoryMonitoring/InventoryQuantity';
import InventoryStructure from '@/pages/InventoryMonitoring/InventoryStructure';
import { lazy, Suspense } from 'react';
// import { renderRoutes } from 'react-router-config';

export enum pathString {
login = 'login',
Expand Down Expand Up @@ -134,6 +135,7 @@ export default function MyRoute () {
</Route>
))
}
{/* {renderRoutes(menuItems)} */}
</Route>
</Routes>
);
Expand Down
49 changes: 23 additions & 26 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { dateFormat, timeFormat } from "@/components/FilterDialogWithBreadcrumbs";
import type { DistributionOfTerminalSalesArray } from "@/pages/SalesVolumeMonitoring/DistributionOfTerminalSales";
import type { SalesSituationOfTerminalSubChannels_labelType } from "@/pages/SalesVolumeMonitoring/SalesSituationOfTerminalSubChannels";
import { priceNameArr } from "@/pages/SalesVolumeMonitoring/SalesStructureOfTerminalPriceRanges";
import type { TOP10ModelInformation_labelType } from "@/pages/SalesVolumeMonitoring/TOP10ModelInformation";
import { enumActionName, enumSeverity, enumSnackbarAlert, type snackbarAlertAction } from "@/store/SnackBarRuducer";
Expand All @@ -11,6 +13,17 @@ interface commonResponse<T = null> {
readonly data: T;
readonly info: string;
}
interface getInitParams {
readonly [level]: number;
readonly orgId: string;
readonly date?: string;
}
export const getInitParams = (): getInitParams => ({ [level]: Number(getLevel()) || 0, orgId: getLocalStorageFromJSON(orgId) || 'HB', date: timeFormat(dateFormat()) });
type timeType = 'year' | 'month' | 'day';
export interface requestType extends getInitParams {
readonly type?: timeType;
};
export const getInitParamsIncludeType = (): requestType => ({ ...getInitParams(), type: 'day' });
// type commonActionType<T = {}, D = void> = (props: T) => (dispatch: Dispatch<snackbarAlertAction>) => Promise<D | void>;
const uuidString = 'uuid';
const setItemAndHeaders = (k: string, v: string) => {
Expand Down Expand Up @@ -43,35 +56,24 @@ export const getScode = () => axios.get<commonResponse<string>>('/api/scode/', {
})()
}
}).then(e => e?.data?.data).catch(console.error);
export const getInitParams = () => ({ [level]: Number(getLevel()) || 0, orgId: getLocalStorageFromJSON(orgId) || 'HB' });
export const getSalesVolumeMonitoring_DistributionOfTerminalSales = (e = getInitParams()) => axios.get<commonResponse<DistributionOfTerminalSalesArray>>('/api/sale/subregion', {
params: e
}).then(e => e.data.data).catch(console.error);
export const getSalesVolumeMonitoring_SalesStructureOfTerminalPriceRanges = (e = {}) => axios.get<commonResponse<{
const addInitParams = (e: object) => ({ params: { ...getInitParams(), ...e } });
export const getSalesVolumeMonitoring_DistributionOfTerminalSales = (e = getInitParams()) => axios.get<commonResponse<DistributionOfTerminalSalesArray>>('/api/sale/subregion', addInitParams(e)).then(e => e.data.data).catch(console.error);
export const getSalesVolumeMonitoring_SalesStructureOfTerminalPriceRanges = ({ type, ...others }: requestType = getInitParamsIncludeType()) => axios.get<commonResponse<{
readonly salesRecordMap: Record<string, {
readonly salesNum: number;
readonly ratio: number;
}>;
}>>('/api/SalesVolumeMonitoring/SalesStructureOfTerminalPriceRanges', {
params: e
}).then(e => e.data.data.salesRecordMap).then(e => priceNameArr.map(i => ({
}>>('/api/sale/structure', addInitParams({ ...others })).then(e => e.data.data.salesRecordMap).then(e => priceNameArr.map(i => ({
price: i,
salesVolume: e[i]?.salesNum ?? 0,
proportion: e[i]?.ratio ?? 0,
}))).catch(console.error);
export const testLogin = () => axios.get<commonResponse>('/api/sell').then(e => e.data.code === successCode).catch(console.error);
type timeType = 'year' | 'month' | 'day';
export const getTerminalActivitySalesStructure = ({ type, ...others }: {
readonly type?: timeType;
readonly orgId?: string;
readonly level?: number;
} = { ...getInitParams() }) => axios.get<commonResponse<{
export const getTerminalActivitySalesStructure = ({ type, ...others }: requestType = getInitParamsIncludeType()) => axios.get<commonResponse<{
readonly scRatio: number;
readonly feRatio: number;
readonly jbRatio: number;
}>>(`/api/sale/contract/${type}`, {
params: { ...others }
}).then(e => Object.entries(e.data.data).map(i => ({ value: i[1], name: i[0] }))).catch(console.error);
}>>(`/api/sale/contract/${type}`, addInitParams({ ...others })).then(e => Object.entries(e.data.data).map(i => ({ value: i[1], name: i[0] }))).catch(console.error);
// export const getAddressList = ({ id }: {
// // readonly type: string;
// readonly id?: string;
Expand All @@ -80,15 +82,9 @@ export const getTerminalActivitySalesStructure = ({ type, ...others }: {
// id
// }
// }).then(e => e.data.data).catch(console.error);
export const getTOP10ModelInformation = ({ type, ...others }: {
readonly type?: timeType;
readonly orgId?: string;
readonly level?: number;
} = { ...getInitParams() }) => axios.get<commonResponse<{
export const getTOP10ModelInformation = ({ type, ...others }: requestType = getInitParamsIncludeType()) => axios.get<commonResponse<{
readonly phoneInfoRank: Record<string, TOP10ModelInformation_labelType>;
}>>(`/api/sale/topPhone/${type}`, {
params: { ...others }
}).then(e => e.data.data.phoneInfoRank).then(e => Object.keys(e).map((i, ind) => {
}>>(`/api/sale/topPhone/${type}`, addInitParams({ ...others })).then(e => e.data.data.phoneInfoRank).then(e => Object.keys(e).map((i, ind) => {
const item = e[ind + 1];
if (item) {
return { ...item, index: String(i) };
Expand All @@ -102,4 +98,5 @@ export const getTOP10ModelInformation = ({ type, ...others }: {
index: '0'
};
}
})).then(e => e.filter(i => Boolean(i.salesNum))).catch(console.error);
})).then(e => e.filter(i => Boolean(i.salesNum))).catch(console.error);
export const getSalesVolumeMonitoring_SalesSituationOfTerminalSubChannels = (e = getInitParams()) => axios.get<commonResponse<ReadonlyArray<SalesSituationOfTerminalSubChannels_labelType>>>('/api/sale/channel/situation', addInitParams(e)).then(e => e.data.data).catch(console.error);
4 changes: 2 additions & 2 deletions src/components/FilterDialogWithBreadcrumbs/_index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
// background-color: rgba(0, 0, 0, 0);
// border-color: rgba(0, 0, 0, 0);
// clip-path: circle(0);
flex-direction: column;
// flex-direction: column;
align-items: center;
align-self: center;
align-content: center;
Expand All @@ -48,7 +48,7 @@
transition: 1s;
display: flex;

> label > input {
> input {
padding: 9q;
font-size: 120%;
}
Expand Down
153 changes: 81 additions & 72 deletions src/components/FilterDialogWithBreadcrumbs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { StyledButton } from "../AppBar";
import SendIcon from '@mui/icons-material/Send';
import classNames from "classnames";
import { getInitParams, getSalesVolumeMonitoring_DistributionOfTerminalSales } from "@/actions";
import { getInitParams, getSalesVolumeMonitoring_DistributionOfTerminalSales, type requestType } from "@/actions";
import { getLevel, getLocalStorageFromJSON, level as levelString, orgId } from "@/actions/axios_instance";
import ReplyIcon from '@mui/icons-material/Reply';
import { regionName } from "../MyTable";
Expand All @@ -22,25 +22,32 @@ export interface labelType {
readonly yearSalesNum: number;
}
const { fromEntries } = Object;
const custom = 'custom';
const dateFormat = (now = new Date()) => `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
const timeFormat = (...args: ReadonlyArray<string>) => args.map(i => i.replaceAll('-', '/')).join('-');
const dateFromOldToNow = (n: number) => {
const now = new Date();
now.setDate(now.getDate() - n);
return timeFormat(dateFormat(now), dateFormat());
};
const ToggleButtonArr = [{
label: 'threeMonth',
text: '近三个月',
value: dateFromOldToNow(90)
const splitString = '-';
export const dateFormat = (now = new Date()) => now.getFullYear() + splitString + String(now.getMonth() + 1).padStart(2, '0') + splitString + String(now.getDate()).padStart(2, '0');
// const timeFormat = (...args: ReadonlyArray<string>) => args.map(i => i.replaceAll('-', '/')).join('-');
export const timeFormat = (s: string) => s.replaceAll(splitString, '/');
// const dateFromOldToNow = (n: number) => {
// const now = new Date();
// now.setDate(now.getDate() - n);
// return timeFormat(dateFormat(now), dateFormat());
// };
const month = 'month';
const thisYear = new Date().getFullYear();
const thisMonth1 = (time: string) => `${time}-01`.slice(0, 10);
const ToggleButtonArr: ReadonlyArray<{
readonly label: requestType["type"];
readonly text: string;
}> = [{
label: 'year',
text: `${thisYear}年`,
// value: dateFromOldToNow(90)
}, {
label: 'thirtyDay',
text: '近30天',
value: dateFromOldToNow(30)
label: month,
text: '按月筛选',
// value: dateFromOldToNow(30)
}, {
label: custom,
text: '自定义',
label: 'day',
text: '按日筛选',
}];
enum unitNameEnum {
city = 'city_id',
Expand Down Expand Up @@ -71,26 +78,23 @@ export interface noNeedSomething {
readonly noNeedTime?: boolean;
readonly noNeedAddress?: boolean;
}
export interface TT {
readonly orgId?: string;
readonly date?: string;
}
interface CurrentFilterShow extends noNeedSomething {
readonly address: addressUseSetStateType;
readonly hasDataIndex: number;
readonly isCustomTime: boolean;
readonly customTimeFormat: string;
// readonly isCustomTime: boolean;
readonly time: string;
readonly f: {
readonly text: string;
readonly label: string;
readonly text?: string | undefined;
readonly label?: string | undefined;
} | undefined;
readonly unitName: ReadonlyArray<unitNameType>;
readonly setBreadcrumbsAddress: (e: number) => void;
}
const HB = '河北省';
const CurrentFilterShow = (props: CurrentFilterShow) => {
const { address, hasDataIndex, isCustomTime, customTimeFormat, f = undefined, noNeedTime = false, noNeedAddress = false, unitName = [], setBreadcrumbsAddress } = props;
const { address, hasDataIndex, time, f = undefined, noNeedTime = false, noNeedAddress = false, unitName = [], setBreadcrumbsAddress } = props;
const allNeed = !noNeedTime && !noNeedAddress;
const timeSplit = time.split(splitString);
return <Paper className={classes['filterResult'] ?? ''} elevation={24}>
{allNeed && <StrictMode><div>当前<wbr />筛选</div><span>{'{'}</span></StrictMode>}
<div>
Expand All @@ -114,15 +118,24 @@ const CurrentFilterShow = (props: CurrentFilterShow) => {
</div>
{allNeed && <Divider />}
{!noNeedTime && <p>时间范围:{(() => {
if (isCustomTime)
return customTimeFormat;
else
return f?.text;
// if (isCustomTime)
// return customTimeFormat;
// else
// return f?.text;
const yearAndMonth = `${timeSplit[0]}${timeSplit[1]}月`;
switch (f?.label) {
case ToggleButtonArr[0]?.label:
return f.text;
case ToggleButtonArr[1]?.label:
return yearAndMonth;
default:
return `${yearAndMonth}${timeSplit[2] ?? '01'}日`;
}
})()}</p>}
</div>
</Paper>;
};
type FilterDialogIncludeButtonProps<T extends TT = TT> = {
type FilterDialogIncludeButtonProps<T extends requestType = requestType> = {
readonly run: (e?: T) => void;
// readonly addressUseState?: [addressUseSetStateType, SetState<addressUseSetStateType>];
} & noNeedSomething;
Expand All @@ -131,11 +144,8 @@ export const FilterDialogWithBreadcrumbs = forwardRef<FilterDialogIncludeButtonI
const level = Number(localStorage.getItem(levelString) ?? getLevel());
const unitName: ReadonlyArray<unitNameType> = level ? unitNameAll.slice(level) : unitNameAll;
const { run, noNeedTime = false, noNeedAddress = false } = props;
const [alignment, setAlignment] = useState(ToggleButtonArr[0]?.label);
const [time, setTime] = useSetState({
start: dateFormat(),
end: dateFormat(),
});
const [alignment, setAlignment] = useState<requestType["type"]>(ToggleButtonArr[0]?.label);
const [time, setTime] = useState(dateFormat());
const [address, setAddress] = useSetState<
addressUseSetStateType
// { [P in unitNameEnum]: addressType }
Expand All @@ -159,23 +169,21 @@ export const FilterDialogWithBreadcrumbs = forwardRef<FilterDialogIncludeButtonI
}));
const hasDataIndex = unitName.findIndex(i => !address[i.label]);
const f = ToggleButtonArr.find(i => i.label === alignment);
const isCustomTime = f?.label === custom;
const customTimeFormat = timeFormat(time.start, time.end);
// const isCustomTime = f?.label === custom;
const [click, setClick] = useState(false);
const setBreadcrumbsAddress: CurrentFilterShow["setBreadcrumbsAddress"] = useCallback((index) => unstable_batchedUpdates(() => {
setAddress(fromEntries(unitName.filter((_i, ind) => ind > index).map(i => [i.label, null])));
setClick(true);
}), []);
const filterResultShow: CurrentFilterShow = {
address, hasDataIndex, isCustomTime, customTimeFormat, f, noNeedAddress, noNeedTime, unitName, setBreadcrumbsAddress
address, hasDataIndex, time, f, noNeedAddress, noNeedTime, unitName, setBreadcrumbsAddress
};
const [filterOpen, setFilterOpen] = useState(false);
const [requestFilterResultShow, setRequestFilterResultShow] = useState<CurrentFilterShow>(filterResultShow);
useEffect(() => unstable_batchedUpdates(() => {
if (click) {
//@ts-expect-error
run({
...(!noNeedTime && { date: isCustomTime ? customTimeFormat : f?.value }),
...(!noNeedTime && { date: alignment === ToggleButtonArr[0]?.label ? timeFormat(`${thisYear + splitString}01${splitString}01`) : timeFormat(thisMonth1(time)), ...(alignment && { type: alignment }) }),
orgId:
[getInitParams().orgId, ...unitName.filter(i => address[i.label]).map(i => address[i.label]?.regionId)].join('.')
, level: hasDataIndex < 0 ? unitNameAll.length - 1 : hasDataIndex
Expand Down Expand Up @@ -386,43 +394,44 @@ export const FilterDialogWithBreadcrumbs = forwardRef<FilterDialogIncludeButtonI
className={classes['ToggleButtonGroup'] ?? ''}
>{
ToggleButtonArr.map((item, index) => <ToggleButton
value={item.label}
value={item.label ?? ''}
key={index}
>{item.text}</ToggleButton>)
}
</ToggleButtonGroup>
<Collapse
in={alignment === ToggleButtonArr[2]?.label}
>
<div
className={classNames(classes["date"]
, {
// [classes['show'] ?? '']: alignment === ToggleButtonArr[2]?.label
})}>
<label>开始日期:<input
type='date'
value={time.start}
<Collapse in={alignment !== ToggleButtonArr[0]?.label}>
<label
className={classNames(classes["date"])} >请选择周期:<input
type={(() => {
switch (alignment) {
case ToggleButtonArr[2]?.label:
return 'date';
case ToggleButtonArr[1]?.label:
return month;
default:
return 'hidden';
}
})()}
value={(() => {
switch (alignment) {
case ToggleButtonArr[1]?.label:
return time.slice(0, 7);
default:
return thisMonth1(time);
}
})()}
onChange={e => {
const { value } = e.target;
setTime({
start: value
});
}}
max={time.end}
/></label>
<label>结束日期:<input
type='date'
value={time.end}
onChange={e => {
const { value } = e.target;
setTime({
start: new Date(value).getTime() < new Date(time.start).getTime() ? value : time.start,
end: value
});
setTime(e.target.value);
}}
max={dateFormat()}
max={(() => {
switch (alignment) {
case ToggleButtonArr[1]?.label:
return dateFormat().slice(0, 7);
default:
return dateFormat();
}
})()}
/></label>
</div>
</Collapse>
</AccordionDetails>
</Accordion>}
Expand Down
Loading

0 comments on commit 92e9487

Please sign in to comment.