二维码扫描并输出信息(小程序,IOS,安卓)

js 复制代码
<template>
  <div>
    <van-sticky>
      <div class="header_box">
        <van-nav-bar :border="false" left-text="" left-arrow>
          <template #left>
            <van-icon name="arrow-left" size="22" @click="goto_out" />
          </template>
          <template #title>
            <span>123</span>
          </template>
          <template #right></template>
        </van-nav-bar>
      </div>
      <!-- 搜索-->

      <form action="">
        <van-search v-model.trim="vinNo" placeholder="请输入123" @search="onSearch">
          <template #left-icon>
            <van-icon name="scan" @click="btn_scancode" size="20px" />
          </template>
        </van-search>
      </form>


    </van-sticky>
    <!-- 123 -->
    <!-- 内容 开始 -->
    <div class="content">
      <!-- 提示 -->

      <div class="content_top" v-if="blackobj != null">
        <div class="content_top_img box_img">
          <img :src="blackobj.banner ? blackobj.banner : logoimg" alt="" srcset="">
        </div>
        <div style="margin-left: 5px;">
          <div style="font-size: 16px;padding: 0 0 5px 0;"> {{ vinNo }}</div>
          <div style="color: #A5B4DA;padding: 2px 0;"> {{ blackobj.sku }}</div>
          <div style="color: #A5B4DA;padding: 2px 0;"> {{ blackobj.bikeModel }}</div>
        </div>
      </div>



      <div class="content_bot">
        <FlexLinePI :title="'123'" :dropshow="true">
          <van-field v-model="remark" rows="3" autosize label="" type="textarea" placeholder="请填写123"
            style="border: 1px solid #ddd;border-radius: 10px;" />
        </FlexLinePI>
      </div>
      <div class="content_bot">
        <div style="margin: 10px 0;">
          <div style="font-size: 16px;padding:5px 0;">上传图片</div>
          <div
            style="width: 80px;height: 80px;float: left;margin: 0 10px 10px 0;position: relative;display: flex;justify-content: center;"
            v-for="(it, id) in filepictureList" :key="id" @click="looktype(it, 'img')">
            <img :src="it" alt="" style="max-width: 100%;max-height: 100%;">
            <div class="close" style="" @click.stop="delimg(id)"><van-icon name="cross" /></div>
          </div>
          <van-uploader :max-count="10" multiple accept=".jpg, .jpeg, .png" :after-read="afterReadImg"
            :max-size="10 * 1024 * 1024" @oversize="onOversize" v-if="filepictureList.length < 10" />
          <div style="color: #A5B4DA;width: 100%;display: flex;justify-content: flex-start;">*(JPEG,PEG,最大10M,最多10张)</div>
        </div>
      </div>
      <div class="content_bot">
        <div style="margin: 10px 0;">
          <div style="font-size: 16px;padding:5px 0;">上传视频</div>
          <div
            style="width: 80px;height: 80px;float: left;margin: 0 10px 10px 0;position: relative;display: flex;justify-content: center;"
            v-for="(it, id) in filevideoList" :key="id" @click="looktype(it, 'video')">
            <!-- :autoplay="false"  -->
            <video id="video" :autoplay="false" :controls="false" style="max-width: 100%;max-height: 100%;" :src="it" :poster="generatePosterUrl(it)">
              <!-- <source :src="it" type="video/mp4" />  -->
            </video>
            <!-- <img :src="logoimg" alt="" style="max-width: 100%;max-height: 100%;"> -->
            <div class="close" style="" @click.stop="delvideo(id)"><van-icon name="cross" /></div>
            <van-icon name="play-circle-o" class="open_video" size="30px" color="#fff" />
          </div>
          <van-uploader :max-count="5" multiple accept="video/*" :after-read="afterReadVideo" :max-size="50 * 1024 * 1024"
            @oversize="onOversizevideo" v-if="filevideoList.length < 5" />
          <div style="color: #A5B4DA;width: 100%;display: flex;justify-content: flex-start;">*(MP4,最大50M,最多5个)</div>
        </div>
      </div>
    </div>
    <!-- 内容 结束 -->
    <div class="bottom" style="justify-content: flex-end;">
      <van-button type="info" round size="normal" block style="width: 100%;margin: 0 auto;" @click="btn_from"
        class="">提交</van-button>
    </div>

    <!-- 弹框展示 图片 和视频 -->
    <van-overlay :show="show" @click="show = false">
      <div class="look_type">
        <img :src="content" alt="" v-if="contenttype == 'img'" style="max-width: 100%;max-height: 100%;">
        <video v-if="contenttype == 'video'" :autoplay="true" style="max-width: 100%;max-height: 100%;" :src="content"
          controls disablepictureinpicture></video>
      </div>
    </van-overlay>

    <van-overlay :show="upoadshow" @click="upoadshow = false" :close-on-click-overlay="false">
      <div class="upoadshow_type">
        <van-loading size="24px" vertical>上传中...</van-loading>
      </div>
    </van-overlay>
  </div>
