diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml new file mode 100644 index 0000000..a970c57 --- /dev/null +++ b/.github/workflows/develop.yml @@ -0,0 +1,75 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - develop + +env: + IMAGE_NAME: '' + REPO_NAME: '' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Setup Environments + shell: bash + run: | + IFS="/" read -r OWNER REPO <<< "$GITHUB_REPOSITORY" + echo "REPO_NAME=$REPO" >> $GITHUB_ENV + echo "IMAGE_NAME=${{ vars.REGISTRY_URL }}/${{ vars.REGISTRY_NAMESPACE }}/$REPO:$GITHUB_REF_NAME" >> $GITHUB_ENV + + - name: Checkout + uses: https://gitee.com/zuowenbo/checkout@v4.2.2 + + - name: Cache Docker layers + uses: https://gitee.com/zuowenbo/cache@v4.2.1 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ env.REPO_NAME }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-${{ env.REPO_NAME }}- + + - name: Set up Docker Buildx + uses: https://gitee.com/zuowenbo/setup-buildx-action@v3.9.0 + with: + driver-opts: image=registry.cn-shenzhen.aliyuncs.com/zuoge-proxy/buildkit:buildx-stable-1 + + - name: Login to Docker Hub + uses: https://gitee.com/zuowenbo/login-action@v3.3.0 + with: + registry: ${{ vars.REGISTRY_URL }} + username: ${{ vars.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build and push final image + uses: https://gitee.com/zuowenbo/build-push-action@v6.14.0 + with: + context: . + tags: ${{ env.IMAGE_NAME }} + push: true + platforms: linux/amd64 + build-args: BRANCH=${{ env.GITHUB_REF_NAME }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max + + - name: Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache + + - name: Deploy to remote + uses: https://gitee.com/zuowenbo/ssh-action@v1.0.3 + with: + host: ${{ vars.DEV_HOST_IP }} + port: 22 + username: 'root' + password: ${{ secrets.DEV_HOST_PASSWORD }} + script: | + docker login -u ${{ vars.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ vars.REGISTRY_URL}} + docker volume create ${{ env.REPO_NAME }} || true + docker pull ${{ env.IMAGE_NAME }} + docker stop ${{ env.REPO_NAME }} || true + docker rm ${{ env.REPO_NAME }} || true + docker run -d --restart always --network my_network --name ${{ env.REPO_NAME }} ${{ env.IMAGE_NAME }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..e25ea88 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,79 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + +env: + IMAGE_NAME: '' + REPO_NAME: '' + +jobs: + build: + runs-on: ubuntu-latest + container: + image: zuogeus/act-ubuntu:node18 + options: --add-host nexus.zzwb.cc:192.168.2.7 + + steps: + - name: Setup Environments + shell: bash + run: | + IFS="/" read -r OWNER REPO <<< "$GITHUB_REPOSITORY" + echo "REPO_NAME=$REPO" >> $GITHUB_ENV + echo "IMAGE_NAME=${{ vars.REGISTRY_URL }}/${{ vars.REGISTRY_NAMESPACE }}/$REPO:$GITHUB_REF_NAME" >> $GITHUB_ENV + + - name: Checkout + uses: https://gitee.com/zuowenbo/checkout@v4.1.1 + + - name: Get npm cache directory + id: npm-cache-dir + shell: bash + run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT} + + - name: Set node_modules cache + uses: https://gitee.com/zuowenbo/cache@v4.0.0 + id: npm-cache + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-node-umi4-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-umi4- + + - run: npm install --registry=https://registry.npmmirror.com + - run: npm run build + + - name: Set up Docker Buildx + uses: https://gitee.com/zuowenbo/setup-buildx-action@v3.0.0 + with: + driver-opts: network=host + + - name: Login to Docker Hub + uses: https://gitee.com/zuowenbo/login-action@v3.0.0 + with: + registry: ${{ vars.REGISTRY_URL }} + username: ${{ vars.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build and push final image + uses: https://gitee.com/zuowenbo/build-push-action@v5.1.0 + with: + context: . + tags: ${{ env.IMAGE_NAME }} + push: true + build-args: BRANCH=${{ env.GITHUB_REF_NAME }} + + - name: Deploy to remote + uses: https://gitee.com/zuowenbo/ssh-action@v1.0.3 + with: + host: ${{ vars.LOAN_MAIN_HOST_IP_PHP }} + port: 22 + username: 'root' + password: ${{ secrets.LOAN_MAIN_HOST_PASSWORD }} + script: | + docker login -u ${{ vars.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} ${{ vars.REGISTRY_URL}} + docker pull ${{ env.IMAGE_NAME }} + docker stop ${{ env.REPO_NAME }} || true + docker rm ${{ env.REPO_NAME }} || true + docker run -d --restart always --network my_network --name ${{ env.REPO_NAME }} ${{ env.IMAGE_NAME }} diff --git a/.gitignore b/.gitignore index ec0cabb..27a5b75 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ /dist /.mfsu .swc +/.idea \ No newline at end of file diff --git a/.umirc.ts b/.umirc.ts index 9539141..52c94ec 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -14,9 +14,14 @@ export default defineConfig({ }, proxy: { '/api/': { +<<<<<<< HEAD // target: 'http://yt:8003', target: 'http://10.39.13.80:8001', // target: 'https://weapp-api.linyikj.com.cn/', +======= + target: 'http://yt:8001', + // target: 'http://10.39.13.80:8001', +>>>>>>> 1275c157f58b27d4d2b966e91a73bab4f3360be2 // target: 'http://we6f9c65.natappfree.cc', // target: 'https://loanos-test.nchl.net/', changeOrigin: true, diff --git a/Dockerfile b/Dockerfile index c7e4c14..f535562 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,15 @@ -FROM nexus.zzwb.cc:18444/nginx:1.21-alpine -COPY dist /usr/share/nginx/html +# 构建阶段 +FROM registry.cn-shenzhen.aliyuncs.com/zuoge-proxy/node:20-alpine AS build +RUN npm install -g pnpm --registry=https://registry.npmmirror.com + +WORKDIR /app +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install --registry=https://registry.npmmirror.com + +COPY . . +RUN pnpm build + +# 部署阶段 +FROM registry.cn-shenzhen.aliyuncs.com/zuoge-proxy/nginx:1.27.3-alpine AS app +COPY --from=build /app/dist /usr/share/nginx/html COPY docker/nginx.conf /etc/nginx/nginx.conf diff --git a/package.json b/package.json index 4758e7f..8bccefa 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,6 @@ "dependencies": { "@ant-design/icons": "^5.0.1", "@ant-design/pro-components": "^2.8.10", - "@antv/g2": "^5.3.5", - "@antv/s2": "^2.0.0-next.25", - "@antv/s2-react": "^2.0.0-next.24", "@umijs/max": "^4.3.10", "antd": "^5.4.0", "axios": "^1.7.2", diff --git a/src/common/index.tsx b/src/common/index.tsx index eb28007..6cc2566 100644 --- a/src/common/index.tsx +++ b/src/common/index.tsx @@ -10,8 +10,8 @@ export * from './components/layout/MyCommonModal'; export * from './components/layout/MyImportModal'; export * from './components/layout/MyPageContainer'; export * from './components/layout/MyRootContainer'; -export * from './components/layout/usePageTabs'; export * from './components/layout/TabsExample'; +export * from './components/layout/usePageTabs'; export * from './components/props/MyDrawerProps'; export * from './components/props/MyModalFormProps'; @@ -33,7 +33,6 @@ export * from './libs/valtio/state'; // pages export * from './pages/MyLoginPage1'; -export * from './pages/NewMyS2Table'; // utils export * from './utils/renderTextHelper'; diff --git a/src/common/pages/NewMyS2Table/MyS2TableComponent.tsx b/src/common/pages/NewMyS2Table/MyS2TableComponent.tsx deleted file mode 100644 index 3b873bc..0000000 --- a/src/common/pages/NewMyS2Table/MyS2TableComponent.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { SheetComponent } from '@antv/s2-react'; -import { DataType } from '.'; - -export function MyS2TableComponent(props: DataType) { - return ( - - ); -} diff --git a/src/common/pages/NewMyS2Table/MyS2TableExtra.tsx b/src/common/pages/NewMyS2Table/MyS2TableExtra.tsx deleted file mode 100644 index 5af23f1..0000000 --- a/src/common/pages/NewMyS2Table/MyS2TableExtra.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { Button, Radio, Space, Switch, Typography } from 'antd'; -import { DataType } from '.'; - -function downloadCSV(json: any) { - if (json === undefined) return; - // 提取表头 - const headers = Object.keys(json[0]); - // 提取数据行 - const rows = json.map((item: any) => Object.values(item)); - - // 构建CSV内容 - let csvContent = ''; - // 添加表头 - csvContent += headers.join(',') + '\r\n'; - // 添加数据行 - rows.forEach((row: any) => { - csvContent += row.join(',') + '\r\n'; - }); - - // 创建一个Blob对象,使用CSV内容,并设置类型为text/csv - const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); - - // 创建一个链接元素 - const link = document.createElement('a'); - // 设置下载的文件名,默认为'download.csv' - if (link.download !== undefined) { - const url = URL.createObjectURL(blob); - link.setAttribute('href', url); - link.setAttribute('download', 'download.csv'); - // 触发点击事件以下载文件 - document.body.appendChild(link); - link.click(); - // 清理DOM - document.body.removeChild(link); - } -} - -export function MyS2TableExtra({ - config, - data, - setConfig, -}: { - config: DataType['config']; - data: DataType['data']; - setConfig: (config: DataType['config']) => void; -}) { - return ( - - 行小计: - { - setConfig({ ...config, rowSubTotals: Boolean(e) }); - }} - /> - 行总计: - { - setConfig({ ...config, rowGrandTotals: Boolean(e) }); - }} - /> - 列小计: - { - setConfig({ ...config, colSubTotals: Boolean(e) }); - }} - /> - 列总计: - { - setConfig({ ...config, colGrandTotals: Boolean(e) }); - }} - /> - 类型: - - setConfig({ - ...config, - hierarchyType: e.target.value, - }) - } - optionType="button" - buttonStyle="solid" - style={{ marginRight: 20 }} - /> - - - - ); -} diff --git a/src/common/pages/NewMyS2Table/MySwitcherFields.tsx b/src/common/pages/NewMyS2Table/MySwitcherFields.tsx deleted file mode 100644 index c7f92be..0000000 --- a/src/common/pages/NewMyS2Table/MySwitcherFields.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Switcher } from '@antv/s2-react'; -import { useSetState } from 'react-use'; -import { DataType } from '.'; - -export function MySwitcherFields({ - fields, - setFields, -}: { - fields: DataType['fields']; - setFields: (fields: DataType['fields']) => void; -}) { - const [switcherFields, setSwitcherFields] = useSetState(() => { - return { - rows: { - selectable: true, - allowEmpty: false, - items: fields.rows?.map((item) => { - return { id: item }; - }), - }, - columns: { - selectable: true, - allowEmpty: true, - items: fields.columns?.map((item) => { - return { id: item }; - }), - }, - values: { - selectable: true, - allowEmpty: false, - items: fields.values?.map((item) => { - return { id: item }; - }), - }, - }; - }); - - function onSwitcherChange(result: any): void { - const fields = { - rows: result.rows.items - .filter((item: { checked?: boolean }) => item.checked ?? true) - .map((item: { id: string }) => item.id), - columns: result.columns.items - .filter((item: { checked?: boolean }) => item.checked ?? true) - .map((item: { id: string }) => item.id), - values: result.values.items - .filter((item: { checked?: boolean }) => item.checked ?? true) - .map((item: { id: string }) => item.id), - }; - - setSwitcherFields({ - rows: { - selectable: true, - allowEmpty: false, - items: result.rows.items, - }, - columns: { - selectable: true, - allowEmpty: true, - items: result.columns.items, - }, - values: { - selectable: true, - allowEmpty: false, - items: result.values.items, - }, - }); - - setFields?.(fields); - } - - return ; -} diff --git a/src/common/pages/NewMyS2Table/Query.tsx b/src/common/pages/NewMyS2Table/Query.tsx deleted file mode 100644 index a5b8305..0000000 --- a/src/common/pages/NewMyS2Table/Query.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { BetaSchemaForm, ProCard } from '@ant-design/pro-components'; -import { PropsType } from '.'; - -export default function Query({ - columns, - doRequest, -}: { - columns?: PropsType['columns']; - doRequest: (values: any) => void; -}) { - return ( - - ) => { - doRequest(values); - }} - columns={columns as any} - /> - - ); -} diff --git a/src/common/pages/NewMyS2Table/index.tsx b/src/common/pages/NewMyS2Table/index.tsx deleted file mode 100644 index daf9bdd..0000000 --- a/src/common/pages/NewMyS2Table/index.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import { MyPageContainer } from '@/common'; -import { MyResponseType } from '@/common/typings'; -import { ProCard, ProFormColumnsType } from '@ant-design/pro-components'; -import { Fields, HierarchyType, Meta, RawData } from '@antv/s2'; -import { Flex, Space } from 'antd'; -import { useEffect } from 'react'; -import { useSetState } from 'react-use'; -import { MyS2TableComponent } from './MyS2TableComponent'; -import { MyS2TableExtra } from './MyS2TableExtra'; -import { MySwitcherFields } from './MySwitcherFields'; -import Query from './Query'; - -export type PropsType = { - title: string; - api: (values?: any) => Promise; - defaultParams?: Record; - columns?: ProFormColumnsType, 'text'>[] | undefined; -}; - -export type DataType = { - config: { - hierarchyType: HierarchyType | undefined; - rowGrandTotals: boolean; - rowSubTotals: boolean; - colGrandTotals: boolean; - colSubTotals: boolean; - }; - data: RawData[]; - fields: Fields; - meta?: Meta[]; - query?: Record; -}; - -export function NewMyS2Table(props: PropsType) { - const [data, setData] = useSetState(undefined); - - // 请求数据 - function doRequest() { - props - .api?.({ ...props.defaultParams, ...data.query, fields: data.fields }) - .then((resp) => { - if (!data.config) - setData({ - config: resp.data.config, - data: resp.data.data, - fields: resp.data.fields, - meta: resp.data.meta, - }); - else setData({ data: resp.data.data }); - }); - } - - // // 如果没有columns,直接发起请求 - // useEffect(() => { - // if (props.columns === undefined) doRequest({}); - // }, []); - - useEffect(() => { - console.log('useEffect query', data.query, data.fields); - if (!data.query && !data.fields) { - if (props.columns === undefined) { - doRequest(); - } - } else { - doRequest(); - } - }, [data.query, data.fields]); - - return ( - - {props.columns && ( - { - setData({ query: values }); - }} - /> - )} - - - - {data.fields && ( - { - console.log('fields', fields); - setData({ fields }); - }} - /> - )} - {data.config && ( - { - setData({ config }); - }} - data={data.data} - /> - )} - - {data.config && ( - - )} - - - - ); -}