From acc3f05f1224b4532f46bd50eee383fcdf604ba6 Mon Sep 17 00:00:00 2001 From: Timi Date: Fri, 21 Aug 2026 13:51:08 +0800 Subject: [PATCH] support pinyin search --- pom.xml | 5 + .../modules/common/entity/Multilingual.java | 14 +++ .../MultilingualServiceImplement.java | 23 +++++ .../api/modules/gao/entity/GaoCustomer.java | 14 +++ .../GaoCustomerServiceImplement.java | 10 ++ .../java/com/imyeyu/api/util/PinyinUtil.java | 63 ++++++++++++ .../V37__backfill_pinyin_search.java | 98 +++++++++++++++++++ .../V36__add_pinyin_search_columns.sql | 15 +++ .../mapper/timi-server/common/TagMapper.xml | 3 + .../timi-server/gao/GaoCustomerMapper.xml | 3 + 10 files changed, 248 insertions(+) create mode 100644 src/main/java/com/imyeyu/api/util/PinyinUtil.java create mode 100644 src/main/java/db/migration/timiserver/V37__backfill_pinyin_search.java create mode 100644 src/main/resources/db/migration/timiserver/V36__add_pinyin_search_columns.sql diff --git a/pom.xml b/pom.xml index a1aec18..a0da353 100644 --- a/pom.xml +++ b/pom.xml @@ -205,6 +205,11 @@ timi-utils 0.0.13 + + me.majiajie + tinypinyin + 2.0.3 + com.imyeyu.font.icon timi-icon-font diff --git a/src/main/java/com/imyeyu/api/modules/common/entity/Multilingual.java b/src/main/java/com/imyeyu/api/modules/common/entity/Multilingual.java index 19d59fd..11fc8fa 100644 --- a/src/main/java/com/imyeyu/api/modules/common/entity/Multilingual.java +++ b/src/main/java/com/imyeyu/api/modules/common/entity/Multilingual.java @@ -1,6 +1,8 @@ package com.imyeyu.api.modules.common.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.imyeyu.java.bean.Language; +import com.imyeyu.spring.annotation.table.Column; import com.imyeyu.spring.entity.UUIDEntity; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,6 +17,18 @@ public class Multilingual extends UUIDEntity { protected String zhCN; + @Column("zh_cn_pinyin_full") + @JsonIgnore + protected String zhCNPinyinFull; + + @Column("zh_cn_pinyin_initial") + @JsonIgnore + protected String zhCNPinyinInitial; + + @Column("zh_cn_pinyin_mixed") + @JsonIgnore + protected String zhCNPinyinMixed; + protected String zhTW; protected String enUS; diff --git a/src/main/java/com/imyeyu/api/modules/common/service/implement/MultilingualServiceImplement.java b/src/main/java/com/imyeyu/api/modules/common/service/implement/MultilingualServiceImplement.java index b67f60a..8471299 100644 --- a/src/main/java/com/imyeyu/api/modules/common/service/implement/MultilingualServiceImplement.java +++ b/src/main/java/com/imyeyu/api/modules/common/service/implement/MultilingualServiceImplement.java @@ -3,6 +3,7 @@ package com.imyeyu.api.modules.common.service.implement; import com.imyeyu.api.modules.common.entity.Multilingual; import com.imyeyu.api.modules.common.mapper.MultilingualMapper; import com.imyeyu.api.modules.common.service.MultilingualService; +import com.imyeyu.api.util.PinyinUtil; import com.imyeyu.spring.mapper.BaseMapper; import com.imyeyu.spring.service.AbstractEntityService; import com.imyeyu.spring.util.Redis; @@ -34,6 +35,18 @@ public class MultilingualServiceImplement extends AbstractEntityService= BATCH_SIZE) { + update.executeBatch(); + batchSize = 0; + } + } + if (batchSize > 0) { + update.executeBatch(); + } + } + } + } + + private void backfillCustomer(Connection connection) throws Exception { + try (PreparedStatement select = connection.prepareStatement(""" + SELECT `id`, `name` + FROM `gao_customer` + WHERE `name` IS NOT NULL + AND (`name_pinyin_full` IS NULL OR `name_pinyin_initial` IS NULL OR `name_pinyin_mixed` IS NULL) + """); + PreparedStatement update = connection.prepareStatement(""" + UPDATE `gao_customer` + SET `name_pinyin_full` = ?, `name_pinyin_initial` = ?, `name_pinyin_mixed` = ? + WHERE `id` = ? + """)) { + try (ResultSet resultSet = select.executeQuery()) { + int batchSize = 0; + while (resultSet.next()) { + addCustomerBatch(update, resultSet.getString("id"), resultSet.getString("name")); + batchSize++; + if (batchSize >= BATCH_SIZE) { + update.executeBatch(); + batchSize = 0; + } + } + if (batchSize > 0) { + update.executeBatch(); + } + } + } + } + + private void addMultilingualBatch(PreparedStatement update, String id, String value) throws Exception { + update.setString(1, PinyinUtil.full(value)); + update.setString(2, PinyinUtil.initial(value)); + update.setString(3, PinyinUtil.mixed(value)); + update.setString(4, id); + update.addBatch(); + } + + private void addCustomerBatch(PreparedStatement update, String id, String value) throws Exception { + update.setString(1, PinyinUtil.full(value)); + update.setString(2, PinyinUtil.initial(value)); + update.setString(3, PinyinUtil.mixed(value)); + update.setString(4, id); + update.addBatch(); + } +} diff --git a/src/main/resources/db/migration/timiserver/V36__add_pinyin_search_columns.sql b/src/main/resources/db/migration/timiserver/V36__add_pinyin_search_columns.sql new file mode 100644 index 0000000..c5dbfc1 --- /dev/null +++ b/src/main/resources/db/migration/timiserver/V36__add_pinyin_search_columns.sql @@ -0,0 +1,15 @@ +ALTER TABLE `multilingual` + ADD COLUMN `zh_cn_pinyin_full` TEXT NULL COMMENT '简体中文全拼' AFTER `zh_cn`, + ADD COLUMN `zh_cn_pinyin_initial` TEXT NULL COMMENT '简体中文拼音首字母' AFTER `zh_cn_pinyin_full`, + ADD COLUMN `zh_cn_pinyin_mixed` TEXT NULL COMMENT '简体中文混合拼音' AFTER `zh_cn_pinyin_initial`, + ADD KEY `idx_multilingual_zh_cn_pinyin_full` (`zh_cn_pinyin_full`(128)), + ADD KEY `idx_multilingual_zh_cn_pinyin_initial` (`zh_cn_pinyin_initial`(128)), + ADD KEY `idx_multilingual_zh_cn_pinyin_mixed` (`zh_cn_pinyin_mixed`(128)); + +ALTER TABLE `gao_customer` + ADD COLUMN `name_pinyin_full` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '姓名全拼' AFTER `name`, + ADD COLUMN `name_pinyin_initial` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '姓名拼音首字母' AFTER `name_pinyin_full`, + ADD COLUMN `name_pinyin_mixed` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '姓名混合拼音' AFTER `name_pinyin_initial`, + ADD KEY `idx_gao_customer_store_name_pinyin_full` (`store_id`, `deleted_at`, `name_pinyin_full`(128)), + ADD KEY `idx_gao_customer_store_name_pinyin_initial` (`store_id`, `deleted_at`, `name_pinyin_initial`), + ADD KEY `idx_gao_customer_store_name_pinyin_mixed` (`store_id`, `deleted_at`, `name_pinyin_mixed`); diff --git a/src/main/resources/mapper/timi-server/common/TagMapper.xml b/src/main/resources/mapper/timi-server/common/TagMapper.xml index c8d7b88..e7784d5 100644 --- a/src/main/resources/mapper/timi-server/common/TagMapper.xml +++ b/src/main/resources/mapper/timi-server/common/TagMapper.xml @@ -32,6 +32,9 @@ OR `m`.`ja_jp` LIKE CONCAT('%', #{keyword}, '%') OR `m`.`de_de` LIKE CONCAT('%', #{keyword}, '%') OR `m`.`ko_kr` LIKE CONCAT('%', #{keyword}, '%') + OR `m`.`zh_cn_pinyin_full` LIKE CONCAT(#{keyword}, '%') + OR `m`.`zh_cn_pinyin_initial` LIKE CONCAT(#{keyword}, '%') + OR `m`.`zh_cn_pinyin_mixed` LIKE CONCAT(#{keyword}, '%') ) AND `t`.`deleted_at` IS NULL diff --git a/src/main/resources/mapper/timi-server/gao/GaoCustomerMapper.xml b/src/main/resources/mapper/timi-server/gao/GaoCustomerMapper.xml index 4352626..3dfc2da 100644 --- a/src/main/resources/mapper/timi-server/gao/GaoCustomerMapper.xml +++ b/src/main/resources/mapper/timi-server/gao/GaoCustomerMapper.xml @@ -29,6 +29,9 @@ `c`.`code` LIKE CONCAT('%', #{keyword}, '%') OR `c`.`name` LIKE CONCAT('%', #{keyword}, '%') OR `c`.`telephone` LIKE CONCAT('%', #{keyword}, '%') + OR `c`.`name_pinyin_full` LIKE CONCAT(#{keyword}, '%') + OR `c`.`name_pinyin_initial` LIKE CONCAT(#{keyword}, '%') + OR `c`.`name_pinyin_mixed` LIKE CONCAT(#{keyword}, '%') )