2023年5月

logback解释说明

logback使用手册

Logback解释说明

Logback是一个流行的用于Java应用程序的日志框架,它为应用程序提供了灵活的配置选项和高效的日志记录和跟踪功能。下面是详细的使用说明:

怎么在SpringBoot中集成使用logback

logback.png

  1. 添加Logback依赖

在Maven项目中,可以通过以下方式在pom.xml文件中添加Logback依赖:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
  1. 配置Logback

Logback通过XML文件配置。它提供了三种不同类型的文件来配置不同的功能:logback.xml,logback-test.xml和logback.groovy。

在logback.xml中,可以配置日志输出到控制台或文件,设置日志级别,定义日志转换模式以及配置日志归档策略等。

以下是一个简单的logback.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <root level="INFO">
        <appender-ref ref="console" />
    </root>
 
</configuration>
1.配置根路径,即日志保存路径 <property name="log.path" value="/home/wukong/logs"/>
2.这是一个用于配置日志输出格式的属性。在这个例子中,属性名是"log.pattern",其值是一个包含特定占位符的字符串。

下面是对占位符的解释:

“%d{yyyy-MM-dd HH:mm:ss}”:表示输出日志的时间戳,格式为"年-月-日 时:分:秒"。
“[%thread]”:表示输出日志的线程名。
“%-5level”:表示输出日志的级别(如DEBUG、INFO、WARN等),并且最多占用5个字符的宽度。其中,"-"表示左对齐输出。
“%logger{36}”:表示输出日志的记录器(或类)名,最多占用36个字符的宽度。
“%msg%n”:表示输出日志的具体信息(即日志消息),并在最后换行。
通过使用这些占位符,我们可以按照指定的格式输出日志,方便查阅和分析。在示例中,日志的输出格式类似于:“时间戳 [线程名] 级别 记录器名 - 日志消息”。
上述配置文件中,定义了一个名为console的控制台appender,设置了输出格式模式。根记录器设置了日志级别为INFO,并将appender引用进来。

名词解释:appender

在日志记录系统中,appender是一种用于定义日志输出目标的组件。它决定了日志消息应该被发送到哪里,比如控制台、文件、数据库或网络等。Appender包含日志消息的格式化和输出逻辑,以及确定日志记录的方式和位置。它充当了将日志消息从应用程序代码发送到指定位置的中间层。

在日志配置中,通常可以定义多个appender以满足不同的需求。每个appender都具有唯一的名称,并与一个或多个日志记录器相关联。这样,日志记录器就可以将日志消息传递给相应的appender进行处理和输出。

常见的appender类型包括:

ConsoleAppender:将日志消息输出到控制台。
FileAppender:将日志消息输出到文件。
RollingFileAppender:类似于FileAppender,但支持滚动日志文件,即自动切割为多个文件以避免文件过大。
SocketAppender:将日志消息通过网络套接字发送到远程位置。
DatabaseAppender:将日志消息存储到数据库中。
通过配置appender,我们可以灵活控制日志消息的输出目标和方式,以满足特定的需求和场景。

3. 在代码中使用Logback

使用Logback非常简单。在程序中引入Logger类,然后调用Logger的方法即可记录日志消息。以下是一个简单的Java类,它使用了Logback记录日志:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class MyClass {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
 
    public void doSomething() {
        LOGGER.debug("This is a debug message");
        LOGGER.info("This is an info message");
        LOGGER.warn("This is a warning message");
        LOGGER.error("This is an error message", new Exception("Test exception"));
    }
 
}

在这个类中,创建了一个静态Logger实例,并用getInstance()方法初始化,然后使用Logger的不同级别方法记录不同类型的日志消息。

4. 运行应用程序并查看日志

接下来就可以运行应用程序,并查看日志输出了。如果你使用Logback默认配置,日志输出将会在控制台上显示。如果你在logback.xml文件中定义了文件appender,日志消息将会写入到默认路径的文件中,通常是在项目的根目录下。

以上就是使用Logback的详细说明。Logback是一个功能丰富的日志框架,完全可以满足大部分Java应用程序的日志需求。

来自你的消息:

