Compare commits

..

No commits in common. 'main' and 'v2.3.7' have entirely different histories.
main ... v2.3.7

@ -1,57 +0,0 @@
# Build & deploy
name: 🚀 Deploy GHH
on:
push:
tags:
- 'v*'
jobs:
build:
name: 🎉 Deploy
runs-on: ubuntu-latest
steps:
- name: 🚚 Get latest code
uses: actions/checkout@v4
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: "npm"
- name: 🔨 Build Project
run: |
npm install
npm run build --if-present
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: fe-build
path: |
dist
build
out
if-no-files-found: ignore
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: fe-build
path: ./build-output
- name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
server: ${{ secrets.GHH_SERVER }}
username: ${{ secrets.GHH_USER }}
password: ${{ secrets.GHH_PASSWORD }}
port: ${{ secrets.GHH_PORT }}
local-dir: ./build-output
server-dir: ${{ secrets.GHH_PATH }}
# dangerous-clean-slate: true # deletes remote files before upload

@ -1,7 +1,7 @@
{
"name": "global-highlights-hub",
"private": true,
"version": "2.3.10",
"version": "2.3.7",
"type": "module",
"scripts": {
"dev": "vite",

@ -156,7 +156,7 @@ export const useNewProductRecord = () => {
'lastedit_changed': '',
'create_date': '',
'created_by': '',
'edit_status': 2, // 信息的审核状态 1已发布2未发布 ~~已审核~~
'edit_status': 2, // 信息的审核状态 1已发布2已审核
'sort_order': '',
'sub_type_D': '', // 包价类型, 值保存在`item_type`字段中
'item_type': '', // 产品子类型的值
@ -210,13 +210,6 @@ export const PackageTypes = [
];
export const formatGroupSize = (min, max, suffix = false) => {
const minSize = min === 0 ? 1 : min;
// const rangeStr = max === min ? `${minSize}` : `${minSize}-${max}`;
const rangeStr = `${minSize}-${max}`;
return max === 1000 ? minSize <= 1 ? '不分人等' : `${minSize}人以上` : (`${rangeStr}`+(suffix ? '人' : ''));
};
export const formatGroupSizeRender = (min, max, suffix = false) => {
const minSize = min === 0 ? 1 : min;
const rangeStr = max === min ? `${minSize}` : `${minSize}-${max}`;
return max === 1000 ? minSize <= 1 ? '不分人等' : `${minSize}人以上` : (`${rangeStr}`+(suffix ? '人' : ''));

@ -52,7 +52,6 @@ import ProductsDetail from '@/views/products/Detail';
import ProductsAudit from '@/views/products/Audit';
import ImageViewer from '@/views/ImageViewer';
import CustomerImageViewer from '@/views/CustomerImageViewer';
import AkamaiLog from '@/views/AkamaiLog';
import PickYear from './views/products/PickYear'
import { BUILD_VERSION, PERM_ACCOUNT_MANAGEMENT, PERM_ROLE_NEW,
@ -123,7 +122,6 @@ const initRouter = async () => {
{ path: '/logout', element: <Logout /> },
{ path: '/image-viewer/:GRI_SN/:GRI_No', element: <ImageViewer /> },
{ path: '/customer-image/:key', element: <CustomerImageViewer /> },
{ path: '/akamai-log', element: <AkamaiLog /> },
]
}
])

@ -1,141 +0,0 @@
import React, { useState, useEffect } from 'react';
import { Input, Button, Card, Typography, Space, Alert, Spin, Table, Tag } from 'antd';
import { useSearchParams } from 'react-router-dom';
import { postJSON } from "@haina/utils-request";
const { Title, Text } = Typography;
const AkamaiLog = () => {
const [searchParams] = useSearchParams();
const ip = searchParams.get('ip');
const [log, setLog] = useState([]);//
const [loading, setLoading] = useState(false);//
const [error, setError] = useState('');//
//
const STATIC_EXTENSIONS = [
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.ico',
'.css', '.scss', '.less',
'.js', '.jsx', '.ts', '.tsx', '.map',
'.woff', '.woff2', '.ttf', '.eot', '.otf',
'.mp4', '.mp3', '.avi', '.mov', '.flv', '.webm', '.m3u8',
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
'.zip', '.tar', '.gz', '.rar', '.7z', '.xml', '.json', '.txt',
'.php'
];
// URL
const FILTER_URLS = [
'/api/', '/admin/', '/wp-admin/',
'robots.txt', 'sitemap.xml', '/404', '/.well-known/'
];
//
const filterLogData = (data) => {
if (!Array.isArray(data)) return [];
return data.filter(item => {
if (!item.request_path) return true;
const fullUrl = `${item.request_host || ''}${item.request_path}`;
const requestPath = item.request_path.toLowerCase();
const hasStaticExtension = STATIC_EXTENSIONS.some(ext =>
requestPath.endsWith(ext)
);
const hasFilteredUrl = FILTER_URLS.some(url =>
fullUrl.includes(url) || requestPath.includes(url)
);
return !hasStaticExtension && !hasFilteredUrl;
});
};
useEffect(() => {
const fetchLog = async () => {
if (!ip) {
setError('未获取到 IP 地址');
return;
}
setLoading(true);
setError('');
try {
const res = await postJSON(`http://202.103.69.110:8010/webhook/60601af9-dbd7-4b01-8718-a1c05018b4be`,
{ ip: ip }
);
// console.log(':', res);
const filteredData = filterLogData(res);
setLog(filteredData);
} catch (err) {
console.error('请求日志失败:', err);
setError('日志加载失败,请稍后重试');
} finally {
setLoading(false);
}
};
fetchLog();
}, [ip]);
//
const columns = [
{
title: '来源地址',
dataIndex: 'referer',
key: 'referer',
width: 250,
},
// {
// title: '(bytes)',
// dataIndex: 'bytes',
// key: 'bytes',
// width: 100,
// },
{
title: '请求路径',
key: 'request_path',
width: 300,
render: (_, record) => {
return record.request_host + '/' + record.request_path + (record.query_str !== '-' ? '?' + record.query_str : '');
},
},
{
title: '请求方法',
dataIndex: 'request_method',
key: 'request_method',
width: 80,
render: (method) => <Tag color="blue">{method}</Tag>,
},
{
title: '状态码',
dataIndex: 'status_code',
key: 'status_code',
width: 80,
},
{
title: '请求时间',
dataIndex: 'request_time',
key: 'request_time',
width: 180,
},
];
return (
<div style={{ padding: '20px' }}>
<Title level={2}>Akamai 日志查询</Title>
{error && <Alert message={error} type="error" showIcon style={{ marginBottom: 16 }} />}
<Card size="small" style={{ marginBottom: 16 }}>
<Text strong>当前查询 IP</Text>
<Text>{ip || '未获取到ip'}</Text>
</Card>
<Spin spinning={loading}>
<Table
rowKey="id"
columns={columns}
dataSource={log}
bordered
size="middle"
pagination={false}
/>
</Spin>
</div>
);
};
export default AkamaiLog;

@ -95,7 +95,7 @@ function Index() {
</Col>
<Col md={6} sm={6} xs={24} >
<Space>
<Button icon={<AuditOutlined />} onClick={() => navigate(`/invoice/detail/0/438241/0`)}>
<Button icon={<AuditOutlined />} onClick={() => navigate(`/invoice/detail/0/395074/0`)}>
Misc. Invoice
</Button>
<Button icon={<AuditOutlined />} onClick={() => navigate(`/invoice/paid`)}>

@ -73,7 +73,6 @@ const ProductInfo = ({ ...props }) => {
const lgc = Object.keys(changedValues.lgc_details_mapped)[0];
setLgcEdits({...lgcEdits, [lgc]: {'edit_status': '2'}});
setEditLgcKeys([...editLgcKeys, ...Object.keys(changedValues.lgc_details_mapped)])
setInfoEditStatus('2');
} else if ('quotation' in changedValues) {
// edit_status
} else {

@ -30,7 +30,7 @@ import dayjs from "dayjs";
import useProductsStore from "@/stores/Products/Index";
import useAuthStore from '@/stores/Auth'
import PriceCompactInput from "@/views/products/Detail/PriceCompactInput";
import { formatGroupSize, formatGroupSizeRender } from "@/hooks/useProductsSets";
import { formatGroupSize } from "@/hooks/useProductsSets";
const { RangePicker } = DatePicker;
@ -259,7 +259,7 @@ const ProductInfoQuotation = ({ editable, ...props }) => {
dataIndex: "group_size",
width: "6rem",
render: (_, record) =>
formatGroupSizeRender(record.group_size_min, record.group_size_max),
formatGroupSize(record.group_size_min, record.group_size_max),
},
{

@ -3,7 +3,7 @@ import { useParams, Link } from 'react-router-dom';
import { Button, Drawer, Card, Table } from 'antd';
import { useTranslation } from 'react-i18next';
import useProductsStore, { getAgencyAllExtrasAction } from '@/stores/Products/Index';
import { useProductsTypes, formatGroupSize, useProductsTypesMapVal, formatGroupSizeRender } from '@/hooks/useProductsSets';
import { useProductsTypes, formatGroupSize, useProductsTypesMapVal } from '@/hooks/useProductsSets';
import { chunkBy, splitTable_6, splitTable_7, splitTable_8, splitTable_B, splitTable_D, splitTable_J, splitTable_Q, splitTable_R } from '@/hooks/useProductsQuotationFormat';
import { groupBy, isNotEmpty } from '@haina/utils-commons';
import useAuthStore from '@/stores/Auth';
@ -259,7 +259,7 @@ const AgencyPreview = ({ params, ...props }) => {
),
},
...cols.map((col) => ({
title: formatGroupSizeRender(...col),
title: formatGroupSize(...col),
// dataIndex: [formatGroupSize(...col), 'adult_cost'],
key: col[0],
children: [
@ -378,7 +378,7 @@ const AgencyPreview = ({ params, ...props }) => {
),
},
...cols.map((col) => ({
title: formatGroupSizeRender(...col),
title: formatGroupSize(...col),
// dataIndex: [formatGroupSize(...col), 'adult_cost'],
key: col[0],
children: [
@ -502,7 +502,7 @@ const AgencyPreview = ({ params, ...props }) => {
),
},
...cols.map((col) => ({
title: formatGroupSizeRender(...col),
title: formatGroupSize(...col),
// dataIndex: [formatGroupSize(...col), 'adult_cost'],
key: col[0],
// children1: [
@ -965,7 +965,7 @@ const AgencyPreview = ({ params, ...props }) => {
),
},
...cols.map((col) => ({
title: formatGroupSizeRender(...col),
title: formatGroupSize(...col),
// dataIndex: [formatGroupSize(...col), 'adult_cost'],
key: col[0],
children: [
@ -1100,7 +1100,7 @@ const AgencyPreview = ({ params, ...props }) => {
),
},
...cols.map((col) => ({
title: formatGroupSizeRender(...col),
title: formatGroupSize(...col),
// dataIndex: [formatGroupSize(...col), 'adult_cost'],
key: col[0],
children: [

Loading…
Cancel
Save