tuqin
4 天以前 612172aacb1b05162270ff846441f1c6336d0321
fix(hrm): 缺勤扣款计薪基数改为基本+岗位+工龄+绩效

问题:薪酬核算按应出/实出天数扣缺勤时,封顶用的是「基本工资」。
而实际员工工资主体是岗位工资(如基本1950/岗位11383.60),
导致实出0天时只扣掉1950,岗位工资11383.60照发,实发仍有1万多。

修复:计薪基数 = 基本工资 + 岗位工资 + 工龄工资 + 绩效工资
(不含加班费/补贴/全勤奖,这些不随出勤折算),日工资与封顶都按该基数计算。

验证(真实数据 基本1950/岗位11383.60/应出30):
- 实出30 → 缺勤0,实发13000.00
- 实出0 → 缺勤13333.60(封顶),实发0.00
- 实出20 → 缺勤4444.53(10天x444.45),实发8684.32

另:补充 application-zyjc.yaml(此前未纳入版本库,丢失会导致启动报
ClassNotFoundException: RestTemplateBuilder)
已添加1个文件
已修改1个文件
248 ■■■■■ 文件已修改
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-server/src/main/resources/application-zyjc.yaml 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -314,9 +314,14 @@
                    .setScale(2, RoundingMode.HALF_UP);
        }
        // è®¡ç®—请假扣款
        // è®¡ç®—缺勤扣款(请假 + æ—·å·¥ï¼‰
        BigDecimal leaveDeduction = calculateAttendanceDeduction(employee, period, baseSalary, workDays, actualDays);
        // ç¼ºå‹¤æ‰£æ¬¾ï¼ˆè¯·å‡ + æ—·å·¥ï¼‰
        // è®¡è–ªåŸºæ•° = åŸºæœ¬å·¥èµ„ + å²—位工资 + å·¥é¾„工资 + ç»©æ•ˆå·¥èµ„(这些与出勤天数直接相关);
        // ä¸å«åŠ ç­è´¹/各项补贴/全勤奖(这些不随出勤天数折算)。
        // æ³¨æ„ï¼šä¸èƒ½ç”¨"基本工资"当基数——很多员工工资主体是岗位工资,否则实出 0 å¤©æ—¶åªæ‰£æŽ‰åŸºæœ¬å·¥èµ„,岗位工资照发。
        BigDecimal attendanceBaseSalary = baseSalary
                .add(postSalary).add(senioritySalary).add(performanceSalary);
        BigDecimal leaveDeduction = calculateAttendanceDeduction(
                employee, period, attendanceBaseSalary, workDays, actualDays);
        // è®¡ç®—个税扣除
        // åº”纳税所得额 = åº”发工资 - ç¤¾ä¿æ‰£é™¤ - å…¬ç§¯é‡‘扣除 - èµ·å¾ç‚¹(5000)
@@ -376,18 +381,18 @@
     *     <li>扣款总额封顶为基本工资,避免出现负工资。</li>
     * </ol>
     *
     * @param employee   å‘˜å·¥ä¿¡æ¯
     * @param period     æ ¸ç®—周期(如 2026-02)
     * @param baseSalary åŸºæœ¬å·¥èµ„
     * @param workDays   åº”出天数(排班累计,无排班时传 22)
     * @param actualDays å®žå‡ºå¤©æ•°ï¼ˆå–自考勤汇总;null è¡¨ç¤ºè¯¥æœˆæœªç”Ÿæˆæ±‡æ€»ï¼‰
     * @return ç¼ºå‹¤æ‰£æ¬¾é‡‘额
     * @param employee       å‘˜å·¥ä¿¡æ¯
     * @param period         æ ¸ç®—周期(如 2026-02)
     * @param attendanceBase è®¡è–ªåŸºæ•° = åŸºæœ¬ + å²—位 + å·¥é¾„ + ç»©æ•ˆï¼ˆä¸Žå‡ºå‹¤ç›´æŽ¥ç›¸å…³çš„固定工资)
     * @param workDays       åº”出天数(排班累计,无排班时传 22)
     * @param actualDays     å®žå‡ºå¤©æ•°ï¼ˆå–自考勤汇总;null è¡¨ç¤ºè¯¥æœˆæœªç”Ÿæˆæ±‡æ€»ï¼‰
     * @return ç¼ºå‹¤æ‰£æ¬¾é‡‘额(封顶为计薪基数)
     */
    private BigDecimal calculateAttendanceDeduction(HrmEmployeeDO employee, String period,
                                                    BigDecimal baseSalary, Integer workDays, Integer actualDays) {
                                                    BigDecimal attendanceBase, Integer workDays, Integer actualDays) {
        int shouldDays = (workDays != null && workDays > 0) ? workDays : 22;
        // æ—¥å·¥èµ„ = åŸºæœ¬å·¥èµ„ / åº”出天数(保留 4 ä½ï¼Œæœ€åŽç»Ÿä¸€ä¿ç•™ 2 ä½ï¼‰
        BigDecimal dailySalary = baseSalary.divide(new BigDecimal(shouldDays), 4, RoundingMode.HALF_UP);
        // æ—¥å·¥èµ„ = è®¡è–ªåŸºæ•° / åº”出天数(保留 4 ä½ï¼Œæœ€åŽç»Ÿä¸€ä¿ç•™ 2 ä½ï¼‰
        BigDecimal dailySalary = attendanceBase.divide(new BigDecimal(shouldDays), 4, RoundingMode.HALF_UP);
        BigDecimal totalDeduction = BigDecimal.ZERO;
        BigDecimal leaveDays = BigDecimal.ZERO;
@@ -428,7 +433,7 @@
        // 3. å°é¡¶ï¼šæ‰£æ¬¾ä¸è¶…过基本工资
        BigDecimal result = totalDeduction.setScale(2, RoundingMode.HALF_UP);
        BigDecimal cap = baseSalary.setScale(2, RoundingMode.HALF_UP);
        BigDecimal cap = attendanceBase.setScale(2, RoundingMode.HALF_UP);
        return result.compareTo(cap) > 0 ? cap : result;
    }
@@ -766,16 +771,22 @@
     * é‡ç®—「缺勤扣款」与「实发工资」
     *
     * <p>核算单 userId å­˜çš„æ˜¯å‘˜å·¥ID(hrm_employee.id)。按「应出天数 / å®žå‡ºå¤©æ•° + è¯·å‡å•」重算
     * ç¼ºå‹¤æ‰£æ¬¾ï¼ˆè¯·å‡æŒ‰é…ç½®æ¯”例扣、旷工按 100% æ‰£ã€å°é¡¶åŸºæœ¬å·¥èµ„),再重算实发工资(不可为负)。
     * æŸ¥ä¸åˆ°å‘˜å·¥æˆ–核算周期时,保留原缺勤扣款,只重算实发。
     * ç¼ºå‹¤æ‰£æ¬¾ï¼ˆè¯·å‡æŒ‰é…ç½®æ¯”例扣、旷工按 100% æ‰£ã€å°é¡¶è®¡è–ªåŸºæ•°ï¼‰ï¼Œå†é‡ç®—实发工资(不可为负)。
     *
     * <p>计薪基数 = åŸºæœ¬ + å²—位 + å·¥é¾„ + ç»©æ•ˆï¼ˆä¸Žå‡ºå‹¤ç›´æŽ¥ç›¸å…³çš„固定工资部分),
     * ä¸èƒ½ç”¨åŸºæœ¬å·¥èµ„单独封顶,否则工资主体为岗位工资的员工实出 0 å¤©æ—¶ä»ä¼šå‘放大部分工资。
     */
    private void recalcAttendanceDeduction(HrmSalaryCalculationDO calculation) {
        HrmEmployeeDO employee = calculation.getUserId() != null
                ? employeeMapper.selectById(calculation.getUserId()) : null;
        if (employee != null && calculation.getPeriod() != null) {
            BigDecimal attendanceBaseSalary = nvl(calculation.getBaseSalary())
                    .add(nvl(calculation.getPostSalary()))
                    .add(nvl(calculation.getSenioritySalary()))
                    .add(nvl(calculation.getPerformanceSalary()));
            BigDecimal deduction = calculateAttendanceDeduction(
                    employee, calculation.getPeriod(),
                    nvl(calculation.getBaseSalary()),
                    attendanceBaseSalary,
                    calculation.getWorkDays(),
                    calculation.getActualDays());
            calculation.setLeaveDeduction(deduction);
yudao-server/src/main/resources/application-zyjc.yaml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
server:
  port: 48080
--- #################### æ•°æ®åº“相关配置 ####################
spring:
  autoconfigure:
    # noinspection SpringBootApplicationYaml
    exclude:
      - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # é»˜è®¤ local çŽ¯å¢ƒï¼Œä¸å¼€å¯ Quartz çš„自动配置
      - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # ç¦ç”¨ AI æ¨¡å—çš„ Qdrant,手动创建
      - org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreAutoConfiguration # ç¦ç”¨ AI æ¨¡å—çš„ Redis,手动创建
      - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # ç¦ç”¨ AI æ¨¡å—çš„ Milvus,手动创建
      - org.dromara.trans.config.TransServiceConfig # TODO èŠ‹è‰¿ï¼šeasy-trans å…¼å®¹ Spring Boot 4 åŽç§»é™¤ï¼ˆTransServiceConfig å¼•用了已移除的 RestTemplateBuilder)
      # ç¦ç”¨æœªé…ç½® API Key çš„æ¨¡åž‹è‡ªåŠ¨é…ç½®ï¼ˆåªä¿ç•™é€šä¹‰åƒé—® Embedding çš„æ‰‹åŠ¨é…ç½®ï¼‰
      - org.springframework.ai.model.openai.autoconfigure.OpenAiChatAutoConfiguration
      - org.springframework.ai.model.openai.autoconfigure.OpenAiEmbeddingAutoConfiguration
      - org.springframework.ai.model.openai.autoconfigure.OpenAiImageAutoConfiguration
      - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioSpeechAutoConfiguration
      - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioTranscriptionAutoConfiguration
      - org.springframework.ai.model.openai.autoconfigure.OpenAiModerationAutoConfiguration
      - org.springframework.ai.model.deepseek.autoconfigure.DeepSeekChatAutoConfiguration
      - org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration
      - org.springframework.ai.model.google.genai.autoconfigure.chat.GoogleGenAiChatAutoConfiguration
      - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiEmbeddingConnectionAutoConfiguration
      - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiTextEmbeddingAutoConfiguration
      - org.springframework.ai.model.ollama.autoconfigure.OllamaApiAutoConfiguration
      - org.springframework.ai.model.ollama.autoconfigure.OllamaChatAutoConfiguration
      - org.springframework.ai.model.ollama.autoconfigure.OllamaEmbeddingAutoConfiguration
      - org.springframework.ai.model.stabilityai.autoconfigure.StabilityAiImageAutoConfiguration
  # æ•°æ®æºé…ç½®é¡¹
  datasource:
    druid: # Druid ã€ç›‘控】相关的全局配置
      web-stat-filter:
        enabled: true
      stat-view-servlet:
        enabled: true
        allow: # è®¾ç½®ç™½åå•,不填则允许所有访问
        url-pattern: /druid/*
        login-username: # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-password:
      filter:
        stat:
          enabled: true
          log-slow-sql: true # æ…¢ SQL è®°å½•
          slow-sql-millis: 100
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
    dynamic: # å¤šæ•°æ®æºé…ç½®
      druid: # Druid ã€è¿žæŽ¥æ± ã€‘相关的全局配置
        initial-size: 1 # åˆå§‹è¿žæŽ¥æ•°
        min-idle: 1 # æœ€å°è¿žæŽ¥æ± æ•°é‡
        max-active: 20 # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
        max-wait: 60000 # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´ï¼Œå•ä½ï¼šæ¯«ç§’ï¼ˆ1 åˆ†é’Ÿï¼‰
        time-between-eviction-runs-millis: 60000 # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒(1 åˆ†é’Ÿï¼‰
        min-evictable-idle-time-millis: 600000 # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位:毫秒(10 åˆ†é’Ÿï¼‰
        max-evictable-idle-time-millis: 1800000 # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位:毫秒(30 åˆ†é’Ÿï¼‰
        validation-query: SELECT 1 FROM DUAL # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: true # æ˜¯å¦å¼€å¯ PreparedStatement ç¼“å­˜
        max-pool-prepared-statement-per-connection-size: 20 # æ¯ä¸ªè¿žæŽ¥ç¼“存的 PreparedStatement æ•°é‡
      primary: master
      datasource:
        master:
          url: jdbc:mysql://172.17.0.1:10000/mom-zyjc?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X è¿žæŽ¥çš„示例
          username: root
          password: xd@123456..
  # Redis é…ç½®ã€‚Redisson é»˜è®¤çš„配置足够使用,一般不需要进行调优
  data:
    redis:
      host: 172.17.0.1 # åœ°å€
      port: 9999 # ç«¯å£ï¼ˆå®¿ä¸»æœº 9999 -> å®¹å™¨ 6379)
      database: 11 # æ•°æ®åº“索引(每客户一个;本机已分配 chdl=5、hm=7、cqny=8)
#      password: dev # å¯†ç ï¼Œå»ºè®®ç”Ÿäº§çŽ¯å¢ƒå¼€å¯
--- #################### å®šæ—¶ä»»åŠ¡ç›¸å…³é…ç½® ####################
# Quartz é…ç½®é¡¹ï¼Œå¯¹åº” QuartzProperties é…ç½®ç±»
spring:
  quartz:
    auto-startup: true # æœ¬åœ°å¼€å‘环境,尽量不要开启 Job
    scheduler-name: schedulerName # Scheduler åå­—。默认为 schedulerName
    job-store-type: jdbc # Job å­˜å‚¨å™¨ç±»åž‹ã€‚默认为 memory è¡¨ç¤ºå†…存,可选 jdbc ä½¿ç”¨æ•°æ®åº“。
    wait-for-jobs-to-complete-on-shutdown: true # åº”用关闭时,是否等待定时任务执行完成。默认为 false ï¼Œå»ºè®®è®¾ç½®ä¸º true
    properties: # æ·»åŠ  Quartz Scheduler é™„加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html æ–‡æ¡£
      org:
        quartz:
          # Scheduler ç›¸å…³é…ç½®
          scheduler:
            instanceName: schedulerName
            instanceId: AUTO # è‡ªåŠ¨ç”Ÿæˆ instance ID
          # JobStore ç›¸å…³é…ç½®
          jobStore:
            # JobStore å®žçŽ°ç±»ã€‚å¯è§åšå®¢ï¼šhttps://blog.csdn.net/weixin_42458219/article/details/122247162
            class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
            isClustered: true # æ˜¯é›†ç¾¤æ¨¡å¼
            clusterCheckinInterval: 15000 # é›†ç¾¤æ£€æŸ¥é¢‘率,单位:毫秒。默认为 15000,即 15 ç§’
            misfireThreshold: 60000 # misfire é˜€å€¼ï¼Œå•位:毫秒。
          # çº¿ç¨‹æ± ç›¸å…³é…ç½®
          threadPool:
            threadCount: 25 # çº¿ç¨‹æ± å¤§å°ã€‚默认为 10 ã€‚
            threadPriority: 5 # çº¿ç¨‹ä¼˜å…ˆçº§
            class: org.quartz.simpl.SimpleThreadPool # çº¿ç¨‹æ± ç±»åž‹
    jdbc: # ä½¿ç”¨ JDBC çš„ JobStore çš„æ—¶å€™ï¼ŒJDBC çš„配置
      initialize-schema: NEVER # æ˜¯å¦è‡ªåŠ¨ä½¿ç”¨ SQL åˆå§‹åŒ– Quartz è¡¨ç»“构。这里设置成 never ï¼Œæˆ‘们手动创建表结构。
--- #################### æœåŠ¡ä¿éšœç›¸å…³é…ç½® ####################
# Lock4j é…ç½®é¡¹
lock4j:
  acquire-timeout: 3000 # èŽ·å–åˆ†å¸ƒå¼é”è¶…æ—¶æ—¶é—´ï¼Œé»˜è®¤ä¸º 3000 æ¯«ç§’
  expire: 30000 # åˆ†å¸ƒå¼é”çš„超时时间,默认为 30000 æ¯«ç§’
--- #################### ç›‘控相关配置 ####################
# Actuator ç›‘控端点的配置项
management:
  endpoints:
    web:
      base-path: /actuator # Actuator æä¾›çš„ API æŽ¥å£çš„æ ¹ç›®å½•。默认为 /actuator
      exposure:
        include: '*' # éœ€è¦å¼€æ”¾çš„端点。默认值只打开 health å’Œ info ä¸¤ä¸ªç«¯ç‚¹ã€‚通过设置 * ï¼Œå¯ä»¥å¼€æ”¾æ‰€æœ‰ç«¯ç‚¹ã€‚
# Spring Boot Admin é…ç½®é¡¹
spring:
  boot:
    admin:
      # Spring Boot Admin Client å®¢æˆ·ç«¯çš„相关配置
      client:
        url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # è®¾ç½® Spring Boot Admin Server åœ°å€
        instance:
          service-host-type: IP # æ³¨å†Œå®žä¾‹æ—¶ï¼Œä¼˜å…ˆä½¿ç”¨ IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
        username: admin
        password: admin
      # Spring Boot Admin Server æœåŠ¡ç«¯çš„ç›¸å…³é…ç½®
      context-path: /admin # é…ç½® Spring
      # å…è®¸åµŒå…¥ iframe çš„域名(支持通配符),实际部署时,可以改为 "'self' [你的公网域名]"
      frame-ancestors: "'self' localhost localhost:48080 127.0.0.1 127.0.0.1:48080"
# æ—¥å¿—文件配置
logging:
  file:
    name: logs/${spring.application.name}.log # æ—¥å¿—文件名,相对于项目根目录
  level:
    # é…ç½®è‡ªå·±å†™çš„ MyBatis Mapper æ‰“印日志
    cn.iocoder.yudao.module.bpm.dal.mysql: debug
    cn.iocoder.yudao.module.infra.dal.mysql: debug
    cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # é…ç½® ApiErrorLogMapper çš„æ—¥å¿—级别为 info,避免和 GlobalExceptionHandler é‡å¤æ‰“印
    cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # é…ç½® JobLogMapper çš„æ—¥å¿—级别为 info
    cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper: INFO # é…ç½® FileConfigMapper çš„æ—¥å¿—级别为 info
    cn.iocoder.yudao.module.system.dal.mysql: debug
    cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # é…ç½® SmsChannelMapper çš„æ—¥å¿—级别为 info
    cn.iocoder.yudao.module.member.dal.mysql: debug
    cn.iocoder.yudao.module.crm.dal.mysql: debug
    cn.iocoder.yudao.module.erp.dal.mysql: debug
    cn.iocoder.yudao.module.mes.dal.mysql: debug
    cn.iocoder.yudao.module.ai.dal.mysql: debug
    cn.iocoder.yudao.module.im.dal.mysql: debug
    org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO èŠ‹è‰¿ï¼šå…ˆç¦ç”¨ï¼ŒSpring Boot 3.X å­˜åœ¨éƒ¨åˆ†é”™è¯¯çš„ WARN æç¤º
debug: false
yudao:
  ai:
    vector-store:
      type: milvus # å‘量库类型:milvus
      milvus:
        initialize-schema: true
        database-name: test
        collection-name: knowledge_segment_zyjc
        host: 36.213.90.123
        port: 19530
--- #################### è¶…级管理员相关配置 ####################
# è¶…级管理员配置项,设置当前项目所有自定义的配置
yudao:
  captcha:
    enable: false # æœ¬åœ°çŽ¯å¢ƒï¼Œæš‚æ—¶å…³é—­å›¾ç‰‡éªŒè¯ç ï¼Œæ–¹ä¾¿ç™»å½•ç­‰æŽ¥å£çš„æµ‹è¯•ï¼›
  security:
    mock-enable: true
  access-log: # è®¿é—®æ—¥å¿—的配置项
    enable: false
  demo: false # å…³é—­æ¼”示模式
  storage: # æ–‡ä»¶ä¸Šä¼ é…ç½®
    path: /data/javaWork/mom/file # æ–‡ä»¶å­˜å‚¨æ ¹ç›®å½•(必须与 publish.sh çš„ -v æŒ‚载路径完全一致,否则重建容器后上传的文件会丢失)
    url-prefix: /admin-api/system/storage-blob # URL路径前缀
    domain: http://36.213.150.237:9024 # åŸŸåå‰ç¼€ï¼ˆæŒ‰å®žé™…域名配置),前端配置好像不太对现在是直连后端,所有要后端端口
    expired: 120 # token过期时间(分钟)
    use-limit: 10 # token使用次数上限
    jwt-secret: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG # JWT密钥
    compress: true # æ˜¯å¦åŽ‹ç¼©å›¾ç‰‡
    need-compress-size: 10MB # è§¦å‘压缩的文件大小阈值
    compress-quality: 0.5 # åŽ‹ç¼©è´¨é‡(0.0-1.0)
  database-backup: # æ•°æ®åº“备份配置
    host: 172.17.0.1 # å¤‡ä»½ç›®æ ‡ MySQL ä¸»æœºï¼Œç•™ç©ºè‡ªåŠ¨ä»Žæ•°æ®æº JDBC URL è§£æž
    port: 10000 # å¤‡ä»½ç›®æ ‡ MySQL ç«¯å£ï¼Œç•™ç©ºè‡ªåŠ¨ä»Žæ•°æ®æº JDBC URL è§£æž
    database: mom-zyjc # å¤‡ä»½ç›®æ ‡æ•°æ®åº“,留空自动从数据源 JDBC URL è§£æž
    username: root # å¤‡ä»½è´¦å·ï¼Œç•™ç©ºä½¿ç”¨æ•°æ®æºè´¦å·
    password: 'xd@123456..' # å¤‡ä»½å¯†ç ï¼Œç•™ç©ºä½¿ç”¨æ•°æ®æºå¯†ç 
    command: # mysqldump å‘½ä»¤ï¼Œç•™ç©ºè‡ªåŠ¨æ£€æµ‹éƒ¨ç½²çŽ¯å¢ƒï¼ˆæœ¬æœº mysqldump æˆ– Docker MySQL å®¹å™¨ï¼‰ï¼›å¯æ‰‹åŠ¨æŒ‡å®šï¼Œå¦‚ï¼šdocker exec mysql8 mysqldump