element ui el-select 过滤id=1的值 循环显示代码

来自ChatAI的消息:

你可以在 el-select 的数据源中使用数组的 filter 方法,过滤出不等于 1 的项,然后使用 v-for 循环显示。

以下是示例代码:

<template>
  <el-select v-model="selected" placeholder="请选择">
    <el-option v-for="item in filteredOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
  </el-select>
</template>

<script>
export default {
  data() {
    return {
      options: [
        { value: 1, label: '选项1' },
        { value: 2, label: '选项2' },
        { value: 3, label: '选项3' },
        { value: 4, label: '选项4' },
        { value: 5, label: '选项5' }
      ],
      selected: null
    }
  },
  computed: {
    filteredOptions() {
      return this.options.filter(item => item.value !== 1)
    }
  }
}
</script>

在上面的代码中,options 是 el-select 的数据源,我们使用 computed 属性 filteredOptions 来过滤掉 value 等于 1 的项,然后在 v-for 中使用 filteredOptions 来循环显示 el-option

希望这可以帮到你。

来自你的消息:

过滤多个值呢

来自ChatAI的消息:

如果你想要过滤多个值,可以使用 JavaScript 中的 Array.prototype.filter 方法和 Array.prototype.includes 方法。Array.prototype.includes 方法可以检查一个数组是否包含某个值。

以下是示例代码:

<template>
  <el-select v-model="selected" placeholder="请选择">
    <el-option v-for="item in filteredOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
  </el-select>
</template>

<script>
export default {
  data() {
    return {
      options: [
        { value: 1, label: '选项1' },
        { value: 2, label: '选项2' },
        { value: 3, label: '选项3' },
        { value: 4, label: '选项4' },
        { value: 5, label: '选项5' }
      ],
      selected: null
    }
  },
  computed: {
    filteredOptions() {
      const filtered = this.options.filter(item => {
        const excluded = [1, 3]; // 要过滤掉的值的数组
        return !excluded.includes(item.value);
      });
      return filtered;
    }
  }
}
</script>

在上面的代码中,我们使用一个名为 excluded 的数组来保存要过滤的值,然后我们在 filteredOptions 计算属性中使用 !excluded.includes(item.value) 来过滤掉这些值。

!excluded.includes(item.value) 表达式将会返回一个布尔值,如果 item.value 不是 excluded 数组中的元素,则为 true,表示该对象的 value 属性可以用于渲染 el-option 组件,否则为 false,表示需要将该对象过滤掉。

希望这对你有帮助。

编写一个基于微信小程序的抽奖页面,需要微信用户登录后才能抽奖,可以按照以下步骤进行:

  1. 在微信公众平台申请小程序账号,并创建一个新的小程序。
  2. 使用微信开发者工具创建一个新的小程序项目,并配置好相关信息。
  3. 创建一个登录页面,使用微信提供的 wx.login 接口获取用户登录凭证,并将其发送到后台服务器进行验证。如果验证通过,则返回用户信息并在前端保存用户登录状态。
  4. 创建一个抽奖页面,使用 wx.checkSession 接口检查用户登录状态是否失效。如果未失效,则显示抽奖按钮;否则提示用户重新登录。
  5. 当用户点击抽奖按钮时,向后台服务器发送请求并获取中奖结果。将中奖结果显示在前端页面上,并更新用户信息和抽奖次数。
  6. 可以添加一些动画效果来增加交互体验,比如转盘旋转、弹出框等。
  7. 注意要处理异常情况,比如网络错误、服务器响应超时等。

以下是一个简单示例代码:

login.js

// 获取应用实例
const app = getApp()

Page({
  data: {
    userInfo: null
  },

  // 登录事件处理函数
  login: function() {
    wx.login({
      success: res => {
        // 发送登录凭证到后台服务器进行验证
        wx.request({
          url: 'https://example.com/login',
          data: {
            code: res.code
          },
          success: res => {
            // 保存用户信息并跳转到首页
            app.globalData.userInfo = res.data.userInfo
            wx.switchTab({
              url: '/pages/index/index'
            })
          },
          fail: err => {
            console.error(err)
            wx.showToast({
              title: '登录失败,请稍后重试',
              icon: 'none'
            })
          }
        })
      }
    })
  },

  // 生命周期函数:页面加载完成
  onLoad: function() {
    // 检查用户是否已登录,如果已登录则跳转到首页
    if (app.globalData.userInfo) {
      wx.switchTab({
        url: '/pages/index/index'
      })
    }
  }
})