</template>
<script>
import {
  compressImgNew
} from "@/assets/js/picture.js";
import { bikeinfo, fileSave } from '@/api/common.js'
import { flowsave, flowrupdate } from '@/api/index/index.js'
export default {
  data() {
    return {
      logoimg: require('../../../../static/images/back_list.png'),
      vinNo: '',

      blackobj: null,
      remark: "", //理由.
      // 图片信息
      filepictureList: [],
      // 视频信息
      filevideoList: [],

      // 二维码扫描
      html5Qrcode: null,
      error: '',
      isScaning: false,

      // 遮罩
      content: '', //内容
      contenttype: '',
      show: false,

      // 上传
      upoadshow: false
    }
  },
  components: {
  },
  mounted() {
    let _this = this;
    // ios
    window.giantapp_scan_callback = (res) => {
      _this.giantapp_scan_callback(res);
    };

    // 安卓
    window.onLoadQr = (res) => {
      _this.onLoadQr(res);
    };
  },
  computed: {},
  methods: {
    goto_out() {
      const _this = this;
      _this.$router.go(-1)
    },
    // 搜索
    onSearch(val) {
      const _this = this
      // _this.vinNo = val
      bikeinfo({ vinNo: _this.vinNo }).then(res => {
        if (res.status == 200) {
          if (typeof res.data != "object") {
            res.data = JSON.parse(res.data);
          }
          if (res.data.code == 200) {
            _this.blackobj = res.data.data
            _this.isScaning = false
          } else if (res.data.code == 0) {
            _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
          } else {
            _this.blackobj = null
            _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
          }
        } else {
          _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
        }
      })
        .catch(err => {
          _this.$toast('网络加载失败,请稍后再试');
        });
    },
    // 提交
    btn_from() {
      const _this = this;
      if (_this.blackobj == null) {
        _this.$toast('请扫码或搜索进行添加信息');
        return
      }

      if (_this.remark == '') {
        _this.$toast('请输入123');
        return
      }

      let parms = {
        images: _this.filepictureList,
        videos: _this.filevideoList,
        shopCode: _this.GLOBAL.loginUser.mainOrgCode,
        shopName: _this.GLOBAL.loginUser.mainOrgName,
        dealerCode: _this.GLOBAL.loginUser.dealercode,
        sbuCode: _this.GLOBAL.loginUser.sbucode,
        sku: _this.blackobj.sku,
        vinNo: _this.vinNo,
        bikeModel: _this.blackobj.bikeModel,
        banner: _this.blackobj.banner,
        remark: _this.remark,
        dealerName: _this.GLOBAL.loginUser.dealerName,
        sbuName: _this.GLOBAL.loginUser.sbuName,
        staffId: _this.GLOBAL.loginUser.staffId,
      }

      flowsave(
        parms
      ).then(res => {
        if (res.status == 200) {
          if (typeof res.data != "object") {
            res.data = JSON.parse(res.data);
          }
          if (res.data.code == 200) {
            _this.$router.push({
              path: "/",
            })
            _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
          } else {
            _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
          }
        } else {
          _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
        }
      })
        .catch(err => {
          _this.$toast('网络加载失败,请稍后再试');
        });
    },
    // 上传 ======================
    // 上传图片
    afterReadImg(file) {
      const _this = this;
      // let files = compressImgNew(file);
      _this.uploadfile(file, 'img')
    },
    // 上传视频
    afterReadVideo(file) {
      const _this = this;
      _this.uploadfile(file, 'video')
    },
    // 上传文件过大
    onOversize() {
      _this.$toast('图片不能大于10M');
    },
    // 上传文件过大
    onOversizevideo() {
      _this.$toast('图片不能大于50M');
    },

    // 删除图片
    delimg(id) {
      const _this = this;
      _this.filepictureList.splice(id, 1)
    },
    // 删除视频
    delvideo(id) {
      const _this = this;
      _this.filevideoList.splice(id, 1)
    },
    // 上传发布
    uploadfile(file, type) {
      const _this = this;
      _this.upoadshow = true
      let formdata = new FormData();
      formdata.append("file", file.file);
      _this.axios.post(_this.GLOBAL.opo_gcross_api + '/crossSend/fileSave', formdata).then(function (res) {
        if (res.status == 200) {
          if (typeof res.data != "object") {
            res.data = JSON.parse(res.data);
          }
          if (res.data.code == 200) {
            if (type == 'img') {
              _this.filepictureList = _this.filepictureList.concat(res.data.data)
            } else {
              _this.filevideoList = _this.filevideoList.concat(res.data.data)
            }
            _this.upoadshow = false
          } else {
            _this.upoadshow = false
            _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
          }
        } else {
          _this.upoadshow = false
          _this.$toast(res.data.msg ? res.data.msg : '网络加载失败,请稍后再试');
        }
      })
    },
    // 视频封面
    generatePosterUrl(videoUrl) {
      // 在这里,你可以使用视频链接 `videoUrl` 来生成封面图像的URL
      // 这个例子中使用了指定尺寸为 80x80 的缩略图
      return `${videoUrl}?vframe/jpg/offset/10/w/80px/h/80px`;
    },
    // 查看信息
    looktype(it, type) {
      const _this = this;
      _this.show = true
      _this.content = it
      _this.contenttype = type
    },
    // 扫描 ==================
    //扫码功能
    btn_scancode() {
      const _this = this;
      if (_this.browser['wx']) {
        _this.axios
          .post(
            "https://wechat.giant.com.cn/third/wechat.ashx?action=jspack2",
            _this.qs.stringify({
              apiname: "Giant",
              apipwd: "Dline!@1587",
              wxname: "giantfwh",
              url: location.href.split("#")[0],
            })
          )
          .then(function (res) {
            var fetch_data = res.data.jspack;
            wx.config({
              debug: false,
              appId: fetch_data.appId, // 必填,公众号的唯一标识
              timestamp: fetch_data.timeStamp, // 必填,生成签名的时间戳
              nonceStr: fetch_data.nonceStr, // 必填,生成签名的随机串
              signature: fetch_data.signatureStr, // 必填,签名
              jsApiList: ["scanQRCode"], // 必填,需要使用的JS接口列表
            });

            wx.ready(function () {
              // config信息验证成功后会执行ready方法,所有接口调用都必须在config接口获得结果之后
              // config 是一个客户端的异步操作,所以如果需要在页面加载时调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行.对于用户触发是才调用的接口,则可以直接调用,不需要放在ready函数中
              wx.checkJsApi({
                // 判断当前客户端版本是否支持指定JS接口
                jsApiList: ["scanQRCode"],
                success: function (res) {
                  // 以键值对的形式返回,可用true,不可用false。如:{"checkResult":{"scanQRCode":true},"errMsg":"checkJsApi:ok"}
                  if (res.checkResult.scanQRCode === true) {
                    wx.scanQRCode({
                      // 微信扫一扫接口
                      desc: "scanQRCode desc",
                      needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                      scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
                      success: function (res) {
                        // const value = res.resultStr.split('/').pop();

                        // _this.onSearch(value)
                        // console.log(res,123123)
                        let url_type = 0;
                        if (
                          res.resultStr.indexOf("https://") == 0 ||
                          res.resultStr.indexOf("http://") == 0
                        ) {
                          if (res.resultStr.indexOf("giant.com.cn") == -1) {
                            url_type = 1;
                          }
                          if (res.resultStr.indexOf("qrgiant.com") == -1) {
                            url_type = 1;
                          }
                          if (res.resultStr.indexOf("qrgiant.cn") != -1) {
                            url_type = 1;
                          }
                        } else {
                          url_type = 1;
                        }

                        if (!url_type) {
                          _this.$dialog
                            .alert({
                              title: "提示",
                              message:
                                "您购买的产品可能属于假冒伪劣产品,请与门店确认",
                              confirmButtonText: "我知道了",
                              confirmButtonColor: "#4E66FF",
                              showCancelButton: false,
                            })
                            .then(() => { })
                            .catch(() => { });
                          return false;
                        }

                        const getCode = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                        let url_index = res.resultStr.lastIndexOf("/");
                        _this.vinNo = res.resultStr.substring(
                          url_index + 1,
                          res.length
                        );
                        _this.onSearch()
                      },
                    });
                  } else {
                    alert("抱歉,当前客户端版本不支持扫一扫");
                  }
                },
                fail: function (res) {
                  // 检测getNetworkType该功能失败时处理
                  alert("fail" + res);
                },
              });
            });

            /* 处理失败验证 */
            wx.error(function (res) {
              // config 信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
              alert("配置验证失败: " + res.errMsg);
            });
          })
          .catch(function (error) {
            _this.$toast("出现了一些问题:" + error);
          });
      } else if (_this.browser['giantapp']) {
        location.href = "ridelifegc://qrcode/scan";
      } else if (_this.browser['giantopoapp']) {
        if (_this.browser['ios']) {
          window.webkit.messageHandlers.toQr.postMessage("");
        } else {
          android.toQr();
        }
      } else {
        _this.$toast(
          "请在微信端或者捷安特O+O经营助手APP与捷安特骑行APP环境下使用"
        );
        return false;
      }
    },
    giantapp_scan_callback(res) {
      const _this = this;

      let url_type = 0;

      if (res.indexOf("https://") == 0 || res.indexOf("http://") == 0) {
        if (res.indexOf("giant.com.cn") != -1) {
          url_type = 1;
        }
        if (res.indexOf("giantqrcode.kssina.com") != -1) {
          url_type = 1;
        }
        if (res.indexOf("qrgiant.com") != -1) {
          url_type = 1;
        }
        if (res.indexOf("qrgiant.cn") != -1) {
          url_type = 1;
        }
      } else {
        url_type = 1;
      }

      if (!url_type) {
        _this.$dialog
          .alert({
            title: "提示",
            message: "您购买的产品可能属于假冒伪劣产品,请与门店确认",
            confirmButtonText: "我知道了",
            confirmButtonColor: "#4E66FF",
            showCancelButton: false,
          })
          .then(() => { })
          .catch(() => { });
        return false;
      }

      let url_index = res.lastIndexOf("/");
      _this.vinNo = res.substring(url_index + 1, res.length);
      _this.onSearch()

      //_this.$router.push({ path: '/partsview', query: { vin: vinno, vintype: 1 } });
    },
    onLoadQr(res) {
      const _this = this;
      /**
       
       * 生成二维码链接(正式环境):http://qrgiant.com/t0123456788
          生成二维码链接(测试环境):https://giantqrcode.kssina.com/t0123456788
       */

      let url_type = 0;

      if (res.indexOf("https://") == 0 || res.indexOf("http://") == 0) {
        if (res.indexOf("giant.com.cn") != -1) {
          url_type = 1;
        }
        if (res.indexOf("giantqrcode.kssina.com") != -1) {
          url_type = 1;
        }
        if (res.indexOf("qrgiant.com") != -1) {
          url_type = 1;
        }
        if (res.indexOf("qrgiant.cn") != -1) {
          url_type = 1;
        }
      } else {
        url_type = 1;
      }

      if (!url_type) {
        _this.$dialog
          .alert({
            title: "提示",
            message: "您购买的产品可能属于假冒伪劣产品,请与门店确认",
            confirmButtonText: "我知道了",
            confirmButtonColor: "#4E66FF",
            showCancelButton: false,
          })
          .then(() => { })
          .catch(() => { });
        return false;
      }

      let url_index = res.lastIndexOf("/");
      _this.vinNo = res.substring(url_index + 1, res.length);
      _this.onSearch()
    },
  },
}
</script>
<style lang='less' scoped>
/deep/ .van-dropdown-menu__bar {
  box-shadow: none;
}

