word转xml的方法

和大佬学的

先把你需要的模版文档弄好成docx格式,再把后缀改成.zip格式 获取里面的document.xml文件,在xml中把你要替换的参数写成表达式如:${productName},在项目中通过代码填充productName参数,进行测试)

也可以把表达式先写到docx文件中,在改后缀。。。亲测

redis+mysql生成商品的唯一货号 带自动递增

如果redis数据被丢失,则从数据库查询出最大数值保存到redis在自增

  // 生成递增的货号逻辑
    public String generateProductCode() {
        lock.lock();  // 加锁,确保多线程安全
        try {
            // 从 Redis 获取当前货号,如果 Redis 中不存在,初始化货号
            String currentCodeStr = redisTemplate.opsForValue().get(PRODUCT_CODE_KEY);
            if (currentCodeStr == null) {
                // 从数据库中获取当前最大的货号
                Integer maxCode = productMapper.findMaxProductCode();
                if (maxCode == null) {
                    maxCode = 0;  // 如果数据库中没有数据,从 0 开始
                }
                // 初始化 Redis 中的货号为数据库中的最大值
                redisTemplate.opsForValue().set(PRODUCT_CODE_KEY, maxCode.toString());
            }

            // 使用 Redis 的 INCR 命令自增货号
            Long newCode = redisTemplate.opsForValue().increment(PRODUCT_CODE_KEY);
            return String.format("%08d", newCode);  // 格式化为 8 位数字
        } finally {
            lock.unlock();  // 解锁
        }
    }
 // 生成递增的货号
        String productCode = generateProductCode();
        product.setItemNumberPrefix("ZML");
        product.setItemNumber(productCode);
 private static final String PRODUCT_CODE_KEY = "product:code";  // Redis 中货号的 key
private final Lock lock = new ReentrantLock();  // 创建一个 ReentrantLock 锁

    @Autowired
    private StringRedisTemplate redisTemplate;
 // 查询当前数据库中最大的货号
    @Select("SELECT MAX(p.item_number) FROM Product p")
    Integer findMaxProductCode();

为了方便查询我是把编号和编号前缀分成了两个字段保存

private String itemNumberPrefix;
@ApiModelProperty(value = "商品货号")
private String itemNumber;

项目spring cloud整合flyway

公司项目用的微服务架构

苦于每次需要手动改数据库表

然后我在想能不能集成一个数据库版本管理工具

调查选择flyway

因为项目是分布式的,每个服务有一个数据库

然后我的做法是创建一个共同的子工程来统一管理sql文件

然后再resources目录创建每个工程对应的文件夹


再总的application.yml写入

#前缀: V 代表版本变迁(Versioned Migrations), U 代表撤销变迁(Undo Migrations), R 代表可重复变迁(Repeatable Migrations)
#版本号: 唯一的版本号,比如V1.0.1
#分隔符: __ (两个下划线)
#描述信息: 描述信息
#后缀: .sql
  flyway:
    # 是否开启flyway
    enabled: true
    encoding: utf-8
    # 是否禁用数据库清理
    clean-disabled: true
    # 若连接的数据库非空库,是否初始化
    # 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
    baseline-on-migrate: true
    # sql脚本文件名前缀,默认大写V
    sql-migration-prefix: V
    # sql脚本文件名称的分隔符,默认2个下划线__
    sql-migration-separator: __
    # 迁移sql脚本文件名称的后缀
    sql-migration-suffixes: .sql
    # metadata 版本控制信息表 默认 flyway_schema_history
    table: flyway_schema_history
    # 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略
    baseline-version: 1

然后再每个服务的配置文件中写入

  flyway:
    # 默认存放sql脚本目录,默认为db/migration
    locations: classpath:db/migration/im

指定每个工程sql位置

即可。。。。

sql文件的命名规则如下:

前缀: V 代表版本变迁(Versioned Migrations), U 代表撤销变迁(Undo Migrations), R 代表可重复变迁(Repeatable Migrations)

版本号: 唯一的版本号,比如V1.0.1

分隔符: __ (两个下划线)

描述信息: 描述信息

后缀: .sql

V1.0.0__create_user.sql

公司在对接快递100记录

首先小程序端的地图轨迹显示问题
如果使用web-view组件的话,地图会沾满满屏

所以要做小程序地图就必须使用在小程序用web-view组件 中引入项目h5页面然后再h5页面用iframe去引入地图轨迹url即可

如果H5页面想改名称的话可以用 来修改名称

 mounted() {
        document.title = "物流信息";
    },

H5代码