index.js

// 获取应用实例
const app = getApp()

Page({
  data: {
    lotteryResult: null,
    lotteryTimes: null,
    isDisabled: false,
    isRotating: false
  },

  // 抽奖事件处理函数
  lottery: function() {
    // 检查用户是否已登录,如果未登录则提示用户先登录
    if (!app.globalData.userInfo) {
      wx.showModal({
        title: '提示',
        content: '请先登录再进行抽奖',
        showCancel: false,
        confirmText: '去登录',
        success(res) {
          if (res.confirm) {
            wx.navigateTo({
              url: '/pages/login/login'
            })
          }
        }
      })
      return
    }

    // 检查用户是否还有抽奖次数,如果没有则提示用户明天再来
    if (this.data.lotteryTimes <= 0) {
      wx.showToast({
        title: '今天的抽奖次数已用完,请明天再来',
        icon: 'none'
      })
      return
    }

    // 发送抽奖请求到后台服务器
    this.setData({
      isDisabled: true,
      isRotating: true
    })
    wx.request({
      url: 'https://example.com/lottery',
      data: {
        userId: app.globalData.userInfo.userId
      },
      success: res => {
        // 显示中奖结果并更新用户信息和抽奖次数
        this.setData({
          lotteryResult: res.data.result,
          lotteryTimes: res.data.times,
          isRotating: false
        })
        app.globalData.userInfo = res.data.userInfo
      },
      fail: err => {
        console.error(err)
        wx.showToast({
          title: '网络错误,请稍后重试',
          icon: 'none'
        })
      },
      complete: () => {
        this.setData({
          isDisabled: false
        })
      }
    })
  },

  // 生命周期函数:页面
继续输出
U

// 加载完成
  onLoad: function() {
    // 检查用户是否已登录,如果未登录则跳转到登录页面
    if (!app.globalData.userInfo) {
      wx.navigateTo({
        url: '/pages/login/login'
      })
      return
    }

    // 初始化抽奖次数和中奖结果
    this.setData({
      lotteryTimes: app.globalData.userInfo.lotteryTimes,
      lotteryResult: null
    })
  }
})

index.wxml

<view class="container">
  <view class="lottery">
    <image class="pointer {{isRotating ? 'rotating' : ''}}" src="/images/pointer.png" bindtap="lottery" disabled="{{isDisabled}}"></image>
  </view>
  
  <view class="result" wx:if="{{lotteryResult}}">
    <text>恭喜你获得{{lotteryResult}}</text>
  </view>
  
  <view class="times">
    <text>你还有{{lotteryTimes}}次抽奖机会</text>
  </view>
</view>

<style lang="scss">
.container {
  display: flex;
  flex-direction: column;
}

.lottery {
  position: relative;
}

.pointer {
  width: 100%;
}

.pointer.rotating {
  animation-name: rotate;
  animation-duration: 5s;
}