.title_prompt {
  background: #FFFBF3;
  color: #DD9E1E;
  border-radius: 10px;
  padding: 10px;
  margin: 0 0 10px 0;
}

.content {
  padding: 10px;
  margin-bottom: 60px;

  .content_top {
    display: flex;
    background: #fff;
    border-radius: 10px;
    padding: 10px;

    .content_top_img {
      width: 100px;
      height: 100px;
    }
  }

  .content_bot {
    background: #fff;
    border-radius: 10px;
    margin: 10px 0;
    padding: 0 10px 10px 10px;
  }
}


.line_radios {
  display: inline-block;
  margin: 5px 0;
  color: #DD9E1E;
  border: 1px solid #DD9E1E;
  border-radius: 50px;
  width: 20px;
  height: 20px;
  line-height: 17px;
  text-align: center;
}

.container {
  height: 100%;
  width: 100%;
}

.qrcode {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 999;
  background-color: rgba(0, 0, 0, 0.48);

  .close_icon {
    position: absolute;
    right: 10px;
    top: 10px;
  }
}

#reader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}


.wrapper {
  position: relative;
  height: 100%;
}


.look_type {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}




/* 隐藏视频控件 */
.content_bot video::-webkit-media-controls {
  display: none !important;
}

.custom-video-controls button {
  /* 样式化自定义按钮 */
  /* 请根据需要自定义按钮的样式 */
}
</style>
相关推荐
m0_748247551 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
Kika写代码1 小时前
【微信小程序】页面跳转基础 | 我的咖啡店-综合实训
服务器·微信小程序·小程序
m0_748255022 小时前
前端常用算法集合
前端·算法
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2342 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
源码哥_博纳软云3 小时前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络3 小时前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
如若1233 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~4 小时前
npm error code ETIMEDOUT
前端·npm·node.js