feat/sancongtou-v4 (#984)
Reviewed-on: daoyoucloud/tachybase#984 Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
parent
d7b2695612
commit
b46c9ee827
@ -1,7 +1,7 @@
|
|||||||
import { createForm } from '@tachybase/schema';
|
import { createForm } from '@tachybase/schema';
|
||||||
import { Schema } from '@tachybase/schema';
|
import { Schema } from '@tachybase/schema';
|
||||||
import { Spin } from 'antd';
|
// import { Spin } from 'antd';
|
||||||
import React, { useMemo } from 'react';
|
import React, { PropsWithChildren, useMemo } from 'react';
|
||||||
import { useRequest } from '../../api-client';
|
import { useRequest } from '../../api-client';
|
||||||
import { useSchemaComponentContext } from '../hooks';
|
import { useSchemaComponentContext } from '../hooks';
|
||||||
import { FormProvider } from './FormProvider';
|
import { FormProvider } from './FormProvider';
|
||||||
@ -58,6 +58,6 @@ const RequestSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) =>
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RemoteSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) => {
|
export const RemoteSchemaComponent: React.FC<PropsWithChildren<RemoteSchemaComponentProps>> = (props) => {
|
||||||
return props.uid ? <RequestSchemaComponent {...props} /> : null;
|
return props.uid ? <RequestSchemaComponent {...props} /> : null;
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@ import { css } from '@emotion/css';
|
|||||||
import { useField, useFieldSchema } from '@tachybase/schema';
|
import { useField, useFieldSchema } from '@tachybase/schema';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { FC, useEffect, useMemo, useRef } from 'react';
|
import React, { FC, PropsWithChildren, useEffect, useMemo, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { SchemaToolbarProvider, useSchemaInitializerRender, useSchemaSettingsRender } from '../application';
|
import { SchemaToolbarProvider, useSchemaInitializerRender, useSchemaSettingsRender } from '../application';
|
||||||
import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider';
|
import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider';
|
||||||
@ -62,7 +62,7 @@ export interface GeneralSchemaDesignerProps {
|
|||||||
/**
|
/**
|
||||||
* @deprecated use `SchemaToolbar` instead
|
* @deprecated use `SchemaToolbar` instead
|
||||||
*/
|
*/
|
||||||
export const GeneralSchemaDesigner: FC<GeneralSchemaDesignerProps> = (props: any) => {
|
export const GeneralSchemaDesigner: FC<PropsWithChildren<GeneralSchemaDesignerProps>> = (props: any) => {
|
||||||
const {
|
const {
|
||||||
disableInitializer,
|
disableInitializer,
|
||||||
title,
|
title,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hera/plugin-sancongtou",
|
"name": "@hera/plugin-sancongtou",
|
||||||
"displayName": "Mobile client: Sancongtou Customization",
|
"displayName": "Mobile client: Sancongtou Customization",
|
||||||
"version": "0.21.26",
|
"version": "0.0.4",
|
||||||
"description": "Provide mobile client customization for the sancongtou project.",
|
"description": "Provide mobile client customization for the sancongtou project.",
|
||||||
"main": "dist/server/index.js",
|
"main": "dist/server/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
|
import { SqlLoader } from '@hera/plugin-core';
|
||||||
import { Plugin } from '@tachybase/server';
|
import { Plugin } from '@tachybase/server';
|
||||||
|
import { Container } from '@tachybase/utils';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
export class PluginSancongtouServer extends Plugin {
|
export class PluginSancongtouServer extends Plugin {
|
||||||
async afterAdd() {}
|
async afterAdd() {}
|
||||||
|
|
||||||
async beforeLoad() {}
|
async beforeLoad() {}
|
||||||
|
|
||||||
async load() {}
|
async load() {
|
||||||
|
const sqlLoader = Container.get(SqlLoader);
|
||||||
|
await sqlLoader.loadSqlFiles(path.join(__dirname, './sqls'));
|
||||||
|
}
|
||||||
|
|
||||||
async install() {}
|
async install() {}
|
||||||
|
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
CREATE OR REPLACE VIEW
|
||||||
|
public.view_order_demi AS
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
'推广总数' AS "label",
|
||||||
|
"orderTotalCount" AS "value"
|
||||||
|
FROM
|
||||||
|
public.view_order_stat
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
'有效总数' AS "label",
|
||||||
|
"orderYouXiaoCount" AS "value"
|
||||||
|
FROM
|
||||||
|
public.view_order_stat
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
'跟进总数' AS "label",
|
||||||
|
"orderGenJinCount" AS "value"
|
||||||
|
FROM
|
||||||
|
public.view_order_stat
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
'异常总数' AS "label",
|
||||||
|
"orderYiChangCount" AS "value"
|
||||||
|
FROM
|
||||||
|
public.view_order_stat
|
@ -0,0 +1,91 @@
|
|||||||
|
--- 三聪头, 转化订单数据, 用于统计分析
|
||||||
|
--- 原始数据, 是订单数据, 包含订单号, 订单创建时间, 关联的代理商,
|
||||||
|
--- 订单的金额, 订单的佣金, 订单的状态,
|
||||||
|
--- 新的数据表: 订单编号, 代理商, 订单金额, 订单佣金, 订单的创建时间, 订单的展平状态,
|
||||||
|
--- 推广总数(每个代理商关联的订单总数);
|
||||||
|
--- 有效总数(订单达到首充状态的订单数);
|
||||||
|
--- 跟进总数(下单成功, 但是物流异常, 或者物流正常但是没有首充的订单数)
|
||||||
|
--- 异常总数(下单没有成功的数量)
|
||||||
|
CREATE OR REPLACE VIEW
|
||||||
|
public.view_order_stat AS
|
||||||
|
WITH
|
||||||
|
orders_need_fields_all AS (
|
||||||
|
SELECT
|
||||||
|
"createdAt" AT TIME ZONE 'Asia/Shanghai' AS "createDate",
|
||||||
|
"updatedAt" AT TIME ZONE 'Asia/Shanghai' AS "updateDate",
|
||||||
|
"createdById",
|
||||||
|
"updatedById",
|
||||||
|
business_id,
|
||||||
|
order_id,
|
||||||
|
amount,
|
||||||
|
--- 订单状态
|
||||||
|
status_order,
|
||||||
|
--- 物流状态
|
||||||
|
status_logistics,
|
||||||
|
--- 激活状态
|
||||||
|
activation_status,
|
||||||
|
--- 充值状态
|
||||||
|
status_recharge,
|
||||||
|
--- 结算状态
|
||||||
|
status_settlement
|
||||||
|
FROM
|
||||||
|
orders
|
||||||
|
),
|
||||||
|
--- 推广总数
|
||||||
|
orders_tuiguang AS (
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
COALESCE(COUNT(*), 0) AS "orderTotalCount"
|
||||||
|
FROM
|
||||||
|
orders_need_fields_all
|
||||||
|
GROUP BY
|
||||||
|
business_id
|
||||||
|
),
|
||||||
|
--- 有效总数
|
||||||
|
order_youxiao AS (
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
COALESCE(COUNT(*), 0) AS "orderYouXiaoCount"
|
||||||
|
FROM
|
||||||
|
orders_need_fields_all
|
||||||
|
WHERE
|
||||||
|
status_recharge = '1' --- 0/未充值, 1/已充值
|
||||||
|
GROUP BY
|
||||||
|
business_id
|
||||||
|
),
|
||||||
|
--- 跟进总数
|
||||||
|
order_genjin AS (
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
COALESCE(COUNT(*), 0) AS "orderGenJinCount"
|
||||||
|
FROM
|
||||||
|
orders_need_fields_all
|
||||||
|
WHERE
|
||||||
|
status_order = '3' --- 1/审核中, 2/审核失败, 3/审核成功
|
||||||
|
AND status_recharge = '0' --- 0/未充值, 1/已充值
|
||||||
|
GROUP BY
|
||||||
|
business_id
|
||||||
|
),
|
||||||
|
--- 异常总数
|
||||||
|
order_yichang AS (
|
||||||
|
SELECT
|
||||||
|
business_id,
|
||||||
|
COALESCE(COUNT(*), 0) AS "orderYiChangCount"
|
||||||
|
FROM
|
||||||
|
orders_need_fields_all
|
||||||
|
WHERE
|
||||||
|
status_order = '2' --- 1/审核中, 2/审核失败, 3/审核成功
|
||||||
|
GROUP BY
|
||||||
|
business_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
orders_tuiguang.business_id,
|
||||||
|
orders_tuiguang."orderTotalCount",
|
||||||
|
order_youxiao."orderYouXiaoCount",
|
||||||
|
order_genjin."orderGenJinCount",
|
||||||
|
order_yichang."orderYiChangCount"
|
||||||
|
FROM
|
||||||
|
orders_tuiguang
|
||||||
|
LEFT JOIN order_youxiao ON orders_tuiguang.business_id = order_youxiao.business_id
|
||||||
|
LEFT JOIN order_genjin ON orders_tuiguang.business_id = order_genjin.business_id
|
||||||
|
LEFT JOIN order_yichang ON orders_tuiguang.business_id = order_yichang.business_id
|
@ -1,12 +1,12 @@
|
|||||||
import { SchemaComponentOptions, SchemaInitializerContext, useSchemaInitializer } from '@tachybase/client';
|
import { SchemaComponentOptions, SchemaInitializerContext, useSchemaInitializer } from '@tachybase/client';
|
||||||
import React, { useState } from 'react';
|
import React, { PropsWithChildren, useState } from 'react';
|
||||||
import { ChartConfigProvider } from '../configure';
|
import { ChartConfigProvider } from '../configure';
|
||||||
import { ChartDataProvider } from './ChartDataProvider';
|
import { ChartDataProvider } from './ChartDataProvider';
|
||||||
import { ChartRenderer, ChartRendererProvider } from '../renderer';
|
import { ChartRenderer, ChartRendererProvider } from '../renderer';
|
||||||
import { ChartFilterBlockProvider, ChartFilterBlockDesigner } from '../filter';
|
import { ChartFilterBlockProvider, ChartFilterBlockDesigner } from '../filter';
|
||||||
import { ChartFilterProvider } from '../filter/FilterProvider';
|
import { ChartFilterProvider } from '../filter/FilterProvider';
|
||||||
|
|
||||||
export const ChartV2Block: React.FC = (props) => {
|
export const ChartV2Block: React.FC<PropsWithChildren> = (props) => {
|
||||||
const [initialVisible, setInitialVisible] = useState(false);
|
const [initialVisible, setInitialVisible] = useState(false);
|
||||||
const schemaInitializerContextData = useSchemaInitializer();
|
const schemaInitializerContextData = useSchemaInitializer();
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, useState } from 'react';
|
import React, { createContext, useState, PropsWithChildren } from 'react';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
|
||||||
type ChartData = {
|
type ChartData = {
|
||||||
@ -15,7 +15,7 @@ export const ChartDataContext = createContext<{
|
|||||||
}>({} as any);
|
}>({} as any);
|
||||||
ChartDataContext.displayName = 'ChartDataContext';
|
ChartDataContext.displayName = 'ChartDataContext';
|
||||||
|
|
||||||
export const ChartDataProvider: React.FC = (props) => {
|
export const ChartDataProvider: React.FC<PropsWithChildren> = (props) => {
|
||||||
const [charts, setCharts] = useState<{
|
const [charts, setCharts] = useState<{
|
||||||
[uid: string]: ChartData;
|
[uid: string]: ChartData;
|
||||||
}>({});
|
}>({});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ISchema } from '@tachybase/schema';
|
import { ISchema } from '@tachybase/schema';
|
||||||
import React, { createContext, useState } from 'react';
|
import React, { PropsWithChildren, createContext, useState } from 'react';
|
||||||
import { ChartRendererProvider } from '../renderer';
|
import { ChartRendererProvider } from '../renderer';
|
||||||
import { ChartConfigure } from './ChartConfigure';
|
import { ChartConfigure } from './ChartConfigure';
|
||||||
import { useDesignable } from '@tachybase/client';
|
import { useDesignable } from '@tachybase/client';
|
||||||
@ -26,7 +26,7 @@ export const ChartConfigContext = createContext<{
|
|||||||
});
|
});
|
||||||
ChartConfigContext.displayName = 'ChartConfigContext';
|
ChartConfigContext.displayName = 'ChartConfigContext';
|
||||||
|
|
||||||
export const ChartConfigProvider: React.FC = (props) => {
|
export const ChartConfigProvider: React.FC<PropsWithChildren> = (props) => {
|
||||||
const { insertAdjacent } = useDesignable();
|
const { insertAdjacent } = useDesignable();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [current, setCurrent] = useState<ChartConfigCurrent>({} as any);
|
const [current, setCurrent] = useState<ChartConfigCurrent>({} as any);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { createContext, useEffect, useState } from 'react';
|
import React, { PropsWithChildren, createContext, useEffect, useState } from 'react';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
|
||||||
type FilterField = {
|
type FilterField = {
|
||||||
@ -28,7 +28,7 @@ export const ChartFilterContext = createContext<{
|
|||||||
}>({} as any);
|
}>({} as any);
|
||||||
ChartFilterContext.displayName = 'ChartFilterContext';
|
ChartFilterContext.displayName = 'ChartFilterContext';
|
||||||
|
|
||||||
export const ChartFilterProvider: React.FC = (props) => {
|
export const ChartFilterProvider: React.FC<PropsWithChildren> = (props) => {
|
||||||
const [ready, setReady] = useState(false);
|
const [ready, setReady] = useState(false);
|
||||||
const [enabled, _setEnabled] = useState(false);
|
const [enabled, _setEnabled] = useState(false);
|
||||||
const [fields, setFields] = useState({});
|
const [fields, setFields] = useState({});
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { PropsWithChildren, useEffect } from 'react';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { isJSBridge } from './core/bridge';
|
import { isJSBridge } from './core/bridge';
|
||||||
|
|
||||||
export const MobileClientProvider = React.memo((props) => {
|
export const MobileClientProvider = React.memo((props: PropsWithChildren) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const navigation = useNavigate();
|
const navigation = useNavigate();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SchemaComponentOptions } from '@tachybase/client';
|
import { SchemaComponentOptions } from '@tachybase/client';
|
||||||
import React from 'react';
|
import React, { PropsWithChildren } from 'react';
|
||||||
import {
|
import {
|
||||||
MMenuBlockInitializer,
|
MMenuBlockInitializer,
|
||||||
MMenu,
|
MMenu,
|
||||||
@ -44,7 +44,7 @@ import {
|
|||||||
import './bridge';
|
import './bridge';
|
||||||
import './assets/svg';
|
import './assets/svg';
|
||||||
|
|
||||||
export const MobileCore: React.FC = (props) => {
|
export const MobileCore: React.FC<PropsWithChildren> = (props) => {
|
||||||
return (
|
return (
|
||||||
<SchemaComponentOptions
|
<SchemaComponentOptions
|
||||||
components={{
|
components={{
|
||||||
@ -56,6 +56,11 @@ export const MobileCore: React.FC = (props) => {
|
|||||||
MPage,
|
MPage,
|
||||||
MHeader,
|
MHeader,
|
||||||
MSettings,
|
MSettings,
|
||||||
|
|
||||||
|
SwiperBlockInitializer,
|
||||||
|
SwiperBlock,
|
||||||
|
SwiperPage,
|
||||||
|
|
||||||
TabSearch,
|
TabSearch,
|
||||||
TabSearchProvider,
|
TabSearchProvider,
|
||||||
TabSearchBlockInitializer,
|
TabSearchBlockInitializer,
|
||||||
@ -64,9 +69,7 @@ export const MobileCore: React.FC = (props) => {
|
|||||||
TabSearchCollapsibleInputItem,
|
TabSearchCollapsibleInputItem,
|
||||||
TabSearchCollapsibleInputMItem,
|
TabSearchCollapsibleInputMItem,
|
||||||
TabSearchFieldSchemaInitializerGadget,
|
TabSearchFieldSchemaInitializerGadget,
|
||||||
SwiperBlockInitializer,
|
|
||||||
SwiperBlock,
|
|
||||||
SwiperPage,
|
|
||||||
ImageSearchView: ImageSearchView,
|
ImageSearchView: ImageSearchView,
|
||||||
ImageSearchInitializer: ImageSearchInitializer,
|
ImageSearchInitializer: ImageSearchInitializer,
|
||||||
ImageSearchProvider: ImageSearchProvider,
|
ImageSearchProvider: ImageSearchProvider,
|
||||||
|
@ -128,6 +128,11 @@ export const mBlockInitializers = new CompatibleSchemaInitializer(
|
|||||||
type: 'item',
|
type: 'item',
|
||||||
Component: 'NoticeBlockInitializer',
|
Component: 'NoticeBlockInitializer',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'chartV2',
|
||||||
|
title: '{{t("Charts")}}',
|
||||||
|
Component: 'ChartV2BlockInitializer',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { css, cx } from '@tachybase/client';
|
import { css, cx } from '@tachybase/client';
|
||||||
import React from 'react';
|
import React, { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
const iOS6: React.FC<{
|
type IProps = PropsWithChildren<{
|
||||||
className: string;
|
className: string;
|
||||||
}> = (props) => {
|
}>;
|
||||||
|
|
||||||
|
const iOS6: React.FC<IProps> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { css, cx } from '@tachybase/client';
|
import { css, cx } from '@tachybase/client';
|
||||||
import React from 'react';
|
import React, { PropsWithChildren } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
// import { useLocation } from 'react-router-dom';
|
||||||
import Device from './iOS6';
|
import Device from './iOS6';
|
||||||
|
|
||||||
export const MobileDevice: React.FC = (props) => {
|
export const MobileDevice: React.FC<PropsWithChildren> = (props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
@ -23,7 +23,7 @@ export const MobileDevice: React.FC = (props) => {
|
|||||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
|
||||||
`}
|
`}
|
||||||
{...props}
|
{...props}
|
||||||
></Device>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ActionContextProvider, AdminProvider, css, cx, RemoteSchemaComponent, useViewport } from '@tachybase/client';
|
import { ActionContextProvider, AdminProvider, css, cx, RemoteSchemaComponent, useViewport } from '@tachybase/client';
|
||||||
import { DrawerProps, ModalProps } from 'antd';
|
import { DrawerProps, ModalProps } from 'antd';
|
||||||
import React, { useMemo } from 'react';
|
import React, { PropsWithChildren, useMemo } from 'react';
|
||||||
import { Outlet, useParams } from 'react-router-dom';
|
import { Outlet, useParams } from 'react-router-dom';
|
||||||
import { MobileCore } from '../core';
|
import { MobileCore } from '../core';
|
||||||
import { useInterfaceContext } from './InterfaceProvider';
|
import { useInterfaceContext } from './InterfaceProvider';
|
||||||
@ -71,7 +71,7 @@ const useMobileSchemaUid = () => {
|
|||||||
return 'nocobase-mobile-container';
|
return 'nocobase-mobile-container';
|
||||||
};
|
};
|
||||||
|
|
||||||
const MApplication: React.FC = (props) => {
|
const MApplication: React.FC<PropsWithChildren> = (props) => {
|
||||||
const mobileSchemaUid = useMobileSchemaUid();
|
const mobileSchemaUid = useMobileSchemaUid();
|
||||||
const params = useParams<{ name: string }>();
|
const params = useParams<{ name: string }>();
|
||||||
const interfaceContext = useInterfaceContext();
|
const interfaceContext = useInterfaceContext();
|
||||||
|
Loading…
Reference in New Issue
Block a user