@keyframes rotate {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.result, .times {
  text-align: center;
}
</style>

在以上代码中,我们使用了微信提供的 wx.login 接口获取用户登录凭证,并将其发送到后台服务器进行验证。如果验证通过,则保存用户信息并跳转到首页。在首页中,我们使用 wx.checkSession 接口检查用户登录状态是否失效,并在抽奖事件处理函数中向后台服务器发送请求并获取中奖结果。同时,我们还添加了一些动画效果来增加交互体验。

需要注意的是,以上代码仅为示例,实际应用中可能需要根据具体情况进行调整和优化。

uni-app——规格选择判断库存(类似电商商品加购)

<template>
    <view class="detail_page" v-cloak :class="isShowPopup? 'popup-show': ''">
        <navBar :title="topInfo.title" :url="topInfo.url" :icon_title="topInfo.icon_title" :type="topInfo.type">
        </navBar>
        <view class="pages" v-cloak>
            <view class="info scroll_item" id="scroll0">
                <view class="banner_top">
                    <swiper :swiperConfig="swiperConfig"></swiper>
                </view>
                <view class="page_info page_item">
                    <view class="price">
                        <text class="large">{{listData.price}}</text>
                        元起
                    </view>
                    <view class="title">{{listData.name}}</view>
                    <view class="sub_title">强效清洗,全面爱家,重新焕发地毯新生</view>
                </view>
                <view class="form_box page_item">
                    <uni-forms ref="signUpform" :value="signUpformData" :rules="rules">
                        <uni-forms-item label="小区" name="housing_id" style="display: none;"></uni-forms-item>
                        <uni-forms-item label="地址" name="user_address_id" @tap="goAddress">
                            <text class="picker_lable">{{address}}</text>
                        </uni-forms-item>
                        <uni-forms-item label="规格" name="flag" @tap="chorceSpecs">
                            <text class="picker_lable">{{specs}}</text>
                        </uni-forms-item>
                        <uni-forms-item label="时间" name="start_time" @tap="openDatetimePicker">
                            <text class="picker_lable">{{signUpformData.start_time}}</text>
                        </uni-forms-item>
                    </uni-forms>
                </view>
            
            
            </view>
            
            <view class="details scroll_item " id="scroll1" style="padding-bottom:80px;">
                <view style="color: #a29696;margin-bottom: 20rpx; text-align: center;">——详情——</view>
                <view class="page_detail page_item" v-html="detail_content" style="margin-bottom:70px;">
                    {{detail_content}}
                </view>
            </view>    
            
            <view class="footer">
                <view>
                    <image class="service" mode="aspectFit" @tap="callPhone" src="../../static/images/service.png">
                    </image>
                    <view class="byButton" form-type="submit" @tap="handleBuy">立即购买</view>
                </view>
            </view>
        </view>

        <!-- 页面滚动到详情时再显示锚点 -->
        <view class="fixedtop" v-show="scrollDistance > 100">
            <view class="fixedtop_box">
                <view v-for="(item,index) in fixedList" :key="index" :class="{'active':currentIndex == index}"
                    @tap="changeactive(index)">{{item.name}}
                </view>
            </view>
        </view>
        <!-- 规格 -->
        <uni-popup ref="popup" type="bottom" :mask-click="false">
            <view class="specs_box spec-shade">
                <view class="specs_box_box">
                    <view class="title">
                        <text></text>
                        <text class="title">请选择服务规格</text>
                        <!--   <text @click="closeProp"
                               class="iconfont icon-close"></text> -->
                        <text></text>
                    </view>
                    <view class="spec-cont">
                        <view class="goods-choose-show flex-star">
                            <view class="goods-choose-show-right" v-if="currentItem">
                                <p>¥{{currentItem.price || 0}}</p>
                                <view>库存{{currentItem.all_count || 0}}件</view>
                                <!-- <view>{{specShowString}}</view> -->
                            </view>
                        </view>
                        <view class="spec-linebox" style="max-height: 550rpx;overflow-y: scroll;">
                            <view class="spec-item" v-for="(skuItem,skuIndex) in skuInfo">
                                <p>{{skuItem.title}}</p>
                                <view class="item-cont flex-star">
                                    <span v-for="(item,index) in skuItem.option"
                                        :class="[item.isShow ? '' : 'noProduct',subIndex[skuIndex] == item.id ? 'act' : '']"
                                        @click="item.isShow ? specificationBtn(item.info,skuIndex,item.id) : disabled">{{item.info}}</span>
                                </view>
                            </view>
                        </view>
                    </view>
                    <button class="confirm" @click="confirmSpec">确定</button>
                </view>
            </view>
        </uni-popup>

        <!-- 时间 -->
        <SimpleDateTimePicker ref="myPicker" @submit="handleSubmit" :start-year="year" :end-year="year+20" />
    </view>

</template>

<script>
    import navBar from "@/components/navBar/navBar.vue"
    import swiper from "@/components/swiper/swiper.vue"
    import forms from "@/components/uni-forms/uni-forms.vue"
    import formItems from "@/components/uni-forms-item/uni-forms-item.vue"
    import SimpleDateTimePicker
    from "uni_modules/buuug7-simple-datetime-picker/components/buuug7-simple-datetime-picker/buuug7-simple-datetime-picker.vue";
    import popup from "@/components/uni-popup/uni-popup.vue"
    import {
        mapMutations
    } from 'vuex';

    export default {
        components: {
            navBar,
            swiper,
            formItems,
            forms,
            SimpleDateTimePicker,
            popup
        },

        data() {
            return {
                isShowPopup: false,
                payParams: 0,
                goods_id: 0,
                isInit: 0, // 默认只显示第一组规格
                allCount_id: 0, // 库存为0的id
                stockIndex: 0, //库存为0的id组
                stock_flag: [],
                getSpecs: [],
                topInfo: {
                    url: "../../pages/index/index",
                    title: "预约详情",
                    icon_title: "返回",
                    type: 'tab'
                },
                token: "",
                year: "",
                listData: {},
                swiperConfig: {
                    indicatorDots: true,
                    vertical: false,
                    autoplay: true,
                    interval: 2000,
                    duration: 600,
                    bannerList: [],
                    swiperH_height: "400rpx"
                },
                detail_content: "", //详情内容
                specs: "请选择规格",
                address: "请选择服务地址",
                signUpformData: {
                    user_address_id: "",
                    housing_id: "",
                    flag: "",
                    start_time: "请选择服务时间"
                },
                currentIndex: 0,
                fixedList: [{
                        name: "商品",
                        targetDom: ".info"
                    },
                    {
                        name: "详情",
                        targetDom: ".details"
                    }
                ], // 固定顶部锚点链接
                rules: {
                    address: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务地址"
                        }]
                    },
                    type: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务规格"
                        }]
                    },
                    serviceTime: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务时间"
                        }]
                    }
                },
                elHeight: "",
                scrollDistance: 0,
                doms: "",
                topList: [],
                multiIndex: 0,
                specsList: [],
                isShow: false,
                selectArr: [],
                subIndex: [],
                currentItem: {
                    flag: '',
                    price: 0,
                    all_count: 0,
                    title: ""
                },
                skuInfo: [],
                specShowString: '选择规格',
                goodsData: {
                    priceInfo: [],
                    SKUInfo: [],
                },
                category_type: 0,// 分类id(只针对垃圾回收)
            }
        },

        onLoad(option) {
            console.log('下单确定地址', option);
            /* 获取当前年份 */
            let date = new Date();
            this.year = date.getFullYear();
            /* 设置页面滚动高度 */
            let screenH = uni.getSystemInfoSync().screenHeight;
            this.elHeight = screenH;


            let loginRes = this.checkLogin();
            if (!loginRes) {
                return false;
            } else {
                /* 初始化页面 */
                if (option.id) {
                    uni.setStorageSync("goods_id", option.id);
                }
                if(option.category_type){
                    uni.setStorageSync("category_type", option.category_type);
                }
                this.token = uni.getStorageSync("token");
                this.goods_id = uni.getStorageSync("goods_id");
                this.category_type = uni.getStorageSync("category_type");
            }

            // this.firstStock();
            this.getStock();
            this.getInfo();

            /* 选择地址 */
            if (option.address_id) {
                this.signUpformData.user_address_id = option.address_id;
                this.address = option.address;

            }
            /* 小区id */
            if (option.housing_id) {
                this.signUpformData.housing_id = option.housing_id;
            }


        },
    
        methods: {
            getStock() {
                let _param = {};
                _param.operate = "order.get_price",
                    _param.goods_id = this.goods_id;
                _param.token = this.token;
                _param.flag = [0];

                this.$myRequset({
                    url: "/api?operate=goods.get_price",
                    method: "POST",
                    data: _param,
                }).then((res) => {
                    this.goodsData.priceInfo = res.data.data;
                    // console.log('获取价格', this.goodsData.priceInfo);
                });
            },
            getInfo() {
                this.$myRequset({
                    url: "/api?operate=goods.info",
                    method: "POST",
                    data: {
                        token: this.token,
                        goods_id: this.goods_id
                    },
                }).then((res) => {
                    this.swiperConfig.bannerList = res.data.data.album_images;
                    this.listData.name = this.topInfo.title = res.data.data.name;
                    this.listData.price = res.data.data.price;
                    this.detail_content = res.data.data.content;
                    this.goodsData.SKUInfo = res.data.data.spec_config;
                    this.skuInfo = this.goodsData.SKUInfo;
                    if(this.skuInfo){
                        this.skuInfo.forEach(item => {
                            item.option.forEach(specItem => {
                                specItem.isShow = true;
                            })
                        })
                    }
                    // console.log('规格列表', this.goodsData.SKUInfo);
                    // console.log('规格列表_skuInfo', this.skuInfo);
                });

            },
            disabled() {
                uni.showToast({
                    title: "不可点击"
                })
            },
            /* 规格 */
            chorceSpecs() {
                setInterval(function() {
                    uni.hideKeyboard(); //隐藏软键盘
                }, 10);
                if (!this.signUpformData.user_address_id) {
                    uni.showToast({
                        title: "请先选择地址",
                        icon: "none"
                    })
                } else if (this.specsList) {
                    this.$refs.popup.open();
                    this.isShowPopup = true;
                } else {
                    uni.showToast({
                        title: "暂无规格可选",
                        icon: "none"
                    })
                }
            },
            closeProp() {
                if (this.subIndex.length == 0) {
                    uni.showToast({
                        icon: "error",
                        title: "请选择服务规格"
                    });
                } else {
                    this.$refs.popup.close();
                }
            },
            /* 确定规格 */
            confirmSpec() {
                console.log('当前选择', this.subIndex);
                console.log('当前选择', this.selectArr);
                // this.signUpformData.type = this.subIndex.toString(",");

                this.signUpformData.flag = this.subIndex;
                this.specs = this.specShowString;
                if (this.currentItem.price == 0) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择完整规格"
                    })
                } else {
                    this.$refs.popup.close();
                }
            },

            /**
             * @param {String} specName 当前点击规格按钮的值(黑色,35)
             * @param {Number} specIndex 选择的规格下标(例子中颜色是0,尺码是1)
             * @param {Number} specItemIndex 选择规格值id(例子中35下标是0)
             */
            specificationBtn(specName, specIndex, specItemIndex) {
                if (this.selectArr[specIndex] != specName) { //判断所选规格数组中是否包含当前点击规格
                    this.selectArr[specIndex] = specName; //如果没有则把当前规格添加
                    this.subIndex[specIndex] = Number(specItemIndex); //添加选中样式
                } else {
                    this.selectArr[specIndex] = '';
                    this.subIndex[specIndex] = -1; //去除样式
                }
                this.specShowString = this.spaceRemoveArr(this.selectArr).join(',') || '选择规格'; //所选规格页面中展示,数组为空则变为选择规格
                this.inventoryLookup(); //当规格选完后,去匹配
                this.clickPitch(); //库存判断,实现不可点击
            },
            spaceRemoveArr(arr) { //数组去除空字符串
                let tempArr = []
                arr.forEach(item => {
                    if (item) {
                        tempArr.push(item)
                    }
                })
                return tempArr;
            },
            /* 规格选完后,去匹配 */
            inventoryLookup() {
                try {
                    this.goodsData.priceInfo.forEach((item, index) => {
                        if (item.title == this.specShowString) {
                            this.currentItem = item;
                            this.listData.price = this.currentItem.price;
                            throw new Error();
                        } else {
                            this.currentItem = {
                                flag: '',
                                price: 0,
                                all_count: 0,
                                title: ""
                            };
                        }
                    })
                } catch (e) {}
            },
            /* 库存判断,实现不可点击 */
            clickPitch() {
                let result = [];
                // console.log('库存判断:',this.goodsData.SKUInfo);
                for (let i in this.goodsData.SKUInfo) {
                    result[i] = this.selectArr[i] ? this.selectArr[i] : '';
                }
                //最难理解的大概就是这里了,这里跟着循环里打印结果,多走几遍就大致明白了  假象.jpg
                for (let i in this.goodsData.SKUInfo) {
                    let last = result[i];
                    // console.log("最后点击======",last);
                    for (let k in this.goodsData.SKUInfo[i].option) {
                        result[i] = this.goodsData.SKUInfo[i].option[k].info;
                        // console.log('result--------', result, "last:", last);
                        this.skuInfo[i].option[k].isShow = this.isMay(result)
                    }
                    result[i] = last;
                }
                // console.log('库存结果111:',result);
            },
            isMay(result) {
                for (let i in result) {
                    if (result[i] == '') {
                        return true;
                    }
                }
                for (let i in this.goodsData.priceInfo) {
                    if (this.goodsData.priceInfo[i].title == result.join(",") && this.goodsData.priceInfo[i].all_count >
                        0) {
                        return true;
                    }
                }
            },
            goAddress() {
                console.log('goAddress');
                uni.redirectTo({
                    url: "../addressList/addressList"
                });
            },
            /* 时间 */
            openDatetimePicker() {
                if (!this.signUpformData.user_address_id) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择服务地址"
                    })
                } else if (!this.signUpformData.flag) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择服务规格"
                    })

                } else {
                    this.$refs.myPicker.show();
                }
            },
            /* 选择时间 */
            handleSubmit(e) {
                console.log('times', e);
                this.signUpformData.start_time = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}`;
            },
        // 锚点链接滚动监听
            onPageScroll(res){
                this.scrollDistance = res.scrollTop;
                // console.log('滚动距离',res.scrollTop);//距离页面顶部距离
                if(res.scrollTop >=600){
                    this.currentIndex = 1;
                }else{
                    this.currentIndex = 0;
                }
            },
                      /* 锚点点击*/          
            changeactive(index) {
                console.log('sdsd',index);
                if(index==1){
                    uni.pageScrollTo({
                        duration:300, // 毫秒
                        scrollTop:600 // 位置
                    });
                }else{
                    uni.pageScrollTo({
                        duration:300, // 毫秒
                        scrollTop:0 // 位置
                    });
                }
            },

            /* 表单提交 */
            handleBuy() {
                this.$refs.signUpform.validate().then(res => {
                    console.log('表单数据信息:', res);
                    let _param = res;
                    _param.operate = "wechat.miniapp";
                    _param.token = this.token;
                    _param.goods_id = this.goods_id;
                    
                    // 垃圾回收
                    if(this.category_type == 21){
                        _param.category_type = this.category_type;
                    }
                    console.log('(_param.flag', typeof _param.flag);
                    let _res = this.$myRequset({
                        url: "/api/pay/index",
                        method: "POST",
                        data: _param,
                    }).then((res) => {
                        console.log('_res', res);
                        if (res.data.code == 1) {
                            let signType = res.data.data.signType
                            let nonceStr = res.data.data.nonceStr;
                            let _package = res.data.data.package;
                            let paySign = res.data.data.paySign;
                            let timeStamp = res.data.data.timeStamp;

                            uni.requestPayment({
                                provider: 'wxpay',
                                timeStamp: timeStamp,
                                nonceStr: nonceStr,
                                package: _package,
                                signType: signType,
                                paySign: paySign,
                                success: function(res) {
                                    console.log('pay_success:' + JSON.stringify(res));
                                    uni.reLaunch({
                                        url: "../../pages/order/order"
                                    });
                                },
                                fail: function(err) {
                                    console.log('pay_fail:' + JSON.stringify(err));
                                    uni.reLaunch({
                                        url: "../../pages/order/order",
                                    });
                                }
                            });

                        } else {
                            uni.showToast({
                                icon: "none",
                                title: "请选择规格"
                            })
                            return false;
                        }

                    });


                }).catch(err => {
                    uni.showToast({
                        title: err[0].errorMessage,
                        icon: "none"
                    });
                })
            },
            /* 拨打电话 */
            callPhone() {
                uni.makePhoneCall({
                    phoneNumber: "15902341080"
                });

            },
        }
    }
</script>

https://www.cnblogs.com/LindaBlog/p/15570833.html