소스 검색

第一次提交

nahida 1 년 전
커밋
c6628a64e2

+ 2 - 0
.env.development

@@ -0,0 +1,2 @@
+NEXT_PUBLIC_API_URL=http://192.168.110.13:8900/data
+NEXT_PUBLIC_SELF_URL=http://192.168.110.13:3000

+ 2 - 0
.env.production

@@ -0,0 +1,2 @@
+NEXT_PUBLIC_API_URL=http://192.168.110.13:8900/data
+NEXT_PUBLIC_SELF_URL=http://192.168.110.13:3000

+ 46 - 0
.gitignore

@@ -0,0 +1,46 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.local
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+package-lock.json

+ 134 - 0
README.md

@@ -0,0 +1,134 @@
+# Getting Started with UnoCSS and Nextjs
+
+This example is a [Next](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Configuration
+
+#### 1. Installing the dependencies:
+
+```bash
+npm i -D unocss @unocss/postcss
+```
+
+<br>
+
+#### 2. Add these files in the root of your project
+
+```ts
+// @filename uno.config.ts
+import { defineConfig, presetUno } from 'unocss'
+
+export default defineConfig({
+  presets: [
+    presetUno(),
+    // ...
+  ],
+})
+```
+
+<br>
+
+```ts
+// @filename postcss.config.js
+module.exports = {
+  plugins: {
+    '@unocss/postcss': {
+      // Optional
+      content: ['**/*.{html,js,ts,jsx,tsx}'],
+    },
+  },
+}
+```
+
+#### 3. Update your `globals.css` file with UnoCSS
+
+```css
+// @filename src/app/globals.css
+@import '@unocss/reset/tailwind.css';
+@unocss all;
+```
+
+## Usage
+
+Style your components using UnoCSS!
+
+```tsx
+// @filename src/app/page.tsx
+export default function Home() {
+  return (
+    <main className="flex min-h-screen flex-col items-center justify-between p-24">
+      <div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
+        <p className="...">
+          Get started by editing&nbsp;
+          <code className="font-mono font-bold">src/app/page.tsx</code>
+        </p>
+      </div>
+    </main>
+  )
+}
+```
+
+## Bonus
+
+### Attributify preset
+
+You can also import from `unocss` package other presets such as `presetAttributify` to enable [attributify mode](https://unocss.dev/presets/attributify#attributify-preset)
+
+```ts
+// @filename uno.config.ts
+import { presetAttributify } from 'unocss'
+
+export default defineConfig({
+  presets: [
+    presetAttributify(),
+    // ...
+  ],
+})
+ ```
+
+Then you can style your components in attributify mode
+
+```tsx
+// @filename src/components/Resources.tsx
+export const Resources: React.FC<{ resources: Resource[] }> = ({ resources }) => {
+  return (
+    <div
+      m="b-32 lg:b-0"
+      grid="~ lg:cols-4" // ~ is used as a prefix for self-referencing
+      text="center lg:left"
+    />
+  )
+}
+```
+
+For TypeScript support while using `AttributifyAttributes` make sure to read: [Attributify TypeScript Support](https://unocss.dev/presets/attributify#typescript-support-jsx-tsx)
+
+### Icons preset
+
+You can also import from `unocss` package `presetIcons` to enable using the [Icons Preset](https://unocss.dev/presets/icons) for any icon with Pure CSS for UnoCSS.
+
+```ts
+// @filename uno.config.ts
+import { presetIcons } from 'unocss'
+
+export default defineConfig({
+  presets: [
+    presetIcons({
+      // Optional
+      extraProperties: {
+        'display': 'inline-block',
+        'vertical-align': 'middle',
+      },
+    }),
+    // ...
+  ],
+})
+```
+
+Then you can use any of the available icons:
+
+```html
+<span className='i-lucide:arrow-up-right' />
+```
+
+For more information on UnoCSS please visit the Docs [UnoCSS.dev](https://unocss.dev/)

+ 23 - 0
global.d.ts

@@ -0,0 +1,23 @@
+declare interface BaseResponse {
+  code: number;
+  data: any;
+  msg: string;
+}
+
+declare interface ClientResponse{
+  code: number;
+  data: any;
+  message: string;
+}
+
+declare class R {
+  constructor(code:number,data:any,message:string)
+  static success(data:any){}
+  static error(data:any){}
+}
+
+declare interface BasePageRequest {
+  pageNum?: number;
+  pageSize?: number;
+  conditionJson?: string;
+}

+ 19 - 0
next.config.js

@@ -0,0 +1,19 @@
+// next.config.js
+const { createProxyMiddleware } = require('http-proxy-middleware');
+
+module.exports = {
+    devServer: {
+        before(app) {
+            app.use(
+                '/api',
+                createProxyMiddleware({
+                    target: 'http://your-backend-api.com', // 你的后端 API 地址
+                    changeOrigin: true,
+                    pathRewrite: {
+                        '^/api': '', // 重写路径
+                    },
+                })
+            );
+        },
+    },
+};

+ 33 - 0
package.json

@@ -0,0 +1,33 @@
+{
+  "name": "unocss-next",
+  "private": true,
+  "scripts": {
+    "dev": "next dev",
+    "build": "next build",
+    "start": "next start",
+    "lint": "next lint"
+  },
+  "dependencies": {
+    "@ant-design/nextjs-registry": "^1.0.1",
+    "antd": "^5.21.6",
+    "axios": "^1.7.7",
+    "http-proxy-middleware": "^3.0.3",
+    "next": "^14.0.0",
+    "react": "18.2.0",
+    "react-dnd": "^16.0.1",
+    "react-dnd-html5-backend": "^16.0.1",
+    "react-dom": "18.2.0"
+  },
+  "devDependencies": {
+    "@iconify-json/lucide": "^1.2.6",
+    "@types/node": "20.8.3",
+    "@types/react": "18.2.25",
+    "@types/react-dom": "18.2.11",
+    "@unocss/postcss": "latest",
+    "eslint": "8.51.0",
+    "eslint-config-next": "13.5.4",
+    "postcss": "8.4.31",
+    "typescript": "5.2.2",
+    "unocss": "latest"
+  }
+}

+ 0 - 0
pnpm-workspace.yaml


+ 8 - 0
postcss.config.js

@@ -0,0 +1,8 @@
+module.exports = {
+  plugins: {
+    '@unocss/postcss': {
+      // Optional
+      content: ['**/*.{html,js,ts,jsx,tsx}'],
+    },
+  },
+}

+ 7 - 0
shims.d.ts

@@ -0,0 +1,7 @@
+// This File is only needed if you use Attributify
+// Learn more: https://unocss.dev/presets/attributify
+import type { AttributifyAttributes } from 'unocss/preset-attributify'
+
+declare module 'react' {
+  interface HTMLAttributes<T> extends AttributifyAttributes {}
+}

+ 22 - 0
src/app/api/log/route.ts

@@ -0,0 +1,22 @@
+import {NextRequest, NextResponse} from "next/server";
+import {AxiosResponse} from "axios";
+import {serverGet} from "@/utils/axiosServer";
+import {R} from "@/utils/R"
+export const GET = async (request:NextRequest)=>{
+  const {searchParams} = new URL(request.url);
+  const pageNum = searchParams.get("pageNum");
+  const pageSize = searchParams.get("pageSize");
+  const conditionJson = searchParams.get("conditionJson");
+  const res = await serverGet<any,LogResponseServer>("/log/list",{
+    params:{
+      pageNum,
+      pageSize,
+      conditionJson
+    }
+  });
+  // console.log(res);
+  if(res.code !== 200){
+    return NextResponse.json(R.error(res.msg));
+  }
+  return NextResponse.json(R.success(res.data));
+}

+ 63 - 0
src/app/api/timeTask/route.ts

@@ -0,0 +1,63 @@
+import {NextRequest, NextResponse} from "next/server";
+import {serverGet, serverPost} from "@/utils/axiosServer";
+import {AreaType, ButtonType, ScheduleType, TaskScheduleReponse, TaskTypeResponse} from "@/type/timeTask/type";
+import {R} from "@/utils/R"
+export const GET =async (request:NextRequest)=>{
+  const res = await serverGet<any,TaskScheduleReponse>("/timeTask/getAllTask")
+  const res2 = await serverGet<any,TaskTypeResponse>("/timeTask/getAllTaskType");
+  const scheduleKey = res2.data.map(q=>({s:q.scheduleType,c:q.cornExpress}))
+  if(res.code !== 200){
+    return NextResponse.json(R.error(res.msg))
+  }
+  //每一个map的键对应一个数组 键为scheduleType
+  const map = res.data.reduce((pre, cur)=>{
+    const key = cur.scheduleType;
+    if(pre.has(key)){
+      pre.get(key).push(cur)
+    }else{
+      pre.set(key,[cur])
+    }
+    return pre
+  },new Map);
+  const arr = Array.from(map.entries());
+  //转为ButtonType[]形式
+  const result:AreaType[] = arr.map(([key,value])=>{
+    return {
+      id:key,
+      title:key,
+      buttons:value,
+      cornExpression:value[0].cronExpression
+    }
+  })
+  // console.log(result);
+  scheduleKey.forEach(q=>{
+    //判断是否有result里面没有的scheduleType
+    if(!result.some(q2=>q2.title === q.s)){
+      result.push({
+        id:q.s,
+        title:q.s,
+        buttons:[],
+        cornExpression:q.c
+      })
+    }
+  })
+  return NextResponse.json(R.success(result))
+}
+
+export const POST = async (request:NextRequest)=>{
+  const req:AreaType[] = await request.json();
+  for (let i = 0; i < req.length; i++) {
+    const q = req[i];
+    q.buttons.map((item:ButtonType)=>{
+      item.cronExpression = q.cornExpression;
+      item.scheduleType = q.title;
+      return item;
+    });
+  }
+  const toServerList = req.flatMap(q=>q.buttons);
+  const res:any = await serverPost("/timeTask/updateAllModifySchedule",toServerList);
+  if(res.code !== 200){
+    return NextResponse.json(R.error(res.msg))
+  }
+  return NextResponse.json(new R(200,null,"更新定时任务成功"))
+}

+ 26 - 0
src/app/globals.css

@@ -0,0 +1,26 @@
+@import "@unocss/reset/tailwind.css";
+@unocss all;
+
+/*:root {*/
+/*  --foreground-rgb: 0, 0, 0;*/
+/*  --background-start-rgb: 214, 219, 220;*/
+/*  --background-end-rgb: 255, 255, 255;*/
+/*}*/
+
+/*@media (prefers-color-scheme: dark) {*/
+/*  :root {*/
+/*    --foreground-rgb: 255, 255, 255;*/
+/*    --background-start-rgb: 0, 0, 0;*/
+/*    --background-end-rgb: 0, 0, 0;*/
+/*  }*/
+/*}*/
+
+/*body {*/
+/*  color: rgb(var(--foreground-rgb));*/
+/*  background: linear-gradient(*/
+/*      to bottom,*/
+/*      transparent,*/
+/*      rgb(var(--background-end-rgb))*/
+/*    )*/
+/*    rgb(var(--background-start-rgb));*/
+/*}*/

+ 106 - 0
src/app/invoke/map.ts

@@ -0,0 +1,106 @@
+export const serviceMap =new Map<string,string>()
+serviceMap.set("xcrCompanyInvestmentServiceImpl", "gateway/api/1/getGdjczxgxxByUniscid");
+serviceMap.set("xcrEquityChangeServiceImpl", "gateway/api/1/getGqczbgxxByUniscid");
+serviceMap.set("xcrSupplementaryForeignInvestmentServiceImpl", "gateway/api/1/getWzbcxxByUniscid");
+serviceMap.set("xcrAppointDelegatesServiceImpl", "gateway/api/1/getWpdbxxByUniscid");
+serviceMap.set("xcrAgriculturalSupplementServiceImpl", "gateway/api/1/getNzbcxxByUniscid");
+serviceMap.set("xcrDomesticCapitalSupplementServiceImpl", "gateway/api/1/getNzbcxxByUniscid1");
+serviceMap.set("xcrInstallmentPaymentServiceImpl", "gateway/api/1/getFqsjxxByUniscid");
+serviceMap.set("xcrInvestorSubscriptionDetailsServiceImpl", "gateway/api/1/getTzrrjxxByUniscid");
+serviceMap.set("xcrNonNaturalPersonContributionServiceImpl", "gateway/api/1/getFzrrczxxByUniscid");
+serviceMap.set("xcrNaturalPersonContributionsServiceImpl", "gateway/api/1/getZrrczxxByUniscid");
+serviceMap.set("xcrHistoryNameServiceImpl", "gateway/api/1/getLsmcxxByUnscid");
+serviceMap.set("xcrHistoricalLegalRepresentativeServiceImpl", "gateway/api/1/getLsfddbrxxByUniscid");
+serviceMap.set("xcrAbnormalHouseholdTerminationServiceImpl", "gateway/api/1/getFzchjcxxByUniscid");
+serviceMap.set("xcrTaxAdministrativePenaltyServiceImpl", "gateway/api/1/getSwxzcfxxByUniscid");
+serviceMap.set("xcrAffiliatedEnterpriseServiceImpl", "gateway/api/1/getLsqyxxByUniscid");
+serviceMap.set("xcrInstallmentSubscriptionServiceImpl", "gateway/api/1/getFqrjxxByUniscid");
+serviceMap.set("xcrAdministrativeLicensingAgriculturalCollegesServiceImpl", "gateway/api/1/getNznbxzxkxxByUniscid");
+serviceMap.set("xcrEnterpriseExceptionListServiceImpl", "gateway/api/1/getQyycmlxxByUniscid1");
+serviceMap.set("xcrInvestorAbnormalRecordServiceImpl", "gateway/api/1/getQyjyycmlgdxxByUnsicd");
+serviceMap.set("xcrEnterprisePublicityLicenseServiceImpl", "gateway/api/1/getQygsxkxxByUniscid");
+serviceMap.set("xcrEnterprisePublicityEquityChangeServiceImpl", "gateway/api/1/getQygsgqbgxxByUniscid");
+serviceMap.set("xcrSimplifiedCancellationAnnouncementServiceImpl", "gateway/api/1/getJyzxggxxByUniscid");
+serviceMap.set("xcrCancelTaxRegistrationServiceImpl", "gateway/api/1/getZxswdjxxByUniscid");
+serviceMap.set("xcrEnterprisePublicityInvestorInformationStatusServiceImpl", "gateway/api/1/getQygsczrxxqkByUniscid");
+serviceMap.set("xcrEnterprisePublicityDetailsContributionsContributorsServiceImpl", "gateway/api/1/getCzrsjmxByUniscid");
+serviceMap.set("xcrEnterprisePublicationSupplySubscribedDetailsInvestorsServiceImpl", "gateway/api/1/getQygsczrrjmxByUniscid");
+serviceMap.set("xcrRevisionInformationAgriculturalCollegeAnnualReportServiceImpl", "gateway/api/1/getNznbxgxxByUniscid");
+serviceMap.set("xcrBasicSupplementAgriculturalCollegeAnnualServiceImpl", "gateway/api/1/getNznbjbxxbcByUniscid");
+serviceMap.set("xcrEnterpriseBasicInformationServiceImpl", "gateway/api/1/getQyjbxxByUniscid");
+serviceMap.set("xcrEnterpriseNameApprovalServiceImpl", "gateway/api/1/getQymcxxByUniscid");
+serviceMap.set("xcrSeriousIllegalDishonestEnterprisesServiceImpl", "gateway/api/1/getYzwfsxqymdBydm");
+serviceMap.set("xcrSeriousIllegalDishonestEnterprisesDetailServiceImpl", "gateway/api/1/getYzwfxxxxByUniscid");
+serviceMap.set("xcrEquityPledgeInfoServiceImpl", "gateway/api/1/getGqczdjxxBydm");
+serviceMap.set("xcrEquityFreezeServiceImpl", "gateway/api/1/getGqdjxxByUniscid");
+serviceMap.set("xcrEquityChangeInfoServiceImpl", "gateway/api/1/getGqbgxxByUniscid");
+serviceMap.set("xcrEquityFreezeExecutionServiceImpl", "gateway/api/1/getGqdjbzxrxxByUniscid");
+serviceMap.set("xcrAbnormalBusinessOperationsServiceImpl", "gateway/api/1/getQyycmlxxxxByUniscid");
+serviceMap.set("xcrCheckWorkInfoServiceImpl", "gateway/api/1/getJcgzxxByUniscid");
+serviceMap.set("xcrTaxRegistrationEstablishmentServiceImpl", "gateway/api/1/getSwdjslxxByUniscid");
+serviceMap.set("xcrStopBusinessInformationServiceImpl", "gateway/api/1/getGtgshtxyxxByUniscid");
+serviceMap.set("xcrAbnormalHouseholdIdentificationServiceImpl", "gateway/api/1/getFzchrdxxByUniscid");
+serviceMap.set("xcrIncomeTaxReturnServiceImpl", "gateway/api/1/getQysdssbxxByUniscid1");
+serviceMap.set("xcrMainFinancialStatementsServiceImpl", "gateway/api/1/getCwbbzbByUniscid");
+serviceMap.set("xcrInvoiceIssuanceServiceImpl", "gateway/api/1/fpkpxxByUniscid");
+serviceMap.set("xcrConfirmationTerminationServiceImpl", "gateway/api/1/getFzchrdjcxxbByUniscid");
+serviceMap.set("xcrTaxpayerCreditRatingServiceImpl", "gateway/api/1/getNsrxydjByUniscid");
+serviceMap.set("xcrInstitutionalClientsServiceImpl", "gateway/api/1/getJgkhxxByUnisicd");
+serviceMap.set("xcrRecordDishonestyServiceImpl", "gateway/api/1/getSxjlmdByQymc");
+serviceMap.set("xcrTechnologyPlanProjectServiceImpl", "gateway/api/1/getKjjhxmapbByQymc");
+serviceMap.set("xcrTechnologyAwardSupplementServiceImpl", "gateway/api/1/getKjjbxmjzjqkByQymc");
+serviceMap.set("xcrMinorEnterprisesServiceImpl", "gateway/api/1/getKjxzxqymdByQymc");
+serviceMap.set("xcrInnovationPlatformServiceImpl", "gateway/api/1/getCxptmd");
+serviceMap.set("xcrHighTechServiceImpl", "gateway/api/1/getGxjsqymdByUniscid");
+serviceMap.set("xcrFoodProductionLicenseDetaliServiceImpl", "gateway/api/1/getSpscxkzpzmxByUniscid");
+serviceMap.set("xcrLegalRepresentativeServiceImpl", "gateway/api/1/getSpscfddbrxxByUniscid");
+serviceMap.set("xcrFoodProductionLicenseServiceImpl", "gateway/api/1/getSpscxkzjbxxByUniscid");
+serviceMap.set("xcrFoodBusinessLicenseServiceImpl", "gateway/api/1/getSpjyxkzjbxxByUniscid");
+serviceMap.set("xcrMsAdministrativeLicenseServiceImpl", "gateway/api/1/getXzxkxxByUniscid");
+serviceMap.set("xcrContactInformationServiceImpl", "gateway/api/1/getLlyxxByUniscid");
+serviceMap.set("xcrFinancialManagerServiceImpl", "gateway/api/1/getCwfzrByUniscid");
+serviceMap.set("xcrPersonalRevokeRecordServiceImpl", "gateway/api/1/getGtdxxxByUniscid");
+serviceMap.set("xcrNoticeRecordServiceImpl", "gateway/api/1/getGsggxxByUniscid");
+serviceMap.set("xcrWebsiteInfoServiceImpl", "gateway/api/1/getGtnbwzhwdxxByUniscid");
+serviceMap.set("xcrSmallAndMicroEnterprisesServiceImpl", "gateway/api/1/getXwqymljbxxByUniscid");
+serviceMap.set("xcrRandomInspectionTaskServiceImpl", "gateway/api/1/getJcgzxxmlByUniscid");
+serviceMap.set("xcrAnnualReportExternalInvestmentServiceImpl", "gateway/api/1/getQynbdwtzxxByUniscid");
+serviceMap.set("xcrExternalGuaranteeServiceImpl", "gateway/api/1/getQynbdwtgbzxxByUniscid");
+serviceMap.set("xcrRevokeInfoServiceImpl", "gateway/api/1/getDxxxByUniscid");
+serviceMap.set("xcrBranchOfficesInfoServiceImpl", "gateway/api/1/getFzjgbaxxByUniscid1");
+serviceMap.set("xcrLicenseInfoServiceImpl", "gateway/api/1/getXkxxByUniscid");
+serviceMap.set("xcrChangeFilingServiceImpl", "gateway/api/1/getBgbaxxByUniscid");
+serviceMap.set("xcrSocialInsuranceDataServiceImpl", "gateway/api/1/getQynbshbxxxByUniscid");
+serviceMap.set("xcrAgriculturalCollegeAnnualReportServiceImpl", "gateway/api/1/getNznbjbxxByUniscid");
+serviceMap.set("xcrEnterprisePollutionPermitInfoServiceImpl", "gateway/api/1/getQypwxkxxByUniscid");
+serviceMap.set("xcrKeyPollutionSourcesServiceImpl", "gateway/api/1/getZdpwdwmlByShxyfwm");
+serviceMap.set("xcrEnvironmentalPenaltyDecisionServiceImpl","gateway/api/1/getHbcfjdqkxxByUniscid");
+serviceMap.set("xcrIndividualBusinessInformationServiceImpl","gateway/api/1/getGtjyzjbxxByUniscid");
+serviceMap.set("xcrIndustryCommerceServiceImpl","gateway/api/1/getGtgshjbxxByUniscid");
+serviceMap.set("xcrAgriculturalSpecializedWebsiteService","gateway/api/1/nznbwzhwdxxByUniscid");
+serviceMap.set("xcrIndividualChangeInformationServiceImpl","gateway/api/1/getGtbgxxByUniscid");
+serviceMap.set("xcrIndividualCancellationServiceImpl","gateway/api/1/getGtzxxxByUniscid");
+serviceMap.set("xcrIndividualBusinessAbnormalityServiceImpl","gateway/api/1/getGtjyycbjxxByUniscid");
+serviceMap.set("xcrMoveOutServiceImpl","gateway/api/1/getQcxxByUniscid");
+serviceMap.set("xcrMoveInServiceImpl","gateway/api/1/getQrxxByUniscid");
+serviceMap.set("xcrDeregistrationServiceImpl","gateway/api/1/getCxdjxxByUniscid");
+serviceMap.set("xcrCancellationServiceImpl","gateway/api/1/getZxxxByUniscid");
+serviceMap.set("xcrLiquidationBasicInfoServiceImpl","gateway/api/1/getQsjbxxByUniscid1");
+serviceMap.set("xcrLiquidationMemberInfoServiceImpl","gateway/api/1/getQscyxxByUniscid");
+serviceMap.set("xcrAbnormalOperationAnnouncementServiceImpl","gateway/api/1/getJyycggplmdxxByUniscid");
+serviceMap.set("xcrFarmSpecialAbnormalDetailServiceImpl","gateway/api/1/getNzycmlxxxxByUniscid");
+serviceMap.set("xcrEnterpriseAnnualReportWebsiteServiceImpl","gateway/api/1/getQynbwzhwdxxByUniscid");
+serviceMap.set("xcrEnterpriseAnnualReportEquityChangeServiceImpl","gateway/api/1/getQynbgqbgxxByUniscid");
+serviceMap.set("xcrIndividualCancellationObjectionServiceImpl","gateway/api/1/getJyzxyyxxByUniscid");
+serviceMap.set("xcrRevokeRegistrationServiceImpl","gateway/api/1/getGtcxdjxxByUniscid");
+serviceMap.set("xcrAgriculturalSpecializedWebsiteServiceImpl","gateway/api/1/nznbwzhwdxxByUniscid");
+serviceMap.set("xcrAnSfcBranchinfoServiceImpl","gateway/api/1/getNznbfzjgxxByUniscid");
+serviceMap.set("xcrMajorMembersServiceImpl","gateway/api/1/zyryxxByUniscid");
+serviceMap.set("xcrOtherInfo36ServiceImpl","interface/v1/datawarehouse/list");
+serviceMap.set("xcrAdministrativeLicensingServiceImpl","interface/v1/doublePublic/findLicensingList");
+serviceMap.set("xcrAdministrativePenaltyServiceImpl","interface/v1/doublePublic/findSanctionList");
+serviceMap.set("xcrOtherInfo37ServiceImpl","interface/v1/datawarehouse/list");
+serviceMap.set("xcrOtherInfo38ServiceImpl","interface/v1/datawarehouse/list");
+serviceMap.set("xcrOtherInfo39ServiceImpl","interface/v1/datawarehouse/list");
+serviceMap.set("xcrTrustworthyIncentive42ServiceImpl","interface/v1/datawarehouse/list");
+serviceMap.set("xcrDishonestyPunishment19ServiceImpl","interface/v1/datawarehouse/list");

+ 25 - 0
src/app/invoke/page.tsx

@@ -0,0 +1,25 @@
+'use client'
+import React from 'react';
+import {Card, Col, Row} from "antd";
+import LadderShapedTab from "@/components/LadderShapedTab";
+import {usePathname} from "next/navigation";
+
+function Page() {
+  const pathname = usePathname();
+  return (
+    <Row>
+      <Col span={24}>
+        <LadderShapedTab currentTab={pathname}/>
+      </Col>
+      <Col span={20}>
+        <Card title="Card title">
+          <p>Card content</p>
+          <p>Card content</p>
+          <p>Card content</p>
+        </Card>
+      </Col>
+    </Row>
+  );
+}
+
+export default Page;

+ 25 - 0
src/app/layout.tsx

@@ -0,0 +1,25 @@
+import { Inter } from 'next/font/google'
+import './globals.css'
+import {AntdRegistry} from "@ant-design/nextjs-registry";
+import Head from "next/head";
+
+const inter = Inter({ subsets: ['latin'] })
+
+export const metadata = {
+  title: '数据采集服务管理系统',
+  description: '数据采集服务管理系统',
+}
+
+export default function RootLayout({
+  children,
+}: {
+  children: React.ReactNode
+}) {
+  return (
+    <html lang="zh">
+      <body className={inter.className}>
+        <AntdRegistry>{children}</AntdRegistry>
+      </body>
+    </html>
+  )
+}

+ 108 - 0
src/app/log/page.tsx

@@ -0,0 +1,108 @@
+"use client"
+import React, {useCallback, useEffect, useState} from 'react';
+import { Card, Col, Pagination, Row, Table, Tag } from 'antd';
+import type { TableColumnsType, TablePaginationConfig } from 'antd';
+import { clientGet } from "@/utils/axiosClient";
+import { message } from 'antd';
+import { timeFormatter } from "@/utils/timeFormatter";
+import LadderShapedTab from "@/components/LadderShapedTab";
+import {usePathname} from "next/navigation";
+
+const columns: TableColumnsType<ResponseDataItem> = [
+  { title: '业务名', dataIndex: 'businessName', key: 'businessName' },
+  { title: '参数', dataIndex: 'params', key: 'params' },
+  { title: '是否成功', dataIndex: 'isSuccess', key: 'isSuccess', width: 100, render: (text,record) => record.isRunning === 0 && (<Tag color={text === 1 ? 'green' : 'red'}>{text === 1 ? '成功' : '失败'}</Tag>) },
+  { title: '是否运行中', dataIndex: 'isRunning', key: 'isRunning', width: 120, render: (text) => (<Tag color={text === 1 ? 'cyan' : 'green'}>{text === 1 ? '运行中' : '完毕'}</Tag>) },
+  { title: '用时', dataIndex: 'useTime', key: 'useTime', render: (text) => (<p>{(text / 1000).toFixed(2)}秒</p>) },
+  { title: '发起时间', dataIndex: 'createTime', key: 'createTime', render: (text) => (<p>{timeFormatter(text)}</p>) },
+  { title: '完成时间', dataIndex: 'updateTime', key: 'updateTime', render: (text) => (<p>{timeFormatter(text)}</p>) },
+];
+
+const Page: React.FC = () => {
+  const pathname = usePathname();
+  const [tableData, setTableData] = useState<ResponseDataItem[]>([]);
+  const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]);
+  const [pagination, setPagination] = useState<TablePaginationConfig>({
+    current: 1,
+    pageSize: 10,
+    total: 0,
+    showTotal: (total) => `共 ${total} 条数据`,
+    locale: {
+      items_per_page: '条/页'
+    }
+  });
+
+  const getList =async (params: BasePageRequest) => {
+    const res = await clientGet<any, LogResponseClient>('/api/log', { params });
+    if (res.code !== 200) {
+      message.error(res.message);
+    } else {
+      setTableData(res.data.list);
+      setPagination({ ...pagination, total: res.data.total });
+    }
+  }
+  const handleExpand = useCallback((expanded: boolean, record: ResponseDataItem) => {
+    if (expanded) {
+      setExpandedRowKeys([...expandedRowKeys, record.id]);
+    } else {
+      setExpandedRowKeys(expandedRowKeys.filter(key => key !== record.id));
+    }
+  },[]);
+  const handleTableChange = useCallback((newPagination: TablePaginationConfig) => {
+    setPagination(newPagination);
+  },[]);
+  let conditionJsonWhole = [];
+  conditionJsonWhole.push({
+    column:'create_time',
+    type:'orderByDesc'
+  })
+  const s = encodeURIComponent(JSON.stringify(conditionJsonWhole));
+  useEffect(() => {
+    getList({ pageNum: pagination.current, pageSize: pagination.pageSize,conditionJson:s });
+  }, [pagination.current, pagination.pageSize]);
+  return (
+    <>
+      <Row>
+        <Col span={24}>
+          <LadderShapedTab currentTab={pathname}/>
+        </Col>
+        <Col span={24}>
+          <div className={'text-4xl font-bold mb-4 text-center mt-5 mb-5'}>
+            数据采集服务日志
+          </div>
+        </Col>
+        <Col span={24}>
+          <Table<ResponseDataItem>
+            columns={columns}
+            expandable={{
+              expandedRowRender: (record) => record.isSuccess === 0 ? (
+                <Card
+                  title={'异常信息'}
+                  className={'bg-white p-4 w-97vw'}
+                >
+                  <div className={'text-red-500'}>
+                    {record.exception}
+                  </div>
+                </Card>
+              ) : null,
+              expandedRowKeys: expandedRowKeys,
+              onExpand: handleExpand,
+              expandRowByClick: true,
+              rowExpandable: (record) => record.isSuccess === 0,
+            }}
+            scroll={{
+              x: 'max-content',
+              y: '600px',
+            }}
+            dataSource={tableData}
+            rowKey="id"
+            pagination={pagination}
+            onChange={handleTableChange}
+          />
+        </Col>
+      </Row>
+    </>
+  );
+};
+
+export default Page;

+ 10 - 0
src/app/page.tsx

@@ -0,0 +1,10 @@
+import { type Resource, Resources } from '@/components/Resources'
+import {Button} from "antd";
+
+export default function Home() {
+  return (
+    <>
+      <Button>好想你</Button>
+    </>
+  )
+}

+ 154 - 0
src/app/timeTask/page.tsx

@@ -0,0 +1,154 @@
+'use client'
+
+import React, {useEffect, useState} from 'react'
+import {Button, Card, Row, Col, Modal, message} from 'antd'
+import LadderShapedTab from "@/components/LadderShapedTab";
+import {usePathname} from "next/navigation";
+import {clientGet, clientPost} from "@/utils/axiosClient";
+import {AreaType, ButtonType, TaskScheduleClientReponse} from "@/type/timeTask/type";
+
+export default function page() {
+  const [areas, setAreas] = useState<AreaType[]>([])
+  const [open, setOpen] = useState(false);
+  const [confirmLoading, setConfirmLoading] = useState(false);
+  const [modalText, setModalText] = useState('确定要同步这个定时任务控制?');
+  const pathname = usePathname();
+  const showModal = () => {
+    setOpen(true);
+    setModalText("确定要同步这个定时任务控制?");
+    console.log(areas);
+  };
+
+  const handleOk = async () => {
+    setModalText('正在提交中请稍后');
+    setConfirmLoading(true);
+    await updateTask()
+    setOpen(false);
+    setConfirmLoading(false);
+
+  };
+
+  const handleCancel = () => {
+    setOpen(false);
+  };
+
+  const [draggedButton, setDraggedButton] = useState<ButtonType | null>(null)
+
+  const onDragStart = (e: React.DragEvent<HTMLDivElement>, button: ButtonType) => {
+    setDraggedButton(button)
+    e.dataTransfer.setData('text/plain', JSON.stringify(button))
+  }
+
+  const onDragOver = (e: React.DragEvent<HTMLDivElement>) => {
+    e.preventDefault()
+  }
+
+  const onDrop = (e: React.DragEvent<HTMLDivElement>, targetAreaId: string, targetIndex: number) => {
+    e.preventDefault()
+    if (draggedButton === null) return
+
+    const newAreas = areas.map(area => ({...area, buttons: [...area.buttons]}))
+
+    // Remove the button from its original position
+    const sourceArea = newAreas.find(area => area.buttons.includes(draggedButton))
+    if (sourceArea) {
+      sourceArea.buttons = sourceArea.buttons.filter(btn => btn !== draggedButton)
+    }
+
+    // Add the button to its new position
+    const targetArea = newAreas.find(area => area.id === targetAreaId)
+    if (targetArea) {
+      targetArea.buttons.splice(targetIndex, 0, draggedButton)
+    }
+    setAreas(newAreas)
+    setDraggedButton(null)
+  }
+
+  const getAllTask = async () => {
+    const res = await clientGet<any, TaskScheduleClientReponse>('/api/timeTask')
+    if (res.code !== 200) {
+      message.error(res.message)
+    }
+    console.log(res.data);
+    setAreas(res.data)
+  }
+  const generateSchedule = (schedule: string): string => {
+    let [prefix, number] = schedule.split(/(\d+)/);
+    prefix = prefix.split('-')[1]
+    switch (prefix) {
+      case 'day':
+        return `每天${number}点更新`;
+      case 'week':
+        return `每周${number}点更新`;
+      case 'month':
+        return `每月${number}点更新`;
+      default:
+        return "未决";
+    }
+  };
+
+  const updateTask = async () => {
+    const res: any = await clientPost<AreaType[]>('/api/timeTask', areas)
+    if (res.code !== 200) {
+      message.error(res.message)
+    }
+    message.success(res.message)
+  }
+
+  const rightClick = (button: ButtonType)=> (e: React.MouseEvent)=>{
+    e.preventDefault()
+    message.info('右键菜单')
+    console.log(button)
+  }
+
+  useEffect(() => {
+    getAllTask()
+  }, []);
+
+  return (
+    <Row gutter={[16, 16]}>
+      <Col span={24}>
+        <LadderShapedTab currentTab={usePathname()}/>
+      </Col>
+      <Col span={24}>
+        <Button type={'primary'} onClick={showModal}>点我同步所有的任务</Button>
+        <Modal
+          title="提交定时任务控制"
+          open={open}
+          onOk={handleOk}
+          confirmLoading={confirmLoading}
+          onCancel={handleCancel}
+          cancelText={'取消'}
+          okText={'确定'}
+        >
+          <p>{modalText}</p>
+        </Modal>
+      </Col>
+      {areas.map(area => (
+        <Col xs={24} sm={12} md={8} key={area.id}>
+          <Card
+            title={generateSchedule(area.title)}
+            onDragOver={onDragOver}
+            onDrop={(e) => onDrop(e, area.id, area.buttons.length)}
+            style={{minHeight: '150px'}}
+          >
+            <div className={'flex flex-wrap'}>
+              {area.buttons.map((button, index) => (
+                <div
+                  key={button.id}
+                  draggable
+                  onDragStart={(e) => onDragStart(e, button)}
+                  onDragOver={onDragOver}
+                  onDrop={(e) => onDrop(e, area.id, index)}
+                  style={{marginBottom: '8px'}}
+                >
+                  <Button onContextMenu={rightClick(button)}>{button.serviceName}</Button>
+                </div>
+              ))}
+            </div>
+          </Card>
+        </Col>
+      ))}
+    </Row>
+  )
+}

+ 34 - 0
src/components/LadderShapedTab.tsx

@@ -0,0 +1,34 @@
+import React from 'react';
+import {usePathname, useRouter} from "next/navigation";
+
+function LadderShapedTab({ currentTab }: { currentTab: string }) {
+  const router = useRouter();
+  const pathname = usePathname();
+  const tablist = ['/log', '/invoke', '/timeTask'];
+  const tablistName = ['日志', '调用', '定时任务'];
+  const map = new Map()
+    .set(tablist[0], tablistName[0])
+    .set(tablist[1], tablistName[1])
+    .set(tablist[2], tablistName[2]);
+
+  return (
+    <>
+      <div className="tab-container mt-5 w-80% ml-auto mr-auto flex justify-center gap-8">
+        {tablist.map((item, index) => (
+          <div
+            key={index}
+            className={`flex-1 font-700 text-20px text-center h-50px line-height-50px rounded-full bg-#3691edff cursor-pointer hover:bg-op-100 hover:text-24px duration-300 ${currentTab === item ? "bg-#3691edff text-24px" : "bg-op-40"}`}
+            onClick={() => {
+              if(pathname == item) return
+              router.push(item);
+            }}
+          >
+            {map.get(item)}
+          </div>
+        ))}
+      </div>
+    </>
+  );
+}
+
+export default LadderShapedTab;

+ 61 - 0
src/components/Resources.tsx

@@ -0,0 +1,61 @@
+import * as React from 'react'
+
+export interface Resource {
+  title: string
+  href: string
+  description: string
+}
+
+/**
+ * The Resources component is an example of UnoCSS Attributify preset
+ * Learn more: https://unocss.dev/presets/attributify
+ */
+export const Resources: React.FC<{ resources: Resource[] }> = ({ resources }) => {
+  return (
+    <div
+      m="b-32 lg:b-0"
+      grid="~ lg:cols-4"
+      text="center lg:left"
+    >
+      {
+        resources.map(({ title, href, description }) => (
+          <a
+            key={href}
+            className="group"
+            href={href}
+            rounded="lg"
+            bg="hover:gray-100 dark:hover:neutral-800/50"
+            border="~ transparent hover:gray-300 dark:hover:neutral-700"
+            p="x-5 y-4"
+            transition="colors"
+            target="_blank"
+            rel="noopener noreferrer"
+          >
+            <h2
+              m="b-3"
+              text="2xl"
+              font="semibold"
+            >
+              {title}
+              <span
+                className="group-hover:-translate-x-1 i-lucide:arrow-up-right"
+                inline="block"
+                transition="transform"
+                motion-reduce="transform-none"
+                m="l-1"
+              />
+            </h2>
+            <p
+              m="0"
+              max-w="[30ch]"
+              text="sm"
+              className="opacity-50"
+            >
+              {description}
+            </p>
+          </a>
+        ))
+      }
+    </div>
+  )
+}

+ 24 - 0
src/type/log/type.ts

@@ -0,0 +1,24 @@
+interface ResponseDataItem {
+  id: string;
+  businessName: string;
+  params: string;
+  isSuccess: number;
+  isRunning: number;
+  useTime: number;
+  exception: string | null;
+  createTime: string;
+  updateTime: string;
+}
+
+interface ResponseData {
+  total: number;
+  pages: string;
+  list: ResponseDataItem[];
+}
+
+interface LogResponseServer extends BaseResponse{
+  data: ResponseData;
+}
+interface LogResponseClient extends ClientResponse{
+  data: ResponseData;
+}

+ 48 - 0
src/type/timeTask/type.ts

@@ -0,0 +1,48 @@
+import React from "react";
+
+export type AreaType = {
+  id: string
+  title: string
+  cornExpression: string
+  buttons: ButtonType[]
+}
+
+export type ButtonType = {
+  id: number;
+  taskName: string;
+  serviceName: string;
+  cronExpression: string;
+  scheduleType: string;
+  enabled: number;
+  createdAt: string;
+  updatedAt: string;
+}
+
+export interface ScheduleType {
+  id:React.Key,
+  cornExpress:string,
+  scheduleType:string
+}
+
+export interface TaskScheduleItem {
+  id: number;
+  taskName: string;
+  serviceName: string;
+  cronExpression: string;
+  scheduleType: string;
+  enabled: number; // 假设 1 表示启用,0 表示禁用
+  createdAt: string; // ISO 8601 格式的日期时间字符串
+  updatedAt: string; // ISO 8601 格式的日期时间字符串
+}
+
+export interface TaskScheduleReponse extends BaseResponse{
+  data: TaskScheduleItem[]
+}
+
+export interface TaskScheduleClientReponse extends ClientResponse{
+  data: AreaType[]
+}
+
+export interface TaskTypeResponse extends BaseResponse{
+  data: ScheduleType[]
+}

+ 24 - 0
src/utils/R.ts

@@ -0,0 +1,24 @@
+export class R{
+  private code:number;
+  private data:any;
+  private message:string;
+  constructor(code:number,data:any,message:string) {
+    this.code = code;
+    this.data = data;
+    this.message = message;
+  }
+  static success(data:any){
+    return {
+      code:200,
+      data,
+      message:"success"
+    }
+  }
+  static error(data:any){
+    return {
+      code:500,
+      data,
+      message:"fail"
+    }
+  }
+}

+ 61 - 0
src/utils/axiosClient.ts

@@ -0,0 +1,61 @@
+'use client'
+import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
+import { message } from 'antd'; // 导入 Ant Design 的 message 组件
+
+// 创建一个 Axios 实例
+const instance: AxiosInstance = axios.create({
+  baseURL: process.env.NEXT_PUBLIC_SELF_URL, // 从环境变量中获取基础 URL
+  timeout: 10000, // 请求超时时间
+  headers: {
+    'Content-Type': 'application/json',
+  },
+});
+
+// 请求拦截器
+instance.interceptors.request.use(
+  (config: InternalAxiosRequestConfig) => {
+    // 可以在这里添加通用的请求头,例如 token
+    // config.headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`;
+    return config;
+  },
+  (error) => {
+    return Promise.reject(error);
+  }
+);
+
+// 响应拦截器
+instance.interceptors.response.use(
+  (response: AxiosResponse) => {
+    return response.data; // 返回响应数据
+  },
+  (error) => {
+    // 处理错误
+    if (error.response) {
+      // 服务器返回了错误状态码
+      const { status, data } = error.response;
+      message.error(`请求失败,状态码: ${status},错误信息: ${data.message || data}`);
+      return Promise.reject(data);
+    } else if (error.request) {
+      // 请求已发出,但没有收到响应
+      message.error('请求已发出,但没有收到响应');
+      return Promise.reject({ message: 'No response received' });
+    } else {
+      // 发生了其他错误
+      message.error(`发生错误: ${error.message}`);
+      return Promise.reject({ message: error.message });
+    }
+  }
+);
+
+// 封装常用的 HTTP 方法
+export const clientGet = <T = any, R = any>(url: string, config?: AxiosRequestConfig) =>
+  instance.get<T, R>(url, config);
+
+export const clientPost = <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
+  instance.post<T>(url, data, config);
+
+export const clientPut = <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
+  instance.put<T>(url, data, config);
+
+export const clientDel = <T = any>(url: string, config?: AxiosRequestConfig) =>
+  instance.delete<T>(url, config);

+ 60 - 0
src/utils/axiosServer.ts

@@ -0,0 +1,60 @@
+'use server'
+import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
+
+// 创建一个 Axios 实例
+const instance: AxiosInstance = axios.create({
+  baseURL: process.env.NEXT_PUBLIC_API_URL, // 从环境变量中获取基础 URL
+  timeout: 10000, // 请求超时时间
+  headers: {
+    'Content-Type': 'application/json',
+  },
+});
+
+// 请求拦截器
+instance.interceptors.request.use(
+  (config: InternalAxiosRequestConfig) => {
+    // 可以在这里添加通用的请求头,例如 token
+    // config.headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`;
+    return config;
+  },
+  (error) => {
+    return Promise.reject(error);
+  }
+);
+
+// 响应拦截器
+instance.interceptors.response.use(
+  (response: AxiosResponse) => {
+    return response.data; // 返回响应数据
+  },
+  (error) => {
+    // 处理错误
+    if (error.response) {
+      // 服务器返回了错误状态码
+      const { status, data } = error.response;
+      console.error(`Request failed with status code ${status}:`, data);
+      return Promise.reject(data);
+    } else if (error.request) {
+      // 请求已发出,但没有收到响应
+      console.error('No response received:', error.request);
+      return Promise.reject({ message: 'No response received' });
+    } else {
+      // 发生了其他错误
+      console.error('Error:', error.message);
+      return Promise.reject({ message: error.message });
+    }
+  }
+);
+
+// 封装常用的 HTTP 方法
+export const serverGet = async <T = any, R = any>(url: string, config?: AxiosRequestConfig) =>
+  instance.get<T, R>(url, config);
+
+export const serverPost = async <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
+  instance.post<T>(url, data, config);
+
+export const serverPut = async <T = any>(url: string, data?: any, config?: AxiosRequestConfig) =>
+  instance.put<T>(url, data, config);
+
+export const serverDel = async <T = any>(url: string, config?: AxiosRequestConfig) =>
+  instance.delete<T>(url, config);

+ 4 - 0
src/utils/timeFormatter.ts

@@ -0,0 +1,4 @@
+export const timeFormatter = (time: number| string) => {
+  const date = new Date(time);
+  return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}时${date.getMinutes()}分${date.getSeconds()}秒`;
+}

+ 28 - 0
tsconfig.json

@@ -0,0 +1,28 @@
+{
+  "compilerOptions": {
+    "incremental": true,
+    "target": "es5",
+    "jsx": "preserve",
+    "lib": ["dom", "dom.iterable", "esnext"],
+    "module": "esnext",
+    "moduleResolution": "node",
+    "paths": {
+      "@/*": ["./src/*"]
+    },
+    "resolveJsonModule": true,
+    "allowJs": true,
+    "strict": true,
+    "noEmit": true,
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+    "isolatedModules": true,
+    "skipLibCheck": true,
+    "plugins": [
+      {
+        "name": "next"
+      }
+    ]
+  },
+  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+  "exclude": ["node_modules"]
+}

+ 21 - 0
uno.config.ts

@@ -0,0 +1,21 @@
+import {
+  defineConfig,
+  presetAttributify,
+  presetIcons,
+  presetUno,
+} from 'unocss'
+
+export default defineConfig({
+  presets: [
+    presetUno({
+      dark: 'media',
+    }),
+    presetAttributify(),
+    presetIcons({
+      extraProperties: {
+        'display': 'inline-block',
+        'vertical-align': 'middle',
+      },
+    }),
+  ],
+})