mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 11:13:43 +08:00
Mirrors the feishu one-click flow: scan a QR with the DingTalk app,
approve, and the bot's client_id / client_secret get auto-filled instead
of forcing the user through the open-dev console. Saves about seven
manual steps per channel setup.
Backend
- Bump dingtalk-stream from 1.3.5 to 1.3.12. Diff against the classes we
depend on (OpenDingTalkStreamClient, ChatbotMessage, MessageContent,
GenericEventListener) is empty — pure point-release bumps, no API churn.
- New DingTalkAppRegistrationService: synchronously runs init + begin
against /app/registration/{init,begin} on oapi.dingtalk.com to obtain
the device_code and verification URL, then spawns a daemon worker that
polls /app/registration/poll every 5s until SUCCESS / FAIL / EXPIRED is
returned. Sessions evict after 7 minutes, worker has a 6-minute hard
runtime cap, transient HTTP errors do not terminate the loop. Same
shape as the feishu service, but written from scratch because the
dingtalk-stream SDK doesn't wrap this OAuth device flow.
- Two new endpoints under /api/v1/channels/webhook:
POST /dingtalk/register/begin returns session_id;
GET /dingtalk/register/status returns status + qrcode_img (data URI
PNG, ZXing-encoded from the verification URL, matching the feishu and
weixin flows). Status surface: waiting / confirmed / expired / denied.
Frontend
- channelApi.dingtalkRegisterBegin / dingtalkRegisterStatus.
- New useDingTalkAppRegister composable, structurally identical to
useFeishuAppRegister minus the domain argument. Stops polling on
terminal status, fires onConfirmed with {clientId, clientSecret}.
- ChannelEditModal: dingtalk-register-card rendered when channelType is
dingtalk, scoped DingTalk blue (#1f79ff) to differentiate from feishu's
indigo. onConfirmed writes channelConfig.client_id / client_secret so
the existing form fields update reactively.
- i18n: channels.dingtalkRegister.* keys for title / hint / button states
/ scan / confirmed / expired / denied / startFailed.
526 lines
21 KiB
XML
526 lines
21 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<groupId>vip.mate</groupId>
|
||
<artifactId>mateclaw-server</artifactId>
|
||
<version>1.1.137-SNAPSHOT</version>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>MateClaw Server</name>
|
||
<description>MateClaw - Java+Vue Personal AI Assistant powered by Spring AI Alibaba</description>
|
||
|
||
<parent>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-parent</artifactId>
|
||
<version>3.5.13</version>
|
||
<relativePath/>
|
||
</parent>
|
||
|
||
<properties>
|
||
<java.version>21</java.version>
|
||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||
<!-- Spring AI 1.1.4 正式版 -->
|
||
<spring-ai.version>1.1.4</spring-ai.version>
|
||
<!-- Spring AI Alibaba 1.1.2.2(对应 Spring AI 1.1.x) -->
|
||
<spring-ai-alibaba.version>1.1.2.2</spring-ai-alibaba.version>
|
||
<mybatis-plus.version>3.5.16</mybatis-plus.version>
|
||
<hutool.version>5.8.26</hutool.version>
|
||
<springdoc.version>2.8.16</springdoc.version>
|
||
<jjwt.version>0.12.6</jjwt.version>
|
||
</properties>
|
||
|
||
<dependencyManagement>
|
||
<dependencies>
|
||
<!-- Spring AI BOM(统一管理 spring-ai-* 版本) -->
|
||
<dependency>
|
||
<groupId>org.springframework.ai</groupId>
|
||
<artifactId>spring-ai-bom</artifactId>
|
||
<version>${spring-ai.version}</version>
|
||
<type>pom</type>
|
||
<scope>import</scope>
|
||
</dependency>
|
||
<!-- SpringDoc OpenAPI BOM(统一管理 springdoc-* 版本) -->
|
||
<dependency>
|
||
<groupId>org.springdoc</groupId>
|
||
<artifactId>springdoc-openapi-bom</artifactId>
|
||
<version>${springdoc.version}</version>
|
||
<type>pom</type>
|
||
<scope>import</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
</dependencyManagement>
|
||
|
||
<dependencies>
|
||
<!-- ===== MateClaw Plugin API ===== -->
|
||
<dependency>
|
||
<groupId>vip.mate</groupId>
|
||
<artifactId>mateclaw-plugin-api</artifactId>
|
||
<version>1.1.0-SNAPSHOT</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Web MVC(不引入 WebFlux,避免自动切换为响应式模式) ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-web</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Actuator — exposes Spring AI observation metrics (gen_ai.*) ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring AI Alibaba DashScope ===== -->
|
||
<!--
|
||
1.1.2.2 需单独指定版本,不在 BOM 中
|
||
内置 DashScope ChatModel / EmbeddingModel / ImageModel
|
||
-->
|
||
<dependency>
|
||
<groupId>com.alibaba.cloud.ai</groupId>
|
||
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
|
||
<version>${spring-ai-alibaba.version}</version>
|
||
<!-- 排除 webflux 传递依赖,保持 MVC 模式 -->
|
||
<exclusions>
|
||
<exclusion>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</exclusion>
|
||
</exclusions>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring AI Alibaba Graph Core(StateGraph 工作流引擎) ===== -->
|
||
<dependency>
|
||
<groupId>com.alibaba.cloud.ai</groupId>
|
||
<artifactId>spring-ai-alibaba-graph-core</artifactId>
|
||
<version>${spring-ai-alibaba.version}</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring AI OpenAI Compatible ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.ai</groupId>
|
||
<artifactId>spring-ai-openai</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring AI Anthropic(Claude 模型支持) ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.ai</groupId>
|
||
<artifactId>spring-ai-anthropic</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring AI MCP Client(动态 MCP server 连接管理) ===== -->
|
||
<!--
|
||
使用 spring-ai-mcp-client-spring-boot-starter 引入 MCP 核心库,
|
||
但禁用自动配置(我们自己管理 McpSyncClient 生命周期)
|
||
-->
|
||
<dependency>
|
||
<groupId>org.springframework.ai</groupId>
|
||
<artifactId>spring-ai-starter-mcp-client</artifactId>
|
||
<exclusions>
|
||
<exclusion>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||
</exclusion>
|
||
</exclusions>
|
||
</dependency>
|
||
|
||
<!-- ===== H2 内嵌数据库(开发环境) ===== -->
|
||
<dependency>
|
||
<groupId>com.h2database</groupId>
|
||
<artifactId>h2</artifactId>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
|
||
<!-- ===== MySQL 驱动(生产环境) ===== -->
|
||
<dependency>
|
||
<groupId>com.mysql</groupId>
|
||
<artifactId>mysql-connector-j</artifactId>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
|
||
<!-- ===== MyBatis Plus(不引入 JPA,避免双 ORM 冲突) ===== -->
|
||
<dependency>
|
||
<groupId>com.baomidou</groupId>
|
||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||
<version>${mybatis-plus.version}</version>
|
||
</dependency>
|
||
<!-- MyBatis Plus 分页插件(3.5.16 拆分为独立模块) -->
|
||
<dependency>
|
||
<groupId>com.baomidou</groupId>
|
||
<artifactId>mybatis-plus-jsqlparser</artifactId>
|
||
<version>${mybatis-plus.version}</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring Security ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-security</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== JJWT (JSON Web Token) ===== -->
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-api</artifactId>
|
||
<version>${jjwt.version}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-impl</artifactId>
|
||
<version>${jjwt.version}</version>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>io.jsonwebtoken</groupId>
|
||
<artifactId>jjwt-jackson</artifactId>
|
||
<version>${jjwt.version}</version>
|
||
<scope>runtime</scope>
|
||
</dependency>
|
||
|
||
<!-- ===== SpringDoc OpenAPI(Swagger UI for Spring MVC) ===== -->
|
||
<dependency>
|
||
<groupId>org.springdoc</groupId>
|
||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Hutool 工具库 ===== -->
|
||
<dependency>
|
||
<groupId>cn.hutool</groupId>
|
||
<artifactId>hutool-all</artifactId>
|
||
<version>${hutool.version}</version>
|
||
</dependency>
|
||
|
||
<!-- ===== 钉钉 Stream SDK(WebSocket 长连接,无需公网 IP) ===== -->
|
||
<dependency>
|
||
<groupId>com.dingtalk.open</groupId>
|
||
<artifactId>dingtalk-stream</artifactId>
|
||
<version>1.3.12</version>
|
||
</dependency>
|
||
|
||
<!-- ===== 飞书 / Lark Open API SDK(WebSocket 长连接 + 事件分发) ===== -->
|
||
<dependency>
|
||
<groupId>com.larksuite.oapi</groupId>
|
||
<artifactId>oapi-sdk</artifactId>
|
||
<version>2.6.1</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Caffeine Cache(用于 skill runtime 缓存) ===== -->
|
||
<dependency>
|
||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||
<artifactId>caffeine</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== SnakeYAML(用于 SKILL.md frontmatter 解析) ===== -->
|
||
<dependency>
|
||
<groupId>org.yaml</groupId>
|
||
<artifactId>snakeyaml</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Lombok ===== -->
|
||
<dependency>
|
||
<groupId>org.projectlombok</groupId>
|
||
<artifactId>lombok</artifactId>
|
||
<optional>true</optional>
|
||
</dependency>
|
||
|
||
<!-- ===== QR Code Generation (ZXing) ===== -->
|
||
<dependency>
|
||
<groupId>com.google.zxing</groupId>
|
||
<artifactId>core</artifactId>
|
||
<version>3.5.3</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>com.google.zxing</groupId>
|
||
<artifactId>javase</artifactId>
|
||
<version>3.5.3</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Playwright (Browser Automation) ===== -->
|
||
<dependency>
|
||
<groupId>com.microsoft.playwright</groupId>
|
||
<artifactId>playwright</artifactId>
|
||
<version>1.52.0</version>
|
||
</dependency>
|
||
|
||
<!-- ===== JDA(Discord Bot Gateway WebSocket 长连接) ===== -->
|
||
<dependency>
|
||
<groupId>net.dv8tion</groupId>
|
||
<artifactId>JDA</artifactId>
|
||
<version>5.2.3</version>
|
||
<exclusions>
|
||
<!-- 排除 audio 相关依赖(MateClaw 不需要语音功能) -->
|
||
<exclusion>
|
||
<groupId>club.minnced</groupId>
|
||
<artifactId>opus-java</artifactId>
|
||
</exclusion>
|
||
</exclusions>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring WebSocket(Talk Mode) ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Slack SDK(Socket Mode + Web API) ===== -->
|
||
<dependency>
|
||
<groupId>com.slack.api</groupId>
|
||
<artifactId>slack-api-client</artifactId>
|
||
<version>1.44.2</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>com.slack.api</groupId>
|
||
<artifactId>bolt-socket-mode</artifactId>
|
||
<version>1.44.2</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.glassfish.tyrus.bundles</groupId>
|
||
<artifactId>tyrus-standalone-client</artifactId>
|
||
<version>2.2.0</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Apache POI (in-process .docx generation) ===== -->
|
||
<!--
|
||
Used by DocxRenderTool to render Markdown into a .docx in-JVM,
|
||
replacing the Node.js docx-js subprocess (3-5 min cold install).
|
||
-->
|
||
<dependency>
|
||
<groupId>org.apache.poi</groupId>
|
||
<artifactId>poi-ooxml</artifactId>
|
||
<version>5.4.1</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Apache Batik (SVG rasterization for docx image embedding) ===== -->
|
||
<!--
|
||
Used by MarkdownDocxRenderer to convert  image references
|
||
into PNG bytes that POI can embed via XWPFRun.addPicture(). Without this,
|
||
agents that produce architecture diagrams as inline SVG cannot get them
|
||
into the final .docx. Rasterization runs in-JVM (no rsvg-convert / cairo
|
||
dependency on the host).
|
||
-->
|
||
<dependency>
|
||
<groupId>org.apache.xmlgraphics</groupId>
|
||
<artifactId>batik-transcoder</artifactId>
|
||
<version>1.18</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.apache.xmlgraphics</groupId>
|
||
<artifactId>batik-codec</artifactId>
|
||
<version>1.18</version>
|
||
</dependency>
|
||
|
||
<!-- ===== jsoup (HTML cleanup for Wiki ingest, RFC-051 PR-1c) ===== -->
|
||
<!--
|
||
Used by WikiContentNormalizer to strip nav/footer/script/style/aside
|
||
and ad-class nodes from URL/HTML uploads before chunking. Small
|
||
(~430KB), no transitive deps, JVM-only — safe for the desktop bundle.
|
||
-->
|
||
<dependency>
|
||
<groupId>org.jsoup</groupId>
|
||
<artifactId>jsoup</artifactId>
|
||
<version>1.18.3</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Apache Tika (RFC-051 PR-?: Java-side last-resort extractor) ===== -->
|
||
<!--
|
||
Wired as the FINAL fallback in DocumentExtractTool's PDF/DOCX/XLSX/PPTX
|
||
chains, after every system command + Python + POI-based path has failed.
|
||
Used in production primarily by Windows users without Python or poppler
|
||
installed; otherwise idle.
|
||
|
||
Pinned to the precise format modules called out in RFC-051 §5.2 — we
|
||
deliberately avoid `tika-parsers-standard-package`, which pulls in mail,
|
||
audio, archive, RTF / ODT, scientific, etc. (~80MB). Current footprint:
|
||
tika-core (~700KB) + tika-parser-pdf-module (PDFBox ~5MB) +
|
||
tika-parser-microsoft-module (POI-scratchpad ~10MB) ≈ 16MB.
|
||
-->
|
||
<dependency>
|
||
<groupId>org.apache.tika</groupId>
|
||
<artifactId>tika-core</artifactId>
|
||
<version>3.0.0</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.apache.tika</groupId>
|
||
<artifactId>tika-parser-pdf-module</artifactId>
|
||
<version>3.0.0</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.apache.tika</groupId>
|
||
<artifactId>tika-parser-microsoft-module</artifactId>
|
||
<version>3.0.0</version>
|
||
</dependency>
|
||
|
||
<!-- ===== Database Migration (Flyway) ===== -->
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-core</artifactId>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>org.flywaydb</groupId>
|
||
<artifactId>flyway-mysql</artifactId>
|
||
</dependency>
|
||
|
||
<!-- ===== Spring Boot Test ===== -->
|
||
<dependency>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
<build>
|
||
<plugins>
|
||
<plugin>
|
||
<groupId>org.springframework.boot</groupId>
|
||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||
<configuration>
|
||
<excludes>
|
||
<exclude>
|
||
<groupId>org.projectlombok</groupId>
|
||
<artifactId>lombok</artifactId>
|
||
</exclude>
|
||
</excludes>
|
||
</configuration>
|
||
</plugin>
|
||
<!-- Populate ${net.bytebuddy:byte-buddy-agent:jar} from the test
|
||
classpath so maven-surefire-plugin can attach it statically
|
||
(Mockito inline mock maker on JDK 21+ can no longer self-attach). -->
|
||
<plugin>
|
||
<groupId>org.apache.maven.plugins</groupId>
|
||
<artifactId>maven-dependency-plugin</artifactId>
|
||
<executions>
|
||
<execution>
|
||
<id>resolve-test-classpath-properties</id>
|
||
<goals>
|
||
<goal>properties</goal>
|
||
</goals>
|
||
</execution>
|
||
</executions>
|
||
</plugin>
|
||
<plugin>
|
||
<groupId>org.apache.maven.plugins</groupId>
|
||
<artifactId>maven-surefire-plugin</artifactId>
|
||
<configuration>
|
||
<!-- Static agent attach for Mockito on JDK 21+. Without this, dynamic
|
||
agent loading raises ByteBuddyAgent.AttachmentTypeEvaluator errors
|
||
depending on the JVM's startup hardening, making tests pass on one
|
||
machine and fail on another. byte-buddy-agent rides in transitively
|
||
via mockito-core. -->
|
||
<argLine>-javaagent:${net.bytebuddy:byte-buddy-agent:jar}</argLine>
|
||
</configuration>
|
||
</plugin>
|
||
</plugins>
|
||
</build>
|
||
|
||
<!--
|
||
Dependency repositories, with US + CN mirrors listed side by side so builds
|
||
are reasonable on either continent. Maven tries repositories in the order
|
||
they are declared — the first one that resolves an artifact wins.
|
||
|
||
IDs are deliberately distinct from the super-POM's `central` id so that
|
||
mirror rules in settings.xml (if any) don't silently redirect them. Keep
|
||
the fastest-by-default first; switch order via a local ~/.m2/settings.xml
|
||
or pass `-Paliyun-first` when building from inside China.
|
||
-->
|
||
<repositories>
|
||
<!-- Primary: Maven Central direct — fast from US/EU backbones. -->
|
||
<repository>
|
||
<id>maven-central</id>
|
||
<name>Maven Central</name>
|
||
<url>https://repo.maven.apache.org/maven2</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
<!-- Fallback 1: Google Cloud's Maven Central mirror (global CDN edge). -->
|
||
<repository>
|
||
<id>google-maven-central</id>
|
||
<name>Google Maven Central Mirror</name>
|
||
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
<!-- Fallback 2: Aliyun public — fast from China, full Central mirror. -->
|
||
<repository>
|
||
<id>aliyun-public</id>
|
||
<name>Aliyun Public</name>
|
||
<url>https://maven.aliyun.com/repository/public</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
<!-- Spring milestones / snapshots — direct from Spring (US). -->
|
||
<repository>
|
||
<id>spring-milestones</id>
|
||
<name>Spring Milestones</name>
|
||
<url>https://repo.spring.io/milestone</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
<!-- Aliyun Spring mirror — fallback for CN builds. -->
|
||
<repository>
|
||
<id>aliyun-spring</id>
|
||
<name>Aliyun Spring Mirror</name>
|
||
<url>https://maven.aliyun.com/repository/spring</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
</repositories>
|
||
|
||
<!-- Plugin lookups follow the same multi-region fallback. -->
|
||
<pluginRepositories>
|
||
<pluginRepository>
|
||
<id>maven-central</id>
|
||
<name>Maven Central</name>
|
||
<url>https://repo.maven.apache.org/maven2</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</pluginRepository>
|
||
<pluginRepository>
|
||
<id>google-maven-central</id>
|
||
<name>Google Maven Central Mirror</name>
|
||
<url>https://maven-central.storage-download.googleapis.com/maven2</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</pluginRepository>
|
||
<pluginRepository>
|
||
<id>aliyun-public</id>
|
||
<name>Aliyun Public</name>
|
||
<url>https://maven.aliyun.com/repository/public</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</pluginRepository>
|
||
</pluginRepositories>
|
||
|
||
<!--
|
||
Profile: swap the primary repo order when building from China so Aliyun
|
||
is tried first. Activate with `mvn -Paliyun-first ...`.
|
||
-->
|
||
<profiles>
|
||
<profile>
|
||
<id>aliyun-first</id>
|
||
<repositories>
|
||
<repository>
|
||
<id>aliyun-public-first</id>
|
||
<url>https://maven.aliyun.com/repository/public</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
<repository>
|
||
<id>aliyun-spring-first</id>
|
||
<url>https://maven.aliyun.com/repository/spring</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</repository>
|
||
</repositories>
|
||
<pluginRepositories>
|
||
<pluginRepository>
|
||
<id>aliyun-public-first</id>
|
||
<url>https://maven.aliyun.com/repository/public</url>
|
||
<releases><enabled>true</enabled></releases>
|
||
<snapshots><enabled>false</enabled></snapshots>
|
||
</pluginRepository>
|
||
</pluginRepositories>
|
||
</profile>
|
||
</profiles>
|
||
</project>
|