<template>
    <div class="app-container">
        <el-card class="box-card" shadow="hover">
            <span>{{ companyName }} {{ expressNumber }}</span>
            <span style="color: #ff5502; margin-left: 12px" @click="handleCopyText()">复制</span>
        </el-card>
        <el-card class="box-card" shadow="hover">
            <div slot="header" class="clearfix">
                <span>物流轨迹</span>
            </div>
            <div v-if="iframeMapUrl">
                <iframe id="iframe" width="100%" height="600px" frameborder="0" allowfullscreen :src="iframeMapUrl" />
            </div>
            <div v-else class="empty-space">暂无物流信息</div>
        </el-card>
        <el-card class="box-card" shadow="hover">
            <div slot="header" class="clearfix">
                <span>物流信息</span>
            </div>
            <template v-if="limitedProgressInfo">
                <div class="view-more-button">
                    <el-button type="text" @click="showAllProgressInfo">{{ showLimitedProgress ? '查看详情' : '收起详情' }}
                        <i :class="showLimitedProgress ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"></i></el-button>
                </div>
                <el-timeline>
                    <el-timeline-item v-for="(activity, index) in limitedProgressInfo" :key="index"
                        :timestamp="activity.time">
                        <template v-if="activity.status === '揽收'">
                            <span style="color: #67c23a">已揽收:</span>
                            <span>{{ activity.context }}</span>
                        </template>
                        <template v-else-if="activity.status === '在途'">
                            <span style="color: #409eff">运输中:</span>
                            <span>{{ activity.context }}</span>
                        </template>
                        <template v-else-if="activity.status === '派件'">
                            <span style="color: #f56c6c">派件中:</span>
                            <span>{{ activity.context }}</span>
                        </template>
                        <template v-else-if="activity.status === '签收'">
                            <span style="color: #67c23a">已签收:</span>
                            <span>{{ activity.context }}</span>
                        </template>
                        <template v-else-if="activity.status === '退回'">
                            <span style="color: #909399">已退回:</span>
                            <span>{{ activity.context }}</span>
                        </template>
                    </el-timeline-item>
                </el-timeline>
            </template>
            <div v-else class="empty-space">暂无物流信息</div>
        </el-card>
    </div>
</template>

<script>
import { deliveryCheck } from '@/api/mall'
export default {
    name: 'logisticsInfoh5',
    components: {},
    // metaInfo: {
    //     title: '物流信息'
    // },
    props: {
        type: {
            default: 1,
            type: Number
        }
    },
    mounted() {
        document.title = "物流信息";
    },
    computed: {

    },
    data() {
        return {
            post_name: '韵达快递', //快递名称
            logo: 'https://cdn.kuaidi100.com/images/all/56/yunda.png', //快递logo
            exp_phone: '95546', //快递电话
            progressVisible: false,
            companyName: null,
            expressNumber: null,
            companyNameExpressNumber: this.companyName + this.expressNumber,
            iframeMapUrl: null,
            progressInfo: null, // 完整的物流信息数据
            limitedProgressInfo: null, // 展示的部分物流信息数据
            showLimitedProgress: true // 控制是否只显示部分物流信息
        }
    },
    watch: {},
    created() {
        this.showProgressBox()
    },
    methods: {
        //复制
        handleCopyText() {
            // 创建一个 Input标签
            const cInput = document.createElement('input')
            cInput.value = this.companyName + this.expressNumber
            document.body.appendChild(cInput)
            cInput.select() // 选取文本域内容;
            // 执行浏览器复制命令
            // 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签)
            // Input要在正常的编辑状态下原生复制方法才会生效
            document.execCommand('Copy')
            this.$message.success('复制成功')
            /// 复制成功后再将构造的标签 移除
            cInput.remove()
        },
        //展示物流进度的对话框
        async showProgressBox() {
            const params = {
                orderNum: 3644
            }
            deliveryCheck(params)
                .then((res) => {
                    this.companyName = res.data.companyName
                    this.expressNumber = res.data.expressNumber

                    if (res.code !== 200) {
                        return this.$message.error('获取物流进度失败!')
                    }

                    if (res.data.queryTrackResp) {
                        this.progressInfo = res.data.queryTrackResp.data
                    }
                    if (res.data.queryTrackMapResp) {
                        this.iframeMapUrl = res.data.queryTrackMapResp.trailUrl
                    }
                    if (this.progressInfo) {
                        this.limitedProgressInfo = this.progressInfo.slice(0, 3)
                    }
                })
                .catch((error) => {
                    console.error(error)
                })
        },
        showAllProgressInfo() {
            this.limitedProgressInfo = this.progressInfo
            this.showLimitedProgress = !this.showLimitedProgress
            if (this.showLimitedProgress) {
                this.limitedProgressInfo = this.progressInfo.slice(0, 3)
            }
        }
    }
}
</script>
<style lang="scss" scoped>
.app-container {
    background-color: #f9f7f8;
}

.el-row {
    line-height: 2;
    font-size: 15px;
}

.box-card {
    margin: 20px 0;

    .flexItem {
        display: flex;
        align-items: center;

        .fuhao {
            margin-right: 3px;
            font-size: 16px;
            color: red;
        }

        .el-input {
            width: auto;
            flex: 1;
        }
    }
}

.custom-input {
    width: 300px;
    /* 设置输入框的宽度为300px */
}

.view-more-button {
    display: flex;
    justify-content: flex-end;
}
</style>

小程序代码: