wangyunpeng 3 тижнів тому
батько
коміт
70bc49b258

+ 14 - 0
core/src/main/java/com/tzld/supply/api/fish/FishApiService.java

@@ -0,0 +1,14 @@
+package com.tzld.supply.api.fish;
+
+import java.io.File;
+
+public interface FishApiService {
+
+    void importTTSModels(String speakerId);
+
+    String tts(String speakerId, String text, String bizId);
+
+    String ttsByAudio(byte[] referenceAudio, String referenceText, String text, String bizId);
+
+    void train(File audioFile, String title, String createAccount);
+}

+ 340 - 0
core/src/main/java/com/tzld/supply/api/fish/FishApiServiceImpl.java

@@ -0,0 +1,340 @@
+package com.tzld.supply.api.fish;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.stuuudy.commons.external.filestorage.enums.EnumPublicBuckets;
+import com.tzld.supply.common.enums.ExceptionEnum;
+import com.tzld.supply.common.exception.CommonException;
+import com.tzld.supply.dao.mapper.supply.spider.AiModelTtsMapper;
+import com.tzld.supply.dao.mapper.supply.spider.FishApiRecordMapper;
+import com.tzld.supply.model.po.supply.spider.AiModelTts;
+import com.tzld.supply.model.po.supply.spider.AiModelTtsExample;
+import com.tzld.supply.model.po.supply.spider.FishApiRecord;
+import com.tzld.supply.model.po.supply.spider.FishApiRecordExample;
+import com.tzld.supply.util.*;
+import com.tzld.supply.util.http.HttpClientUtils;
+import com.tzld.supply.util.http.HttpResponseContent;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import lombok.extern.slf4j.Slf4j;
+import org.msgpack.jackson.dataformat.MessagePackFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.*;
+
+@Service
+@Slf4j
+public class FishApiServiceImpl implements FishApiService {
+
+    @Autowired
+    AiModelTtsMapper aiModelTtsMapper;
+    @Autowired
+    FishApiRecordMapper fishApiRecordMapper;
+
+    private static final String apiKey = "0891f3f93a2640428f9988e267aa57e1";
+
+    @Override
+    public void importTTSModels(String speakerId) {
+        if (StringUtils.hasText(speakerId)) {
+            importTTSModelsBySpeakerId(speakerId);
+        } else {
+            importTTSModelsBySelf();
+        }
+    }
+
+    private void importTTSModelsBySpeakerId(String speakerId) {
+        String apiUrl = "https://api.fish.audio/model/" + speakerId;
+        Map<String, String> headerMap = buildCommonHeaderMap();
+        HttpResponseContent hrc = HttpClientUtils.get(apiUrl, headerMap);
+        if (Objects.isNull(hrc)) {
+            log.error("importTTSModelsBySpeakerId hrc is null");
+            return;
+        }
+        if (!hrc.isSuccessful()) {
+            log.error("importTTSModelsBySpeakerId httpCode:{}, response:{}", hrc.getStatusCode(), hrc.getBodyContent());
+            return;
+        }
+        String responseBody = hrc.getBodyContent();
+        log.info("importTTSModelsBySpeakerId,speakerId:{},response:\n{}", speakerId, responseBody);
+        FishTTSModel fishTTSModel = JSON.parseObject(responseBody, FishTTSModel.class);
+        if (Objects.nonNull(fishTTSModel)) {
+            insertTTSModelToDB(fishTTSModel);
+        }
+    }
+
+    private void importTTSModelsBySelf() {
+        String apiUrl = "https://api.fish.audio/model?page_size=1000&page_number=1&self=true";
+        Map<String, String> headerMap = buildCommonHeaderMap();
+        HttpResponseContent hrc = HttpClientUtils.get(apiUrl, headerMap);
+        if (Objects.isNull(hrc)) {
+            log.error("importTTSModelsBySelf hrc is null");
+            return;
+        }
+        if (!hrc.isSuccessful()) {
+            log.error("importTTSModelsBySelf httpCode:{}, response:{}", hrc.getStatusCode(), hrc.getBodyContent());
+            return;
+        }
+        String responseBody = hrc.getBodyContent();
+        log.info("importTTSModelsBySelf,response:\n{}", responseBody);
+        FishTTSListModel fishTTSListModel = JSON.parseObject(responseBody, FishTTSListModel.class);
+        if (Objects.nonNull(fishTTSListModel) && CollectionUtil.isNotEmpty(fishTTSListModel.getItems())) {
+            for (FishTTSModel fishTTSModel : fishTTSListModel.getItems()) {
+                insertTTSModelToDB(fishTTSModel);
+            }
+        }
+    }
+
+    private void insertTTSModelToDB(FishTTSModel fishTTSModel) {
+        String speakerId = fishTTSModel.get_id();
+        AiModelTts tts = getAiModelTtsBySpeakerId(speakerId);
+        if (Objects.nonNull(tts)) {
+            log.info("insertTTSModelToDB,speakerId id exist,{}", speakerId);
+            return;
+        }
+        tts = new AiModelTts();
+        tts.setId("tts_" + DistributedIdGenerator.generate());
+        tts.setModel("fish");
+        tts.setTtsId(speakerId);
+        tts.setSpeaker(fishTTSModel.getTitle());
+        tts.setSpeakerId(speakerId);
+        tts.setReferAccountId("20250227195837915481438");
+        tts.setType(1);
+        tts.setCreateAccount(StringUtils.hasText(fishTTSModel.getCreateAccount()) ? fishTTSModel.getCreateAccount() : "liuzhiheng");
+        tts.setCreateTimestamp(System.currentTimeMillis());
+        String sourceType = "public";
+        if ("private".equals(sourceType)) {
+            sourceType = "personal";
+        }
+        tts.setSourceType(sourceType);
+
+        List<FishTTSModelSample> samples = fishTTSModel.getSamples();
+        if (CollectionUtil.isNotEmpty(samples)) {
+            String sampleAudioUrl = samples.get(0).getAudio();
+            if (!sampleAudioUrl.startsWith("http")) {
+                sampleAudioUrl = "https://platform.r2.fish.audio/" + sampleAudioUrl;
+            }
+            // 上传音频
+            String ossKey = "audio/fish/robot/" + speakerId + ".mp3";
+            HttpResponseContent hrc = HttpClientUtils.get(sampleAudioUrl);
+            InputStream inputStream = new ByteArrayInputStream(hrc.getContentBytes());
+            AliOssFileTool.saveInPublic(EnumPublicBuckets.PUBBUCKET.getBucketName(), ossKey, inputStream, "audio/mp3");
+
+            tts.setAudioUrl(CdnUtil.getOssHttpUrl(ossKey));
+        }
+        aiModelTtsMapper.insertSelective(tts);
+    }
+
+    private AiModelTts getAiModelTtsBySpeakerId(String speakerId) {
+        AiModelTtsExample example = new AiModelTtsExample();
+        example.createCriteria().andSpeakerIdEqualTo(speakerId);
+        List<AiModelTts> list = aiModelTtsMapper.selectByExample(example);
+        if (CollectionUtil.isNotEmpty(list)) {
+            return list.get(0);
+        }
+        return null;
+    }
+
+    @Getter
+    @Setter
+    @Accessors(chain = true)
+    public static class FishTTSListModel {
+        private Integer total;
+        private List<FishTTSModel> items;
+    }
+
+    @Getter
+    @Setter
+    @Accessors(chain = true)
+    public static class FishTTSModel {
+        private String _id;
+        private String title;
+        private String visibility;
+        private List<FishTTSModelSample> samples;
+        private String createAccount;
+    }
+
+    @Getter
+    @Setter
+    @Accessors(chain = true)
+    public static class FishTTSModelSample {
+        private String audio;
+    }
+
+    private Map<String, String> buildCommonHeaderMap() {
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("Authorization", "Bearer " + apiKey);
+        headerMap.put("Content-Type", "application/json");
+        return headerMap;
+    }
+
+    @Override
+    public String tts(String speakerId, String text, String bizId) {
+        // 先从缓存中拿
+        String textMd5 = Md5Util.encoderByMd5(text);
+        String ttsUrl = getCacheTtsUrl(speakerId, textMd5);
+        if (StringUtils.hasText(ttsUrl)) {
+            log.info("fish tts hit cache,{},{}", bizId, ttsUrl);
+            return ttsUrl;
+        }
+        String apiUrl = "https://api.fish.audio/v1/tts";
+        Map<String, String> headerMap = buildCommonHeaderMap();
+        Map<String, String> paramMap = new HashMap<>();
+        paramMap.put("reference_id", speakerId);
+        paramMap.put("text", text);
+
+        boolean enableRetry = false;
+        // retry 3 times
+        int retryTimes = 0;
+        do {
+            HttpResponseContent hrc = HttpClientUtils.postDataAddHeader(apiUrl, JSON.toJSONString(paramMap), headerMap,
+                    10000, 1800000);
+            if (Objects.isNull(hrc)) {
+                log.error("fishTTS hrc is null,bizId:{}", bizId);
+                enableRetry = true;
+            }
+            if (!hrc.isSuccessful()) {
+                log.error("fishTTS,bizId:{}, httpCode:{}, response:{}", bizId, hrc.getStatusCode(), hrc.getBodyContent());
+                if (hrc.getStatusCode() == 402 || hrc.getStatusCode() >= 500) {
+                    enableRetry = true;
+                }
+            }
+            byte[] contentBytes = hrc.getContentBytes();
+            if (contentBytes.length < 10) {
+                enableRetry = true;
+            }
+            // 上传音频
+            String ossKey = "audio/fish/tts/" + RandomUtil.getRandomUUIDStr() + ".mp3";
+            InputStream inputStream = new ByteArrayInputStream(contentBytes);
+            AliOssFileTool.saveInPublic(EnumPublicBuckets.PUBBUCKET.getBucketName(), ossKey, inputStream, "audio/mp3");
+            ttsUrl = CdnUtil.getOssHttpUrl(ossKey);
+            // 保存记录
+            saveTTSCache(speakerId, textMd5, text, bizId, ttsUrl);
+            retryTimes++;
+        } while (enableRetry && retryTimes < 3);
+        return ttsUrl;
+    }
+
+    private void saveTTSCache(String speakerId, String textMd5, String text, String bizId, String ttsUrl) {
+        try {
+            FishApiRecord record = new FishApiRecord();
+            record.setSpeakerId(speakerId);
+            record.setBizId(bizId);
+            record.setTtsUrl(ttsUrl);
+            record.setTextMd5(textMd5);
+            record.setTextRaw(text);
+            record.setCreateTimestamp(System.currentTimeMillis());
+            fishApiRecordMapper.insertSelective(record);
+        } catch (Exception e) {
+            log.error("saveTTSCache error", e);
+        }
+    }
+
+    private String getCacheTtsUrl(String speakerId, String textMd5) {
+        FishApiRecordExample example = new FishApiRecordExample();
+        example.createCriteria().andSpeakerIdEqualTo(speakerId).andTextMd5EqualTo(textMd5);
+        example.setOrderByClause("id desc");
+        List<FishApiRecord> list = fishApiRecordMapper.selectByExample(example);
+        if (CollectionUtil.isNotEmpty(list)) {
+            return list.get(0).getTtsUrl();
+        }
+        return null;
+    }
+
+    @Override
+    public String ttsByAudio(byte[] referenceAudio, String referenceText, String text, String bizId) {
+        String apiUrl = "https://api.fish.audio/v1/tts";
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("Authorization", "Bearer " + apiKey);
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("text", text);
+
+        List<Map<String, Object>> references = new ArrayList<>();
+        Map<String, Object> reference = new HashMap<>();
+        reference.put("audio", referenceAudio);
+        reference.put("text", referenceText);
+        references.add(reference);
+
+        paramMap.put("references", references);
+
+        ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
+
+        byte[] msgpackBytes;
+        try {
+            msgpackBytes = objectMapper.writeValueAsBytes(paramMap);
+        } catch (JsonProcessingException e) {
+            log.error("fish ttsByAudio 序列化参数异常,bizId:{}", bizId, e);
+            return null;
+        }
+
+        // retry 3 times
+        int retryTimes = 0;
+        boolean enableRetry = false;
+        HttpResponseContent hrc = null;
+        String ttsUrl = null;
+        do {
+            retryTimes++;
+            hrc = HttpClientUtils.postMsgpackDataAddHeader(apiUrl, msgpackBytes, headerMap,
+                    10000, 1800000);
+            if (Objects.isNull(hrc)) {
+                log.error("fish ttsByAudio hrc is null,bizId:{}", bizId);
+                enableRetry = true;
+                continue;
+            }
+            if (!hrc.isSuccessful()) {
+                log.error("fish ttsByAudio bizId:{}, httpCode:{}, response:{}", bizId, hrc.getStatusCode(), hrc.getBodyContent());
+                enableRetry = false;
+                if (hrc.getStatusCode() == 402 || hrc.getStatusCode() >= 500) {
+                    enableRetry = true;
+                    continue;
+                }
+            }
+            // 上传音频
+            String ossKey = "audio/fish/tts/" + RandomUtil.getRandomUUIDStr() + ".mp3";
+            InputStream inputStream = new ByteArrayInputStream(hrc.getContentBytes());
+            AliOssFileTool.saveInPublic(EnumPublicBuckets.PUBBUCKET.getBucketName(), ossKey, inputStream, "audio/mp3");
+            ttsUrl = CdnUtil.getOssHttpUrl(ossKey);
+        } while (enableRetry && retryTimes < 3);
+        return ttsUrl;
+    }
+
+    @Override
+    public void train(File audioFile, String title, String createAccount) {
+        String apiUrl = "https://api.fish.audio/model";
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("Authorization", "Bearer " + apiKey);
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("voices", audioFile);
+        paramMap.put("type", "tts");
+        paramMap.put("title", title);
+        paramMap.put("visibility", "private");
+        paramMap.put("train_mode", "fast");
+        paramMap.put("enhance_audio_quality", true);
+        paramMap.put("generate_sample", true);
+
+        HttpResponseContent hrc = HttpClientUtils.postMultipart(apiUrl, paramMap, 3000, 600000, headerMap);
+        if (Objects.isNull(hrc)) {
+            throw new CommonException(ExceptionEnum.SYSTEM_ERROR.getCode(), "fish音色训练接口请求超时");
+        }
+        String responseBody = hrc.getBodyContent();
+        log.info("fish train,title:{},httpCode:{},response:{}", title, hrc.getStatusCode(), responseBody);
+        if (hrc.getStatusCode() == 201) {
+            FishTTSModel fishTTSModel = JSON.parseObject(responseBody, FishTTSModel.class);
+            if (Objects.nonNull(fishTTSModel)) {
+                fishTTSModel.setCreateAccount(createAccount);
+                insertTTSModelToDB(fishTTSModel);
+            }
+        } else {
+            throw new CommonException(ExceptionEnum.SYSTEM_ERROR.getCode(),
+                    "fish音色训练接口返回失败,httpCode:" + hrc.getStatusCode() + "response:" + responseBody);
+        }
+    }
+
+}

