feat(uniapp_v2): 二开功能迁移与小程序主包优化
- 从 uniapp 迁移 HJF 页面、API、组件及用户/订单相关改动 - queue、assets 使用独立分包以降低主包体积 - 修复首页单根节点与支付结果页 v-if 链 - 关闭 HjfDemoPanel 全局注册;uniNoticeBar 注释 $getAppWebview 避免 __webviewId__ 报错 - 配置域名与 manifest 应用名称;cache/store 防御性处理 Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
<script>
|
||||
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
|
||||
export default {
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
cateList:{
|
||||
type:Array,
|
||||
default: () => []
|
||||
},
|
||||
brandList:{
|
||||
type:Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
cateGoryList:[],
|
||||
brand_id: [],
|
||||
cateId:[],
|
||||
sid:''
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
cateList:{
|
||||
handler(val){
|
||||
this.cateGoryList = val;
|
||||
this.cateGoryList.map(item=>{
|
||||
this.$set(item,'more', true);
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
fixedTop() {
|
||||
// #ifdef MP || APP-PLUS
|
||||
return uni.getWindowInfo().statusBarHeight
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
return 20
|
||||
// #endif
|
||||
},
|
||||
},
|
||||
components: {
|
||||
baseDrawer
|
||||
},
|
||||
methods: {
|
||||
closeDrawer() {
|
||||
this.$emit('closeDrawer');
|
||||
},
|
||||
checkBrand(item){
|
||||
if(this.brand_id.includes(item.id)){
|
||||
this.brand_id = this.brand_id.filter(function (ele){return ele != item.id;});
|
||||
}else{
|
||||
this.brand_id.push(item.id);
|
||||
}
|
||||
},
|
||||
checkCate(item){
|
||||
this.sid = item.id;
|
||||
},
|
||||
checkMore(item){
|
||||
item.more = !item.more
|
||||
},
|
||||
confirmFilter(){
|
||||
let data = {
|
||||
brand_id: this.brand_id.join(','),
|
||||
sid: this.sid
|
||||
};
|
||||
this.$emit('filterChange',data);
|
||||
},
|
||||
resetFilter(){
|
||||
this.brand_id = [];
|
||||
this.sid = '';
|
||||
let data = {
|
||||
brand_id: '',
|
||||
sid: ''
|
||||
};
|
||||
this.$emit('filterChange',data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<view>
|
||||
<base-drawer mode="right" :visible="visible" background-color="transparent" mask maskClosable
|
||||
@close="closeDrawer">
|
||||
<view class="drawer_box bg--w111-fff px-32 h-full">
|
||||
<scroll-view scroll-y="true" style="height: 100vh;">
|
||||
<view :style="{height:fixedTop + 'px'}"></view>
|
||||
<view class="h-80 flex-center fs-34 fw-500 text--w111-333">筛选</view>
|
||||
<view class="activity_box py-24">
|
||||
<view v-if="brandList.length">
|
||||
<view class="fs-28 text--w111-333 fw-500 mt-24">品牌</view>
|
||||
<view class="grid-column-3 box_gap mt-24">
|
||||
<view class="h-56 rd-28rpx bg--w111-f5f5f5 flex-center fs-24 text--w111-333"
|
||||
v-for="item in brandList" :key="item.id"
|
||||
:class="{active: brand_id.includes(item.id)}"
|
||||
@tap="checkBrand(item)">
|
||||
<text class="inline-block w-full line1 px-12 text-center">{{item.brand_name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="cateGoryList.length">
|
||||
<view class="fs-28 text--w111-333 fw-500 mt-48">分类</view>
|
||||
<view v-for="(item,i) in cateGoryList" :key="i">
|
||||
<view class="flex-between-center mt-48">
|
||||
<text class='fs-24'>{{item.cate_name}}</text>
|
||||
<view class="flex-y-center fs-20 text--w111-999 lh-34rpx" @tap="checkMore(item)">
|
||||
<text>{{ item.more ? '收起' : '展开' }}</text>
|
||||
<text class="iconfont fs-20" :class="item.more ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-column-3 box_gap mt-24" v-show="item.more">
|
||||
<view class="h-56 rd-28rpx bg--w111-f5f5f5 flex-center fs-24 text--w111-333"
|
||||
v-for="(cate,k) in item.children" :key="k"
|
||||
:class="{active: cate.id == sid}"
|
||||
@tap="checkCate(cate)">
|
||||
<text class="inline-block w-full line1 px-12 text-center">{{cate.cate_name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="pb-safe">
|
||||
<view class="h-112"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="fixed-lb pb-safe bg--w111-fff w-full">
|
||||
<view class="px-32 flex-between-center h-112">
|
||||
<view class="w-296 h-72 rd-40rpx flex-center text-mer con_border bg--w111-fff"
|
||||
@tap="resetFilter()">重置</view>
|
||||
<view class="w-296 h-72 rd-40rpx flex-center text--w111-fff mer-bg" @tap="confirmFilter()">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-drawer>
|
||||
</view>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
.drawer_box {
|
||||
width: 668rpx;
|
||||
border-radius: 40rpx 0 0 40rpx;
|
||||
overflow: auto;
|
||||
}
|
||||
.box_gap {
|
||||
grid-row-gap: 24rpx;
|
||||
grid-column-gap: 26rpx;
|
||||
}
|
||||
.con_border{
|
||||
border: 1rpx solid $primary-merchant;
|
||||
}
|
||||
.active{
|
||||
border: 1px solid $primary-merchant;
|
||||
color: $primary-merchant;
|
||||
background: $light-primary-merchant;
|
||||
}
|
||||
.text-mer{
|
||||
color: $primary-merchant;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,46 @@
|
||||
<script>
|
||||
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
|
||||
export default {
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
ensureInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseDrawer
|
||||
},
|
||||
methods: {
|
||||
closeDrawer() {
|
||||
this.$emit('closeDrawer');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<view>
|
||||
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
|
||||
<view class="w-full bg--w111-fff rd-t-40rpx py-32">
|
||||
<view class="text-center fs-32 text--w111-333 fw-500 mb-34">服务</view>
|
||||
<scroll-view scroll-y="true" class="h-400">
|
||||
<view class="px-32">
|
||||
<view class="mb-38" v-for="(item, index) in ensureInfo.ensure" :key="index">
|
||||
<view class="flex-y-center">
|
||||
<image class="w-34 h-34" :src="item.image"></image>
|
||||
<text class="pl-12 text--w111-333 fs-28 fw-500">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="mt-6 pl-40 fs-22 text--w111-999">{{ item.desc }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="mx-20 pb-safe">
|
||||
<view class="mt-52 h-72 flex-center rd-36px mer-bg fs-26 text--w111-fff" @click="closeDrawer">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-drawer>
|
||||
</view>
|
||||
</template>
|
||||
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<base-drawer mode="bottom" :visible="attr.cartAttr" background-color="transparent" zIndex="3000" mask maskClosable
|
||||
@close="closeDrawer">
|
||||
<view>
|
||||
<view class="bg--w111-fff rd-t-40rpx">
|
||||
<view class="w-full pt-32">
|
||||
<view class="px-32 flex">
|
||||
<image class="w-180 h-180 rd-16rpx" :src="attr.productSelect.image" @tap="showImg"></image>
|
||||
<view class="pl-24">
|
||||
<baseMoney :money="attr.productSelect.channel_price" symbolSize="32" integerSize="48"
|
||||
decimalSize="32" color="#FF7E00" weight></baseMoney>
|
||||
<view class="mt-20 fs-24 text--w111-999">库存:{{ attr.productSelect.stock }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="px-32" scroll-y="true" style="max-height: 400rpx;">
|
||||
<view class="item mt-32" v-for="(item, indexw) in attr.productAttr" :key="indexw">
|
||||
<view class="fs-28">{{ item.attr_name }}</view>
|
||||
<view class="flex-y-center flex-wrap">
|
||||
<view class="sku-item" :class="item.index === itemn.attr ? 'active' : ''"
|
||||
v-for="(itemn, indexn) in item.attr_value" @click="tapAttr(indexw, indexn)"
|
||||
:key="indexn">
|
||||
{{ itemn.attr }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="flex-between-center px-32 mt-24">
|
||||
<text class="fs-28">数量</text>
|
||||
<view class="flex-y-center">
|
||||
<view class="jia-btn w-84 h-48 flex-center" @click="CartNumAdd(false)">
|
||||
<text class="iconfont icon-ic_Reduce fs-24"></text>
|
||||
</view>
|
||||
<view class='w-84 h-48 text-center lh-48rpx bg--w111-f5f5f5'>{{ attr.productSelect.cart_num }}</view>
|
||||
<view class="jia-btn w-84 h-48 flex-center" @click="CartNumAdd(true)">
|
||||
<text class="iconfont icon-ic_increase fs-24"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mx-20 pb-box">
|
||||
<view class="mt-52 h-72 flex-center rd-36px mer-bg fs-26 text--w111-fff" @click="confirmCartAdd"
|
||||
v-if="attr.productSelect.stock">
|
||||
确定</view>
|
||||
<view class="mt-52 h-72 flex-center rd-36px bg-gray fs-26 text--w111-fff" v-else>已售罄</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-drawer>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props:{
|
||||
attr: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
storeInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
CartNumAdd(type){
|
||||
this.$emit('ChangeCartNum', type);
|
||||
},
|
||||
closeDrawer(){
|
||||
this.$emit('myevent');
|
||||
},
|
||||
confirmCartAdd(){
|
||||
this.$emit('onConfirm');
|
||||
},
|
||||
tapAttr: function(indexw, indexn) {
|
||||
let that = this;
|
||||
that.$emit("attrVal", {
|
||||
indexw: indexw,
|
||||
indexn: indexn
|
||||
});
|
||||
this.$set(this.attr.productAttr[indexw], 'index', this.attr.productAttr[indexw].attr_values[indexn]);
|
||||
let value = that
|
||||
.getCheckedValue()
|
||||
.join(",");
|
||||
that.$emit("ChangeAttr", value);
|
||||
|
||||
},
|
||||
//获取被选中属性;
|
||||
getCheckedValue: function() {
|
||||
let productAttr = this.attr.productAttr;
|
||||
let value = [];
|
||||
for (let i = 0; i < productAttr.length; i++) {
|
||||
for (let j = 0; j < productAttr[i].attr_values.length; j++) {
|
||||
if (productAttr[i].index === productAttr[i].attr_values[j]) {
|
||||
value.push(productAttr[i].attr_values[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
showImg(){
|
||||
this.$emit('getImg');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.sku-item {
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
border: 1px solid #F2F2F2;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
padding: 0 44rpx;
|
||||
border-radius: 28rpx;
|
||||
margin: 24rpx 0 0 16rpx;
|
||||
background-color: #F2F2F2;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: $primary-merchant;
|
||||
background: $light-primary-merchant;
|
||||
border-color: $primary-merchant;
|
||||
}
|
||||
.pb-box{
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
.bg-gray{
|
||||
background-color: #ccc;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<!-- 产品参数 -->
|
||||
<base-drawer mode="bottom" :visible="specsInfo.show" background-color="transparent" mask maskClosable @close="closeSpecs">
|
||||
<view class="w-full bg--w111-fff rd-t-40rpx py-32">
|
||||
<view class="text-center fs-32 text--w111-333 fw-500 mb-34">参数</view>
|
||||
<scroll-view scroll-y="true" class="h-400">
|
||||
<view class="px-32 scroll-content">
|
||||
<view class="item flex break_word" v-for="(item,index) in specsInfo.specs" :key="index">
|
||||
<view class="w-160 text--w111-999 mr-12">{{item.name}}</view>
|
||||
<view class="flex-1">{{item.value}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="mx-20 pb-safe">
|
||||
<view class="mt-52 h-72 flex-center rd-36px mer-bg fs-26 text--w111-fff" @click="closeSpecs">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</base-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
|
||||
export default {
|
||||
props: {
|
||||
specsInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
baseDrawer
|
||||
},
|
||||
methods: {
|
||||
closeSpecs() {
|
||||
this.$emit('myevent');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.item ~ .item{
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<!-- 底部导航 -->
|
||||
<keep-alive>
|
||||
<view class="page-footer">
|
||||
<view class="foot-item" :class="item.pagePath == activeRouter?'active':''"
|
||||
v-for="(item,index) in footerList" :key="index" @click="goRouter(item)">
|
||||
<block v-if="item.pagePath == activeRouter">
|
||||
<image :src="item.selectedIconPath"></image>
|
||||
<view class="txt">{{item.text}}</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<image :src="item.iconPath"></image>
|
||||
<view class="txt">{{item.text}}</view>
|
||||
</block>
|
||||
<uni-badge v-if="index == 1 && cartNum > 0" class="badge-style" :text="cartNum" absolute="rightTop"></uni-badge>
|
||||
</view>
|
||||
</view>
|
||||
</keep-alive>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import {getCartCounts} from '@/api/order.js';
|
||||
export default {
|
||||
name: 'footer',
|
||||
props: {},
|
||||
created() {
|
||||
let routes = getCurrentPages(); //获取当前打开过的页面路由数组
|
||||
let curRoute = routes[routes.length - 1].route //获取当前页面路由
|
||||
this.activeRouter = '/' + curRoute
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isLogin', 'cartNum']),
|
||||
styleType(){
|
||||
return this.$store.state.app.system_channel_style;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeRouter:'',
|
||||
footerList:[
|
||||
{
|
||||
pagePath: "/pages/merchant/index/index",
|
||||
iconPath: require("../../static/1-0.png"),
|
||||
selectedIconPath: require("../../static/1-1.png"),
|
||||
text: "首页"
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/merchant/cart/index",
|
||||
iconPath: require("../../static/2-0.png"),
|
||||
selectedIconPath: require("../../static/2-1.png"),
|
||||
text: "购物车"
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/merchant/user/index",
|
||||
iconPath: require("../../static/3-0.png"),
|
||||
selectedIconPath: require("../../static/3-1.png"),
|
||||
text: "我的"
|
||||
}
|
||||
],
|
||||
// cartNum:0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getCartNum();
|
||||
},
|
||||
methods: {
|
||||
goRouter(item) {
|
||||
var pages = getCurrentPages();
|
||||
var page = (pages[pages.length - 1]).$page.fullPath;
|
||||
if (item.pagePath == page) return
|
||||
|
||||
uni.redirectTo({
|
||||
url: item.pagePath,
|
||||
animationType: 'none' // 关闭默认的滑动效果
|
||||
});
|
||||
},
|
||||
getCartNum() {
|
||||
this.$store.dispatch('indexData/getCartNum')
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.page-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
height: calc(100rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
|
||||
height: calc(100rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
|
||||
box-sizing: border-box;
|
||||
border-top: solid 1rpx #F3F3F3;
|
||||
background-color: #fff;
|
||||
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
|
||||
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
|
||||
|
||||
.foot-item {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
padding: 0 20rpx;
|
||||
&.active {
|
||||
color: $primary-merchant;
|
||||
}
|
||||
}
|
||||
|
||||
.foot-item image {
|
||||
height: 40rpx;
|
||||
width: 40rpx;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.foot-item .txt {
|
||||
font-size: 20rpx;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
import CryptoJS from './crypto-js.js'
|
||||
/**
|
||||
* @word 要加密的内容
|
||||
* @keyWord String 服务器随机返回的关键字
|
||||
* */
|
||||
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
|
||||
var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||
var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
|
||||
return encrypted.toString();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user