+ 96 - 0
core/src/main/java/com/tzld/supply/dao/mapper/supply/spider/AiModelTtsMapper.java

@@ -0,0 +1,96 @@
+package com.tzld.supply.dao.mapper.supply.spider;
+
+import com.tzld.supply.model.po.supply.spider.AiModelTts;
+import com.tzld.supply.model.po.supply.spider.AiModelTtsExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface AiModelTtsMapper {
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    long countByExample(AiModelTtsExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int deleteByExample(AiModelTtsExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int deleteByPrimaryKey(String id);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int insert(AiModelTts record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int insertSelective(AiModelTts record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    List<AiModelTts> selectByExample(AiModelTtsExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    AiModelTts selectByPrimaryKey(String id);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByExampleSelective(@Param("record") AiModelTts record, @Param("example") AiModelTtsExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByExample(@Param("record") AiModelTts record, @Param("example") AiModelTtsExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByPrimaryKeySelective(AiModelTts record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByPrimaryKey(AiModelTts record);
+}

+ 120 - 0
core/src/main/java/com/tzld/supply/dao/mapper/supply/spider/FishApiRecordMapper.java

@@ -0,0 +1,120 @@
+package com.tzld.supply.dao.mapper.supply.spider;
+
+import com.tzld.supply.model.po.supply.spider.FishApiRecord;
+import com.tzld.supply.model.po.supply.spider.FishApiRecordExample;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+
+public interface FishApiRecordMapper {
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    long countByExample(FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int deleteByExample(FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int deleteByPrimaryKey(Long id);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int insert(FishApiRecord record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int insertSelective(FishApiRecord record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    List<FishApiRecord> selectByExampleWithBLOBs(FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    List<FishApiRecord> selectByExample(FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    FishApiRecord selectByPrimaryKey(Long id);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByExampleSelective(@Param("record") FishApiRecord record, @Param("example") FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByExampleWithBLOBs(@Param("record") FishApiRecord record, @Param("example") FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByExample(@Param("record") FishApiRecord record, @Param("example") FishApiRecordExample example);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByPrimaryKeySelective(FishApiRecord record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByPrimaryKeyWithBLOBs(FishApiRecord record);
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    int updateByPrimaryKey(FishApiRecord record);
+}

+ 528 - 0
core/src/main/java/com/tzld/supply/model/po/supply/spider/AiModelTts.java

@@ -0,0 +1,528 @@
+package com.tzld.supply.model.po.supply.spider;
+
+/**
+ *
+ * This class was generated by MyBatis Generator.
+ * This class corresponds to the database table ai_model_tts
+ */
+public class AiModelTts {
+    /**
+     * Database Column Remarks:
+     *   ID
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String id;
+
+    /**
+     * Database Column Remarks:
+     *   模型(30-guiji,31-musicfy,32-jichuang)
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.model
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String model;
+
+    /**
+     * Database Column Remarks:
+     *   ttsID
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.tts_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String ttsId;
+
+    /**
+     * Database Column Remarks:
+     *   名称
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.speaker
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String speaker;
+
+    /**
+     * Database Column Remarks:
+     *   数字人ID
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String speakerId;
+
+    /**
+     * Database Column Remarks:
+     *   label
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.speaker_label
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String speakerLabel;
+
+    /**
+     * Database Column Remarks:
+     *   音频
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.audio_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String audioUrl;
+
+    /**
+     * Database Column Remarks:
+     *   关联账号ID
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.refer_account_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String referAccountId;
+
+    /**
+     * Database Column Remarks:
+     *   使用类型(1-文字转语音 2-音频音色替换)
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private Integer type;
+
+    /**
+     * Database Column Remarks:
+     *   创建人
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.create_account
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String createAccount;
+
+    /**
+     * Database Column Remarks:
+     *   创建时间戳
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private Long createTimestamp;
+
+    /**
+     * Database Column Remarks:
+     *   类型:personal-个人;public-平台
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.source_type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String sourceType;
+
+    /**
+     * Database Column Remarks:
+     *   性别
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.sex
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String sex;
+
+    /**
+     * Database Column Remarks:
+     *   封面url
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column ai_model_tts.cover_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String coverUrl;
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.id
+     *
+     * @return the value of ai_model_tts.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.id
+     *
+     * @param id the value for ai_model_tts.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.model
+     *
+     * @return the value of ai_model_tts.model
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getModel() {
+        return model;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.model
+     *
+     * @param model the value for ai_model_tts.model
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.tts_id
+     *
+     * @return the value of ai_model_tts.tts_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getTtsId() {
+        return ttsId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.tts_id
+     *
+     * @param ttsId the value for ai_model_tts.tts_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setTtsId(String ttsId) {
+        this.ttsId = ttsId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.speaker
+     *
+     * @return the value of ai_model_tts.speaker
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSpeaker() {
+        return speaker;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.speaker
+     *
+     * @param speaker the value for ai_model_tts.speaker
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSpeaker(String speaker) {
+        this.speaker = speaker;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.speaker_id
+     *
+     * @return the value of ai_model_tts.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSpeakerId() {
+        return speakerId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.speaker_id
+     *
+     * @param speakerId the value for ai_model_tts.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSpeakerId(String speakerId) {
+        this.speakerId = speakerId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.speaker_label
+     *
+     * @return the value of ai_model_tts.speaker_label
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSpeakerLabel() {
+        return speakerLabel;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.speaker_label
+     *
+     * @param speakerLabel the value for ai_model_tts.speaker_label
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSpeakerLabel(String speakerLabel) {
+        this.speakerLabel = speakerLabel;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.audio_url
+     *
+     * @return the value of ai_model_tts.audio_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getAudioUrl() {
+        return audioUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.audio_url
+     *
+     * @param audioUrl the value for ai_model_tts.audio_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setAudioUrl(String audioUrl) {
+        this.audioUrl = audioUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.refer_account_id
+     *
+     * @return the value of ai_model_tts.refer_account_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getReferAccountId() {
+        return referAccountId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.refer_account_id
+     *
+     * @param referAccountId the value for ai_model_tts.refer_account_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setReferAccountId(String referAccountId) {
+        this.referAccountId = referAccountId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.type
+     *
+     * @return the value of ai_model_tts.type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Integer getType() {
+        return type;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.type
+     *
+     * @param type the value for ai_model_tts.type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.create_account
+     *
+     * @return the value of ai_model_tts.create_account
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getCreateAccount() {
+        return createAccount;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.create_account
+     *
+     * @param createAccount the value for ai_model_tts.create_account
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setCreateAccount(String createAccount) {
+        this.createAccount = createAccount;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.create_timestamp
+     *
+     * @return the value of ai_model_tts.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Long getCreateTimestamp() {
+        return createTimestamp;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.create_timestamp
+     *
+     * @param createTimestamp the value for ai_model_tts.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setCreateTimestamp(Long createTimestamp) {
+        this.createTimestamp = createTimestamp;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.source_type
+     *
+     * @return the value of ai_model_tts.source_type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSourceType() {
+        return sourceType;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.source_type
+     *
+     * @param sourceType the value for ai_model_tts.source_type
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSourceType(String sourceType) {
+        this.sourceType = sourceType;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.sex
+     *
+     * @return the value of ai_model_tts.sex
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSex() {
+        return sex;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.sex
+     *
+     * @param sex the value for ai_model_tts.sex
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSex(String sex) {
+        this.sex = sex;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column ai_model_tts.cover_url
+     *
+     * @return the value of ai_model_tts.cover_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getCoverUrl() {
+        return coverUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column ai_model_tts.cover_url
+     *
+     * @param coverUrl the value for ai_model_tts.cover_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setCoverUrl(String coverUrl) {
+        this.coverUrl = coverUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", model=").append(model);
+        sb.append(", ttsId=").append(ttsId);
+        sb.append(", speaker=").append(speaker);
+        sb.append(", speakerId=").append(speakerId);
+        sb.append(", speakerLabel=").append(speakerLabel);
+        sb.append(", audioUrl=").append(audioUrl);
+        sb.append(", referAccountId=").append(referAccountId);
+        sb.append(", type=").append(type);
+        sb.append(", createAccount=").append(createAccount);
+        sb.append(", createTimestamp=").append(createTimestamp);
+        sb.append(", sourceType=").append(sourceType);
+        sb.append(", sex=").append(sex);
+        sb.append(", coverUrl=").append(coverUrl);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 1262 - 0
core/src/main/java/com/tzld/supply/model/po/supply/spider/AiModelTtsExample.java

@@ -0,0 +1,1262 @@
+package com.tzld.supply.model.po.supply.spider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AiModelTtsExample {
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected String orderByClause;
+
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected boolean distinct;
+
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected List<Criteria> oredCriteria;
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public AiModelTtsExample() {
+        oredCriteria = new ArrayList<Criteria>();
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<Criterion>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(String value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(String value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(String value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(String value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(String value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(String value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLike(String value) {
+            addCriterion("id like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotLike(String value) {
+            addCriterion("id not like", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<String> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<String> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(String value1, String value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(String value1, String value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelIsNull() {
+            addCriterion("model is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelIsNotNull() {
+            addCriterion("model is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelEqualTo(String value) {
+            addCriterion("model =", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelNotEqualTo(String value) {
+            addCriterion("model <>", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelGreaterThan(String value) {
+            addCriterion("model >", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelGreaterThanOrEqualTo(String value) {
+            addCriterion("model >=", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelLessThan(String value) {
+            addCriterion("model <", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelLessThanOrEqualTo(String value) {
+            addCriterion("model <=", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelLike(String value) {
+            addCriterion("model like", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelNotLike(String value) {
+            addCriterion("model not like", value, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelIn(List<String> values) {
+            addCriterion("model in", values, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelNotIn(List<String> values) {
+            addCriterion("model not in", values, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelBetween(String value1, String value2) {
+            addCriterion("model between", value1, value2, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andModelNotBetween(String value1, String value2) {
+            addCriterion("model not between", value1, value2, "model");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdIsNull() {
+            addCriterion("tts_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdIsNotNull() {
+            addCriterion("tts_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdEqualTo(String value) {
+            addCriterion("tts_id =", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdNotEqualTo(String value) {
+            addCriterion("tts_id <>", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdGreaterThan(String value) {
+            addCriterion("tts_id >", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdGreaterThanOrEqualTo(String value) {
+            addCriterion("tts_id >=", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdLessThan(String value) {
+            addCriterion("tts_id <", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdLessThanOrEqualTo(String value) {
+            addCriterion("tts_id <=", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdLike(String value) {
+            addCriterion("tts_id like", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdNotLike(String value) {
+            addCriterion("tts_id not like", value, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdIn(List<String> values) {
+            addCriterion("tts_id in", values, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdNotIn(List<String> values) {
+            addCriterion("tts_id not in", values, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdBetween(String value1, String value2) {
+            addCriterion("tts_id between", value1, value2, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsIdNotBetween(String value1, String value2) {
+            addCriterion("tts_id not between", value1, value2, "ttsId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIsNull() {
+            addCriterion("speaker is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIsNotNull() {
+            addCriterion("speaker is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerEqualTo(String value) {
+            addCriterion("speaker =", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerNotEqualTo(String value) {
+            addCriterion("speaker <>", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerGreaterThan(String value) {
+            addCriterion("speaker >", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerGreaterThanOrEqualTo(String value) {
+            addCriterion("speaker >=", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLessThan(String value) {
+            addCriterion("speaker <", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLessThanOrEqualTo(String value) {
+            addCriterion("speaker <=", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLike(String value) {
+            addCriterion("speaker like", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerNotLike(String value) {
+            addCriterion("speaker not like", value, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIn(List<String> values) {
+            addCriterion("speaker in", values, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerNotIn(List<String> values) {
+            addCriterion("speaker not in", values, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerBetween(String value1, String value2) {
+            addCriterion("speaker between", value1, value2, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerNotBetween(String value1, String value2) {
+            addCriterion("speaker not between", value1, value2, "speaker");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIsNull() {
+            addCriterion("speaker_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIsNotNull() {
+            addCriterion("speaker_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdEqualTo(String value) {
+            addCriterion("speaker_id =", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotEqualTo(String value) {
+            addCriterion("speaker_id <>", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdGreaterThan(String value) {
+            addCriterion("speaker_id >", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdGreaterThanOrEqualTo(String value) {
+            addCriterion("speaker_id >=", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLessThan(String value) {
+            addCriterion("speaker_id <", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLessThanOrEqualTo(String value) {
+            addCriterion("speaker_id <=", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLike(String value) {
+            addCriterion("speaker_id like", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotLike(String value) {
+            addCriterion("speaker_id not like", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIn(List<String> values) {
+            addCriterion("speaker_id in", values, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotIn(List<String> values) {
+            addCriterion("speaker_id not in", values, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdBetween(String value1, String value2) {
+            addCriterion("speaker_id between", value1, value2, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotBetween(String value1, String value2) {
+            addCriterion("speaker_id not between", value1, value2, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelIsNull() {
+            addCriterion("speaker_label is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelIsNotNull() {
+            addCriterion("speaker_label is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelEqualTo(String value) {
+            addCriterion("speaker_label =", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelNotEqualTo(String value) {
+            addCriterion("speaker_label <>", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelGreaterThan(String value) {
+            addCriterion("speaker_label >", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelGreaterThanOrEqualTo(String value) {
+            addCriterion("speaker_label >=", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelLessThan(String value) {
+            addCriterion("speaker_label <", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelLessThanOrEqualTo(String value) {
+            addCriterion("speaker_label <=", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelLike(String value) {
+            addCriterion("speaker_label like", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelNotLike(String value) {
+            addCriterion("speaker_label not like", value, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelIn(List<String> values) {
+            addCriterion("speaker_label in", values, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelNotIn(List<String> values) {
+            addCriterion("speaker_label not in", values, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelBetween(String value1, String value2) {
+            addCriterion("speaker_label between", value1, value2, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerLabelNotBetween(String value1, String value2) {
+            addCriterion("speaker_label not between", value1, value2, "speakerLabel");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlIsNull() {
+            addCriterion("audio_url is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlIsNotNull() {
+            addCriterion("audio_url is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlEqualTo(String value) {
+            addCriterion("audio_url =", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlNotEqualTo(String value) {
+            addCriterion("audio_url <>", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlGreaterThan(String value) {
+            addCriterion("audio_url >", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlGreaterThanOrEqualTo(String value) {
+            addCriterion("audio_url >=", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlLessThan(String value) {
+            addCriterion("audio_url <", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlLessThanOrEqualTo(String value) {
+            addCriterion("audio_url <=", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlLike(String value) {
+            addCriterion("audio_url like", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlNotLike(String value) {
+            addCriterion("audio_url not like", value, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlIn(List<String> values) {
+            addCriterion("audio_url in", values, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlNotIn(List<String> values) {
+            addCriterion("audio_url not in", values, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlBetween(String value1, String value2) {
+            addCriterion("audio_url between", value1, value2, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andAudioUrlNotBetween(String value1, String value2) {
+            addCriterion("audio_url not between", value1, value2, "audioUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdIsNull() {
+            addCriterion("refer_account_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdIsNotNull() {
+            addCriterion("refer_account_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdEqualTo(String value) {
+            addCriterion("refer_account_id =", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdNotEqualTo(String value) {
+            addCriterion("refer_account_id <>", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdGreaterThan(String value) {
+            addCriterion("refer_account_id >", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdGreaterThanOrEqualTo(String value) {
+            addCriterion("refer_account_id >=", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdLessThan(String value) {
+            addCriterion("refer_account_id <", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdLessThanOrEqualTo(String value) {
+            addCriterion("refer_account_id <=", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdLike(String value) {
+            addCriterion("refer_account_id like", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdNotLike(String value) {
+            addCriterion("refer_account_id not like", value, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdIn(List<String> values) {
+            addCriterion("refer_account_id in", values, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdNotIn(List<String> values) {
+            addCriterion("refer_account_id not in", values, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdBetween(String value1, String value2) {
+            addCriterion("refer_account_id between", value1, value2, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andReferAccountIdNotBetween(String value1, String value2) {
+            addCriterion("refer_account_id not between", value1, value2, "referAccountId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIsNull() {
+            addCriterion("`type` is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIsNotNull() {
+            addCriterion("`type` is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeEqualTo(Integer value) {
+            addCriterion("`type` =", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotEqualTo(Integer value) {
+            addCriterion("`type` <>", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeGreaterThan(Integer value) {
+            addCriterion("`type` >", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeGreaterThanOrEqualTo(Integer value) {
+            addCriterion("`type` >=", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeLessThan(Integer value) {
+            addCriterion("`type` <", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeLessThanOrEqualTo(Integer value) {
+            addCriterion("`type` <=", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIn(List<Integer> values) {
+            addCriterion("`type` in", values, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotIn(List<Integer> values) {
+            addCriterion("`type` not in", values, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeBetween(Integer value1, Integer value2) {
+            addCriterion("`type` between", value1, value2, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotBetween(Integer value1, Integer value2) {
+            addCriterion("`type` not between", value1, value2, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountIsNull() {
+            addCriterion("create_account is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountIsNotNull() {
+            addCriterion("create_account is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountEqualTo(String value) {
+            addCriterion("create_account =", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountNotEqualTo(String value) {
+            addCriterion("create_account <>", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountGreaterThan(String value) {
+            addCriterion("create_account >", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountGreaterThanOrEqualTo(String value) {
+            addCriterion("create_account >=", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountLessThan(String value) {
+            addCriterion("create_account <", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountLessThanOrEqualTo(String value) {
+            addCriterion("create_account <=", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountLike(String value) {
+            addCriterion("create_account like", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountNotLike(String value) {
+            addCriterion("create_account not like", value, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountIn(List<String> values) {
+            addCriterion("create_account in", values, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountNotIn(List<String> values) {
+            addCriterion("create_account not in", values, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountBetween(String value1, String value2) {
+            addCriterion("create_account between", value1, value2, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateAccountNotBetween(String value1, String value2) {
+            addCriterion("create_account not between", value1, value2, "createAccount");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNull() {
+            addCriterion("create_timestamp is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNotNull() {
+            addCriterion("create_timestamp is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampEqualTo(Long value) {
+            addCriterion("create_timestamp =", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotEqualTo(Long value) {
+            addCriterion("create_timestamp <>", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThan(Long value) {
+            addCriterion("create_timestamp >", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp >=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThan(Long value) {
+            addCriterion("create_timestamp <", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp <=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIn(List<Long> values) {
+            addCriterion("create_timestamp in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotIn(List<Long> values) {
+            addCriterion("create_timestamp not in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp not between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeIsNull() {
+            addCriterion("source_type is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeIsNotNull() {
+            addCriterion("source_type is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeEqualTo(String value) {
+            addCriterion("source_type =", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeNotEqualTo(String value) {
+            addCriterion("source_type <>", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeGreaterThan(String value) {
+            addCriterion("source_type >", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeGreaterThanOrEqualTo(String value) {
+            addCriterion("source_type >=", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeLessThan(String value) {
+            addCriterion("source_type <", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeLessThanOrEqualTo(String value) {
+            addCriterion("source_type <=", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeLike(String value) {
+            addCriterion("source_type like", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeNotLike(String value) {
+            addCriterion("source_type not like", value, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeIn(List<String> values) {
+            addCriterion("source_type in", values, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeNotIn(List<String> values) {
+            addCriterion("source_type not in", values, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeBetween(String value1, String value2) {
+            addCriterion("source_type between", value1, value2, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSourceTypeNotBetween(String value1, String value2) {
+            addCriterion("source_type not between", value1, value2, "sourceType");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexIsNull() {
+            addCriterion("sex is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexIsNotNull() {
+            addCriterion("sex is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexEqualTo(String value) {
+            addCriterion("sex =", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexNotEqualTo(String value) {
+            addCriterion("sex <>", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexGreaterThan(String value) {
+            addCriterion("sex >", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexGreaterThanOrEqualTo(String value) {
+            addCriterion("sex >=", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexLessThan(String value) {
+            addCriterion("sex <", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexLessThanOrEqualTo(String value) {
+            addCriterion("sex <=", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexLike(String value) {
+            addCriterion("sex like", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexNotLike(String value) {
+            addCriterion("sex not like", value, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexIn(List<String> values) {
+            addCriterion("sex in", values, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexNotIn(List<String> values) {
+            addCriterion("sex not in", values, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexBetween(String value1, String value2) {
+            addCriterion("sex between", value1, value2, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andSexNotBetween(String value1, String value2) {
+            addCriterion("sex not between", value1, value2, "sex");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIsNull() {
+            addCriterion("cover_url is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIsNotNull() {
+            addCriterion("cover_url is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlEqualTo(String value) {
+            addCriterion("cover_url =", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotEqualTo(String value) {
+            addCriterion("cover_url <>", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlGreaterThan(String value) {
+            addCriterion("cover_url >", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlGreaterThanOrEqualTo(String value) {
+            addCriterion("cover_url >=", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLessThan(String value) {
+            addCriterion("cover_url <", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLessThanOrEqualTo(String value) {
+            addCriterion("cover_url <=", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlLike(String value) {
+            addCriterion("cover_url like", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotLike(String value) {
+            addCriterion("cover_url not like", value, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlIn(List<String> values) {
+            addCriterion("cover_url in", values, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotIn(List<String> values) {
+            addCriterion("cover_url not in", values, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlBetween(String value1, String value2) {
+            addCriterion("cover_url between", value1, value2, "coverUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andCoverUrlNotBetween(String value1, String value2) {
+            addCriterion("cover_url not between", value1, value2, "coverUrl");
+            return (Criteria) this;
+        }
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated do_not_delete_during_merge Fri Oct 24 13:51:27 CST 2025
+     */
+    public static class Criteria extends GeneratedCriteria {
+
+        protected Criteria() {
+            super();
+        }
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table ai_model_tts
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 274 - 0
core/src/main/java/com/tzld/supply/model/po/supply/spider/FishApiRecord.java

@@ -0,0 +1,274 @@
+package com.tzld.supply.model.po.supply.spider;
+
+/**
+ *
+ * This class was generated by MyBatis Generator.
+ * This class corresponds to the database table fish_api_record
+ */
+public class FishApiRecord {
+    /**
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private Long id;
+
+    /**
+     * Database Column Remarks:
+     *   fish speakerId
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String speakerId;
+
+    /**
+     * Database Column Remarks:
+     *   业务ID
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.biz_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String bizId;
+
+    /**
+     * Database Column Remarks:
+     *   tts url
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.tts_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String ttsUrl;
+
+    /**
+     * Database Column Remarks:
+     *   文本md5
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.text_md5
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String textMd5;
+
+    /**
+     * Database Column Remarks:
+     *   创建时间戳
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private Long createTimestamp;
+
+    /**
+     * Database Column Remarks:
+     *   原始文本
+     *
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database column fish_api_record.text_raw
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    private String textRaw;
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.id
+     *
+     * @return the value of fish_api_record.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.id
+     *
+     * @param id the value for fish_api_record.id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.speaker_id
+     *
+     * @return the value of fish_api_record.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getSpeakerId() {
+        return speakerId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.speaker_id
+     *
+     * @param speakerId the value for fish_api_record.speaker_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setSpeakerId(String speakerId) {
+        this.speakerId = speakerId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.biz_id
+     *
+     * @return the value of fish_api_record.biz_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getBizId() {
+        return bizId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.biz_id
+     *
+     * @param bizId the value for fish_api_record.biz_id
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setBizId(String bizId) {
+        this.bizId = bizId;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.tts_url
+     *
+     * @return the value of fish_api_record.tts_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getTtsUrl() {
+        return ttsUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.tts_url
+     *
+     * @param ttsUrl the value for fish_api_record.tts_url
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setTtsUrl(String ttsUrl) {
+        this.ttsUrl = ttsUrl;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.text_md5
+     *
+     * @return the value of fish_api_record.text_md5
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getTextMd5() {
+        return textMd5;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.text_md5
+     *
+     * @param textMd5 the value for fish_api_record.text_md5
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setTextMd5(String textMd5) {
+        this.textMd5 = textMd5;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.create_timestamp
+     *
+     * @return the value of fish_api_record.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Long getCreateTimestamp() {
+        return createTimestamp;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.create_timestamp
+     *
+     * @param createTimestamp the value for fish_api_record.create_timestamp
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setCreateTimestamp(Long createTimestamp) {
+        this.createTimestamp = createTimestamp;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method returns the value of the database column fish_api_record.text_raw
+     *
+     * @return the value of fish_api_record.text_raw
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getTextRaw() {
+        return textRaw;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method sets the value of the database column fish_api_record.text_raw
+     *
+     * @param textRaw the value for fish_api_record.text_raw
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setTextRaw(String textRaw) {
+        this.textRaw = textRaw;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", id=").append(id);
+        sb.append(", speakerId=").append(speakerId);
+        sb.append(", bizId=").append(bizId);
+        sb.append(", ttsUrl=").append(ttsUrl);
+        sb.append(", textMd5=").append(textMd5);
+        sb.append(", createTimestamp=").append(createTimestamp);
+        sb.append(", textRaw=").append(textRaw);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 702 - 0
core/src/main/java/com/tzld/supply/model/po/supply/spider/FishApiRecordExample.java

@@ -0,0 +1,702 @@
+package com.tzld.supply.model.po.supply.spider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FishApiRecordExample {
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected String orderByClause;
+
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected boolean distinct;
+
+    /**
+     * This field was generated by MyBatis Generator.
+     * This field corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected List<Criteria> oredCriteria;
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public FishApiRecordExample() {
+        oredCriteria = new ArrayList<Criteria>();
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    /**
+     * This method was generated by MyBatis Generator.
+     * This method corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<Criterion>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(Long value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(Long value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(Long value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(Long value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(Long value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<Long> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<Long> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(Long value1, Long value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(Long value1, Long value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIsNull() {
+            addCriterion("speaker_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIsNotNull() {
+            addCriterion("speaker_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdEqualTo(String value) {
+            addCriterion("speaker_id =", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotEqualTo(String value) {
+            addCriterion("speaker_id <>", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdGreaterThan(String value) {
+            addCriterion("speaker_id >", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdGreaterThanOrEqualTo(String value) {
+            addCriterion("speaker_id >=", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLessThan(String value) {
+            addCriterion("speaker_id <", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLessThanOrEqualTo(String value) {
+            addCriterion("speaker_id <=", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdLike(String value) {
+            addCriterion("speaker_id like", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotLike(String value) {
+            addCriterion("speaker_id not like", value, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdIn(List<String> values) {
+            addCriterion("speaker_id in", values, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotIn(List<String> values) {
+            addCriterion("speaker_id not in", values, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdBetween(String value1, String value2) {
+            addCriterion("speaker_id between", value1, value2, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andSpeakerIdNotBetween(String value1, String value2) {
+            addCriterion("speaker_id not between", value1, value2, "speakerId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdIsNull() {
+            addCriterion("biz_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdIsNotNull() {
+            addCriterion("biz_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdEqualTo(String value) {
+            addCriterion("biz_id =", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdNotEqualTo(String value) {
+            addCriterion("biz_id <>", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdGreaterThan(String value) {
+            addCriterion("biz_id >", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdGreaterThanOrEqualTo(String value) {
+            addCriterion("biz_id >=", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdLessThan(String value) {
+            addCriterion("biz_id <", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdLessThanOrEqualTo(String value) {
+            addCriterion("biz_id <=", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdLike(String value) {
+            addCriterion("biz_id like", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdNotLike(String value) {
+            addCriterion("biz_id not like", value, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdIn(List<String> values) {
+            addCriterion("biz_id in", values, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdNotIn(List<String> values) {
+            addCriterion("biz_id not in", values, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdBetween(String value1, String value2) {
+            addCriterion("biz_id between", value1, value2, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andBizIdNotBetween(String value1, String value2) {
+            addCriterion("biz_id not between", value1, value2, "bizId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlIsNull() {
+            addCriterion("tts_url is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlIsNotNull() {
+            addCriterion("tts_url is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlEqualTo(String value) {
+            addCriterion("tts_url =", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlNotEqualTo(String value) {
+            addCriterion("tts_url <>", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlGreaterThan(String value) {
+            addCriterion("tts_url >", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlGreaterThanOrEqualTo(String value) {
+            addCriterion("tts_url >=", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlLessThan(String value) {
+            addCriterion("tts_url <", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlLessThanOrEqualTo(String value) {
+            addCriterion("tts_url <=", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlLike(String value) {
+            addCriterion("tts_url like", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlNotLike(String value) {
+            addCriterion("tts_url not like", value, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlIn(List<String> values) {
+            addCriterion("tts_url in", values, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlNotIn(List<String> values) {
+            addCriterion("tts_url not in", values, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlBetween(String value1, String value2) {
+            addCriterion("tts_url between", value1, value2, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTtsUrlNotBetween(String value1, String value2) {
+            addCriterion("tts_url not between", value1, value2, "ttsUrl");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5IsNull() {
+            addCriterion("text_md5 is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5IsNotNull() {
+            addCriterion("text_md5 is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5EqualTo(String value) {
+            addCriterion("text_md5 =", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5NotEqualTo(String value) {
+            addCriterion("text_md5 <>", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5GreaterThan(String value) {
+            addCriterion("text_md5 >", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5GreaterThanOrEqualTo(String value) {
+            addCriterion("text_md5 >=", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5LessThan(String value) {
+            addCriterion("text_md5 <", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5LessThanOrEqualTo(String value) {
+            addCriterion("text_md5 <=", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5Like(String value) {
+            addCriterion("text_md5 like", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5NotLike(String value) {
+            addCriterion("text_md5 not like", value, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5In(List<String> values) {
+            addCriterion("text_md5 in", values, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5NotIn(List<String> values) {
+            addCriterion("text_md5 not in", values, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5Between(String value1, String value2) {
+            addCriterion("text_md5 between", value1, value2, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andTextMd5NotBetween(String value1, String value2) {
+            addCriterion("text_md5 not between", value1, value2, "textMd5");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNull() {
+            addCriterion("create_timestamp is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIsNotNull() {
+            addCriterion("create_timestamp is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampEqualTo(Long value) {
+            addCriterion("create_timestamp =", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotEqualTo(Long value) {
+            addCriterion("create_timestamp <>", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThan(Long value) {
+            addCriterion("create_timestamp >", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampGreaterThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp >=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThan(Long value) {
+            addCriterion("create_timestamp <", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampLessThanOrEqualTo(Long value) {
+            addCriterion("create_timestamp <=", value, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampIn(List<Long> values) {
+            addCriterion("create_timestamp in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotIn(List<Long> values) {
+            addCriterion("create_timestamp not in", values, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimestampNotBetween(Long value1, Long value2) {
+            addCriterion("create_timestamp not between", value1, value2, "createTimestamp");
+            return (Criteria) this;
+        }
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table fish_api_record
+     *
+     * @mbg.generated do_not_delete_during_merge Fri Oct 24 13:51:27 CST 2025
+     */
+    public static class Criteria extends GeneratedCriteria {
+
+        protected Criteria() {
+            super();
+        }
+    }
+
+    /**
+     * This class was generated by MyBatis Generator.
+     * This class corresponds to the database table fish_api_record
+     *
+     * @mbg.generated Fri Oct 24 13:51:27 CST 2025
+     */
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 23 - 0
core/src/main/java/com/tzld/supply/util/DistributedIdGenerator.java

@@ -0,0 +1,23 @@
+package com.tzld.supply.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+
+public abstract class DistributedIdGenerator {
+    /**
+     * 生成一个
+     *
+     * @return
+     */
+    public static String generate() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
+        builder.append(new Random().nextInt(899999) + 100000);
+        return builder.toString();
+    }
+
+    public static void main(String[] args) {
+        System.out.println(generate());
+    }
+}

+ 3 - 1
core/src/main/resources/generator/mybatis-spider-generator-config.xml

@@ -48,7 +48,9 @@
 
 <!--        <table tableName="spider_task" domainObjectName="" alias=""/>-->
 <!--        <table tableName="spider_content" domainObjectName="" alias=""/>-->
-        <table tableName="spider_content_media" domainObjectName="" alias=""/>
+<!--        <table tableName="spider_content_media" domainObjectName="" alias=""/>-->
+        <table tableName="ai_model_tts" domainObjectName="" alias=""/>
+        <table tableName="fish_api_record" domainObjectName="" alias=""/>
     </context>
 
 </generatorConfiguration>

+ 428 - 0
core/src/main/resources/mapper/supply/spider/AiModelTtsMapper.xml

@@ -0,0 +1,428 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tzld.supply.dao.mapper.supply.spider.AiModelTtsMapper">
+  <resultMap id="BaseResultMap" type="com.tzld.supply.model.po.supply.spider.AiModelTts">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <id column="id" jdbcType="VARCHAR" property="id" />
+    <result column="model" jdbcType="VARCHAR" property="model" />
+    <result column="tts_id" jdbcType="VARCHAR" property="ttsId" />
+    <result column="speaker" jdbcType="VARCHAR" property="speaker" />
+    <result column="speaker_id" jdbcType="VARCHAR" property="speakerId" />
+    <result column="speaker_label" jdbcType="VARCHAR" property="speakerLabel" />
+    <result column="audio_url" jdbcType="VARCHAR" property="audioUrl" />
+    <result column="refer_account_id" jdbcType="VARCHAR" property="referAccountId" />
+    <result column="type" jdbcType="INTEGER" property="type" />
+    <result column="create_account" jdbcType="VARCHAR" property="createAccount" />
+    <result column="create_timestamp" jdbcType="BIGINT" property="createTimestamp" />
+    <result column="source_type" jdbcType="VARCHAR" property="sourceType" />
+    <result column="sex" jdbcType="VARCHAR" property="sex" />
+    <result column="cover_url" jdbcType="VARCHAR" property="coverUrl" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    id, model, tts_id, speaker, speaker_id, speaker_label, audio_url, refer_account_id, 
+    `type`, create_account, create_timestamp, source_type, sex, cover_url
+  </sql>
+  <select id="selectByExample" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTtsExample" resultMap="BaseResultMap">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from ai_model_tts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select 
+    <include refid="Base_Column_List" />
+    from ai_model_tts
+    where id = #{id,jdbcType=VARCHAR}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    delete from ai_model_tts
+    where id = #{id,jdbcType=VARCHAR}
+  </delete>
+  <delete id="deleteByExample" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTtsExample">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    delete from ai_model_tts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTts">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    insert into ai_model_tts (id, model, tts_id, 
+      speaker, speaker_id, speaker_label, 
+      audio_url, refer_account_id, `type`, 
+      create_account, create_timestamp, source_type, 
+      sex, cover_url)
+    values (#{id,jdbcType=VARCHAR}, #{model,jdbcType=VARCHAR}, #{ttsId,jdbcType=VARCHAR}, 
+      #{speaker,jdbcType=VARCHAR}, #{speakerId,jdbcType=VARCHAR}, #{speakerLabel,jdbcType=VARCHAR}, 
+      #{audioUrl,jdbcType=VARCHAR}, #{referAccountId,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, 
+      #{createAccount,jdbcType=VARCHAR}, #{createTimestamp,jdbcType=BIGINT}, #{sourceType,jdbcType=VARCHAR}, 
+      #{sex,jdbcType=VARCHAR}, #{coverUrl,jdbcType=VARCHAR})
+  </insert>
+  <insert id="insertSelective" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTts">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    insert into ai_model_tts
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="model != null">
+        model,
+      </if>
+      <if test="ttsId != null">
+        tts_id,
+      </if>
+      <if test="speaker != null">
+        speaker,
+      </if>
+      <if test="speakerId != null">
+        speaker_id,
+      </if>
+      <if test="speakerLabel != null">
+        speaker_label,
+      </if>
+      <if test="audioUrl != null">
+        audio_url,
+      </if>
+      <if test="referAccountId != null">
+        refer_account_id,
+      </if>
+      <if test="type != null">
+        `type`,
+      </if>
+      <if test="createAccount != null">
+        create_account,
+      </if>
+      <if test="createTimestamp != null">
+        create_timestamp,
+      </if>
+      <if test="sourceType != null">
+        source_type,
+      </if>
+      <if test="sex != null">
+        sex,
+      </if>
+      <if test="coverUrl != null">
+        cover_url,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=VARCHAR},
+      </if>
+      <if test="model != null">
+        #{model,jdbcType=VARCHAR},
+      </if>
+      <if test="ttsId != null">
+        #{ttsId,jdbcType=VARCHAR},
+      </if>
+      <if test="speaker != null">
+        #{speaker,jdbcType=VARCHAR},
+      </if>
+      <if test="speakerId != null">
+        #{speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="speakerLabel != null">
+        #{speakerLabel,jdbcType=VARCHAR},
+      </if>
+      <if test="audioUrl != null">
+        #{audioUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="referAccountId != null">
+        #{referAccountId,jdbcType=VARCHAR},
+      </if>
+      <if test="type != null">
+        #{type,jdbcType=INTEGER},
+      </if>
+      <if test="createAccount != null">
+        #{createAccount,jdbcType=VARCHAR},
+      </if>
+      <if test="createTimestamp != null">
+        #{createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="sourceType != null">
+        #{sourceType,jdbcType=VARCHAR},
+      </if>
+      <if test="sex != null">
+        #{sex,jdbcType=VARCHAR},
+      </if>
+      <if test="coverUrl != null">
+        #{coverUrl,jdbcType=VARCHAR},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTtsExample" resultType="java.lang.Long">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select count(*) from ai_model_tts
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update ai_model_tts
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=VARCHAR},
+      </if>
+      <if test="record.model != null">
+        model = #{record.model,jdbcType=VARCHAR},
+      </if>
+      <if test="record.ttsId != null">
+        tts_id = #{record.ttsId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.speaker != null">
+        speaker = #{record.speaker,jdbcType=VARCHAR},
+      </if>
+      <if test="record.speakerId != null">
+        speaker_id = #{record.speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.speakerLabel != null">
+        speaker_label = #{record.speakerLabel,jdbcType=VARCHAR},
+      </if>
+      <if test="record.audioUrl != null">
+        audio_url = #{record.audioUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="record.referAccountId != null">
+        refer_account_id = #{record.referAccountId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.type != null">
+        `type` = #{record.type,jdbcType=INTEGER},
+      </if>
+      <if test="record.createAccount != null">
+        create_account = #{record.createAccount,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createTimestamp != null">
+        create_timestamp = #{record.createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="record.sourceType != null">
+        source_type = #{record.sourceType,jdbcType=VARCHAR},
+      </if>
+      <if test="record.sex != null">
+        sex = #{record.sex,jdbcType=VARCHAR},
+      </if>
+      <if test="record.coverUrl != null">
+        cover_url = #{record.coverUrl,jdbcType=VARCHAR},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update ai_model_tts
+    set id = #{record.id,jdbcType=VARCHAR},
+      model = #{record.model,jdbcType=VARCHAR},
+      tts_id = #{record.ttsId,jdbcType=VARCHAR},
+      speaker = #{record.speaker,jdbcType=VARCHAR},
+      speaker_id = #{record.speakerId,jdbcType=VARCHAR},
+      speaker_label = #{record.speakerLabel,jdbcType=VARCHAR},
+      audio_url = #{record.audioUrl,jdbcType=VARCHAR},
+      refer_account_id = #{record.referAccountId,jdbcType=VARCHAR},
+      `type` = #{record.type,jdbcType=INTEGER},
+      create_account = #{record.createAccount,jdbcType=VARCHAR},
+      create_timestamp = #{record.createTimestamp,jdbcType=BIGINT},
+      source_type = #{record.sourceType,jdbcType=VARCHAR},
+      sex = #{record.sex,jdbcType=VARCHAR},
+      cover_url = #{record.coverUrl,jdbcType=VARCHAR}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTts">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update ai_model_tts
+    <set>
+      <if test="model != null">
+        model = #{model,jdbcType=VARCHAR},
+      </if>
+      <if test="ttsId != null">
+        tts_id = #{ttsId,jdbcType=VARCHAR},
+      </if>
+      <if test="speaker != null">
+        speaker = #{speaker,jdbcType=VARCHAR},
+      </if>
+      <if test="speakerId != null">
+        speaker_id = #{speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="speakerLabel != null">
+        speaker_label = #{speakerLabel,jdbcType=VARCHAR},
+      </if>
+      <if test="audioUrl != null">
+        audio_url = #{audioUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="referAccountId != null">
+        refer_account_id = #{referAccountId,jdbcType=VARCHAR},
+      </if>
+      <if test="type != null">
+        `type` = #{type,jdbcType=INTEGER},
+      </if>
+      <if test="createAccount != null">
+        create_account = #{createAccount,jdbcType=VARCHAR},
+      </if>
+      <if test="createTimestamp != null">
+        create_timestamp = #{createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="sourceType != null">
+        source_type = #{sourceType,jdbcType=VARCHAR},
+      </if>
+      <if test="sex != null">
+        sex = #{sex,jdbcType=VARCHAR},
+      </if>
+      <if test="coverUrl != null">
+        cover_url = #{coverUrl,jdbcType=VARCHAR},
+      </if>
+    </set>
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.tzld.supply.model.po.supply.spider.AiModelTts">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update ai_model_tts
+    set model = #{model,jdbcType=VARCHAR},
+      tts_id = #{ttsId,jdbcType=VARCHAR},
+      speaker = #{speaker,jdbcType=VARCHAR},
+      speaker_id = #{speakerId,jdbcType=VARCHAR},
+      speaker_label = #{speakerLabel,jdbcType=VARCHAR},
+      audio_url = #{audioUrl,jdbcType=VARCHAR},
+      refer_account_id = #{referAccountId,jdbcType=VARCHAR},
+      `type` = #{type,jdbcType=INTEGER},
+      create_account = #{createAccount,jdbcType=VARCHAR},
+      create_timestamp = #{createTimestamp,jdbcType=BIGINT},
+      source_type = #{sourceType,jdbcType=VARCHAR},
+      sex = #{sex,jdbcType=VARCHAR},
+      cover_url = #{coverUrl,jdbcType=VARCHAR}
+    where id = #{id,jdbcType=VARCHAR}
+  </update>
+</mapper>

+ 387 - 0
core/src/main/resources/mapper/supply/spider/FishApiRecordMapper.xml

@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.tzld.supply.dao.mapper.supply.spider.FishApiRecordMapper">
+  <resultMap id="BaseResultMap" type="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="speaker_id" jdbcType="VARCHAR" property="speakerId" />
+    <result column="biz_id" jdbcType="VARCHAR" property="bizId" />
+    <result column="tts_url" jdbcType="VARCHAR" property="ttsUrl" />
+    <result column="text_md5" jdbcType="VARCHAR" property="textMd5" />
+    <result column="create_timestamp" jdbcType="BIGINT" property="createTimestamp" />
+  </resultMap>
+  <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <result column="text_raw" jdbcType="LONGVARCHAR" property="textRaw" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    id, speaker_id, biz_id, tts_url, text_md5, create_timestamp
+  </sql>
+  <sql id="Blob_Column_List">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    text_raw
+  </sql>
+  <select id="selectByExampleWithBLOBs" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecordExample" resultMap="ResultMapWithBLOBs">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    ,
+    <include refid="Blob_Column_List" />
+    from fish_api_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByExample" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecordExample" resultMap="BaseResultMap">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from fish_api_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="ResultMapWithBLOBs">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select 
+    <include refid="Base_Column_List" />
+    ,
+    <include refid="Blob_Column_List" />
+    from fish_api_record
+    where id = #{id,jdbcType=BIGINT}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    delete from fish_api_record
+    where id = #{id,jdbcType=BIGINT}
+  </delete>
+  <delete id="deleteByExample" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecordExample">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    delete from fish_api_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    insert into fish_api_record (id, speaker_id, biz_id, 
+      tts_url, text_md5, create_timestamp, 
+      text_raw)
+    values (#{id,jdbcType=BIGINT}, #{speakerId,jdbcType=VARCHAR}, #{bizId,jdbcType=VARCHAR}, 
+      #{ttsUrl,jdbcType=VARCHAR}, #{textMd5,jdbcType=VARCHAR}, #{createTimestamp,jdbcType=BIGINT}, 
+      #{textRaw,jdbcType=LONGVARCHAR})
+  </insert>
+  <insert id="insertSelective" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    insert into fish_api_record
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="speakerId != null">
+        speaker_id,
+      </if>
+      <if test="bizId != null">
+        biz_id,
+      </if>
+      <if test="ttsUrl != null">
+        tts_url,
+      </if>
+      <if test="textMd5 != null">
+        text_md5,
+      </if>
+      <if test="createTimestamp != null">
+        create_timestamp,
+      </if>
+      <if test="textRaw != null">
+        text_raw,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=BIGINT},
+      </if>
+      <if test="speakerId != null">
+        #{speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="bizId != null">
+        #{bizId,jdbcType=VARCHAR},
+      </if>
+      <if test="ttsUrl != null">
+        #{ttsUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="textMd5 != null">
+        #{textMd5,jdbcType=VARCHAR},
+      </if>
+      <if test="createTimestamp != null">
+        #{createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="textRaw != null">
+        #{textRaw,jdbcType=LONGVARCHAR},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecordExample" resultType="java.lang.Long">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    select count(*) from fish_api_record
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=BIGINT},
+      </if>
+      <if test="record.speakerId != null">
+        speaker_id = #{record.speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.bizId != null">
+        biz_id = #{record.bizId,jdbcType=VARCHAR},
+      </if>
+      <if test="record.ttsUrl != null">
+        tts_url = #{record.ttsUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="record.textMd5 != null">
+        text_md5 = #{record.textMd5,jdbcType=VARCHAR},
+      </if>
+      <if test="record.createTimestamp != null">
+        create_timestamp = #{record.createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="record.textRaw != null">
+        text_raw = #{record.textRaw,jdbcType=LONGVARCHAR},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExampleWithBLOBs" parameterType="map">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    set id = #{record.id,jdbcType=BIGINT},
+      speaker_id = #{record.speakerId,jdbcType=VARCHAR},
+      biz_id = #{record.bizId,jdbcType=VARCHAR},
+      tts_url = #{record.ttsUrl,jdbcType=VARCHAR},
+      text_md5 = #{record.textMd5,jdbcType=VARCHAR},
+      create_timestamp = #{record.createTimestamp,jdbcType=BIGINT},
+      text_raw = #{record.textRaw,jdbcType=LONGVARCHAR}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    set id = #{record.id,jdbcType=BIGINT},
+      speaker_id = #{record.speakerId,jdbcType=VARCHAR},
+      biz_id = #{record.bizId,jdbcType=VARCHAR},
+      tts_url = #{record.ttsUrl,jdbcType=VARCHAR},
+      text_md5 = #{record.textMd5,jdbcType=VARCHAR},
+      create_timestamp = #{record.createTimestamp,jdbcType=BIGINT}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    <set>
+      <if test="speakerId != null">
+        speaker_id = #{speakerId,jdbcType=VARCHAR},
+      </if>
+      <if test="bizId != null">
+        biz_id = #{bizId,jdbcType=VARCHAR},
+      </if>
+      <if test="ttsUrl != null">
+        tts_url = #{ttsUrl,jdbcType=VARCHAR},
+      </if>
+      <if test="textMd5 != null">
+        text_md5 = #{textMd5,jdbcType=VARCHAR},
+      </if>
+      <if test="createTimestamp != null">
+        create_timestamp = #{createTimestamp,jdbcType=BIGINT},
+      </if>
+      <if test="textRaw != null">
+        text_raw = #{textRaw,jdbcType=LONGVARCHAR},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKeyWithBLOBs" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    set speaker_id = #{speakerId,jdbcType=VARCHAR},
+      biz_id = #{bizId,jdbcType=VARCHAR},
+      tts_url = #{ttsUrl,jdbcType=VARCHAR},
+      text_md5 = #{textMd5,jdbcType=VARCHAR},
+      create_timestamp = #{createTimestamp,jdbcType=BIGINT},
+      text_raw = #{textRaw,jdbcType=LONGVARCHAR}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.tzld.supply.model.po.supply.spider.FishApiRecord">
+    <!--
+      WARNING - @mbg.generated
+      This element is automatically generated by MyBatis Generator, do not modify.
+      This element was generated on Fri Oct 24 13:51:27 CST 2025.
+    -->
+    update fish_api_record
+    set speaker_id = #{speakerId,jdbcType=VARCHAR},
+      biz_id = #{bizId,jdbcType=VARCHAR},
+      tts_url = #{ttsUrl,jdbcType=VARCHAR},
+      text_md5 = #{textMd5,jdbcType=VARCHAR},
+      create_timestamp = #{createTimestamp,jdbcType=BIGINT}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+</mapper>

+ 10 - 0
pom.xml

@@ -267,6 +267,16 @@
             <artifactId>hutool-all</artifactId>
             <version>5.8.18</version>
         </dependency>
+        <dependency>
+            <groupId>org.msgpack</groupId>
+            <artifactId>msgpack-core</artifactId>
+            <version>0.9.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.msgpack</groupId>
+            <artifactId>jackson-dataformat-msgpack</artifactId>
+            <version>0.9.9</version>
+        </dependency>
 
     </dependencies>