HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

vite.js+vue3+electron12.0.4超清爽UI界面前端中后台管理系统

vuex Vue

上次有给大家分享一个Electron跨端仿抖音短视频项目,这次带来最新研发的vite.js+electron开发vue3中后台管理系统。

vite2-vue3-electronAdmin:一套基于electron+vite.js和element-plus组件库开发的客户端后台管理系统EXE。使用了最新的vue3全家桶技术,内置了 Vue-i18n 国际化解决方案,支持PC桌面端和平板自适应布局。

electron12 vite2.x仿制抖音短视频|直播聊天

img

基于最新的前端技术栈vite2+vue3全家桶+electron12+element-plus+echarts5开发而来。

img

技术栈

  • 编码器:VScode
  • 构建工具:Vitejs
  • vue3全家桶:Vue3.0+Vuex4+Vue-router@4
  • 跨端框架:Electron^12.0.4
  • 打包工具:vue-cli-plugin-electron-builder
  • UI组件库:element-plus^1.0.2 (饿了么vue3组件库)
  • 表格拖拽:Sortablejs^1.13
  • 图表组件:Echarts^5.1
  • 国际化:vue-i18n^9.1
  • 模拟请求:mockjs^1.1

img

特性

  • 使用最新前端技术栈开发
  • 支持桌面端及平板响应式布局
  • 支持组件式+指令式两种权限认证方式
  • 支持中英文/繁体国际化方案
  • 支持表格拖拽排序、全屏表格、树形表格等功能
  • 支持个性化换肤

img

项目结构

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

main.js配置

/**  
 * 渲染进程主入口  
 * @author XiaoYan  
 */  

import { createApp } from 'vue'  
import App from './App.vue'  
import Router from './router'  
import Store from './store'  

// 引入公共配置  
import gPlugins from './plugins'  

import { winCfg, loadWin } from './windows/actions'  

loadWin().then(config => {  
    winCfg.window = config  
    createApp(App)  
    .use(Router)  
    .use(Store)  
    .use(gPlugins)  
    .mount('#app')  
})

vue-router路由配置

项目中的路由采用了结构化分层加载,分为验证路由authRoutes.js和主模块路由mainRoutes.js两大部分。

/**  
 * 路由配置 Router util  
 * @author XiaoYan  
 */  

import { createRouter, createWebHashHistory } from "vue-router"  

import { ElLoading } from "element-plus"  
import { loginWin } from "@/windows/actions"  

import store from '@/store'  

// 导入公共模板/路由配置  
import mainLayout from "@/layouts/main"  
import authLayout from "@/layouts/auth"  
import mainRoutes from "@/layouts/main/routes.js"  
import authRoutes from "@/layouts/auth/routes.js"  

const RoutesLs = [  
    // 主页面模块  
    {  
        path: '/',  
        redirect: '/home/index',  
        component: mainLayout,  
        children: mainRoutes,  
    },  
    // 验证模块  
    {  
        path: '/auth',  
        redirect: '/auth/login',  
        component: authLayout,  
        children: authRoutes,  
    },  
    // 错误模块  
    {  
        path: '/:pathMatch(.*)*',  
        component: () => import('@/views/error/404.vue'),  
        meta: {  
            title: 'app__global-page-notfound',  
        }  
    }  
]  

const router = createRouter({  
    history: createWebHashHistory(),  
    routes: RoutesLs,  
})  

let loadingIns  
router.beforeEach((to, from, next) => {  
    // 开启加载提示  
    loadingIns = ElLoading.service({  
        lock: true,  
        text: 'Loading...',  
        spinner: 'el-icon-loading',  
        background: 'rgba(19, 209, 122, .1)'  
    })  

    // 判断当前路由状态  
    const isLogined = store.state.isLogin  
    if(to.meta.auth) {  
        if(isLogined) {  
            next()  
        }else {  
            loginWin()  
            loadingIns.close()  
        }  
    }else {  
        next()  
    }  
})  

router.afterEach(() => {  
    loadingIns.close()  
})

electron-vue3自定义仿Mac导航栏

项目中顶部导航条采用的是mac导航条风格,关闭/最小化/最大化按钮在左侧。
img

<!-- //仿Mac导航条 -->  
<template>  
    <WinBar zIndex="1000">  
        <template #wbtn>  
            <MsgMenu />  
            <Lang />  
            <a class="wbtn" @click="handleSkinWin"><i class="iconfont icon-huanfu"></i></a>  
            <Setting />  
            <a class="wbtn" @click="handleRefresh"><i class="iconfont el-icon-refresh"></i></a>  
            <a class="wbtn" :class="{'on': isAlwaysOnTop}" :title="isAlwaysOnTop ? '取消置顶' : '置顶'" @click="handleAlwaysTop"><i class="iconfont icon-ding"></i></a>  
            <Avatar @logout="handleLogout" />  
        </template>  
    </WinBar>  
</template>

vue-i18n国际化方案

img

新建一个locale目录用来存放项目中语言文件。

img

/**  
 * @desc    vue-i18n国际化配置文件  
 * @Time    andy by 2021-05  
 * @Author      Q:282310962  wx:xy190310  
 */  

import { createI18n } from 'vue-i18n'  
import Storage from '@/utils/storage'  

// 默认设置  
export const langKey = 'lang'  
export const langVal = 'zh-CN'  

/**  
 * 引入element-plus国际化包  
 */  
import enUS from 'element-plus/lib/locale/lang/en'  
import zhCN from 'element-plus/lib/locale/lang/zh-cn'  
import zhTW from 'element-plus/lib/locale/lang/zh-tw'  
export const ElPlusLang = {  
    'en-US': enUS,  
    'zh-CN': zhCN,  
    'zh-TW': zhTW  
}  

/**  
 * 初始化多语言  
 */  
export const $messages = importLang()  
export const $lang = getLang()  
const i18n = createI18n({  
    legacy: false,  
    locale: $lang,  
    messages: $messages  
})  

/**  
 * 自动导入语言配置  
 */  
export function importLang() {  
    const localeModule = {}  
    try {  
        // 导入 @/layouts 文件夹下包含子目录locale中的xxx.js文件  
        const layoutsCtx = require.context('@/layouts', true, /[/\\]locale[/\\]([a-z]{2})-?([A-Z]{2})?\.js$/)  
        layoutsCtx.keys().map(path => {  
            const pathCtx = layoutsCtx(path)  
            if(pathCtx.default) {  
                const pathName = path.replace(/(.*\/)*([^.]+).*/ig, '$2')  
                if(localeModule[pathName]) {  
                    localeModule[pathName] = {  
                        ...localeModule[pathName], ...pathCtx.default  
                    }  
                }else {  
                    localeModule[pathName] = pathCtx.default  
                }  
            }  
        })  
    } catch (error) {  
        console.log(error)  
    }  

    return localeModule  
}  

/**  
 * 存储设置语言  
 * @param lang 语言类型 zh-CN | zh-TW | en-US  
 */  
export function setLang(lang, reload = false) {  
    if(getLang() !== lang) {  
        Storage.set(langKey, lang || '')  
        // 设置全局语言  
        i18n.global.locale.value = lang  

        if(reload) {  
            window.location.reload()  
        }  
    }  
}  

/**  
 * 获取语言  
 */  
export function getLang() {  
    const lang = Storage.get(langKey)  
    return lang || langVal  
}

vite2+electron主模板布局

项目整体分为顶部导航条、侧边栏、路由菜单、右侧上面包屑导航、右侧下主体内容。

<!-- //Main主模块模板 -->  
<template>  
    <div class="vadmin__wrapper" :style="{'--themeSkin': store.state.skin}">  
        <div v-if="!route.meta.isNewin" class="vadmin__layouts-main flexbox flex-col">  
            <!-- //顶部导航 -->  
            <div class="layout__topbar">  
                <TopNav />  
            </div>  

            <div class="layout__workpanel flex1 flexbox">  
                <!-- //侧边栏 -->  
                <div v-show="rootRouteEnable" class="panel__leftlayer">  
                    <SideMenu :routes="mainRoutes" :rootRoute="rootRoute" />  
                </div>  

                <!-- //中间栏 -->  
                <div class="panel__middlelayer" :class="{'collapsed': collapsed}">  
                    <RouteMenu   
                        :routes="getAllRoutes"   
                        :rootRoute="rootRoute"   
                        :defaultActive="defaultActive"   
                        :rootRouteEnable="rootRouteEnable"   
                    />  
                </div>  

                <!-- //右边栏 -->  
                <div class="panel__rightlayer flex1 flexbox flex-col">  
                    <!-- 面包屑导航 -->  
                    <BreadCrumb />  

                    <!-- 主内容区 -->  
                    <v3-scroll autohide>  
                        <div class="lay__container">  
                            <!-- //路由权限控制 -->  
                            <permission :roles="route.meta.roles">  
                                <template #tooltips>  
                                    <Forbidden />  
                                </template>  
                                <router-view></router-view>  
                            </permission>  
                        </div>  
                    </v3-scroll>  
                </div>  
            </div>  
        </div>  
        <router-view v-else class="vadmin__layouts-main flexbox flex-col"></router-view>  
    </div>  
</template>

Vue3图表化Hook

项目中多个地方需要使用到图表功能,于是就封装了一个图表hook函数。

/**  
 * 封装图表Hook  
 * @author XiaoYan  
 */  

import { onMounted, onBeforeUnmount, ref } from "vue"  
import * as echarts from "echarts"  
import elementResizeDetectorMaker from "element-resize-detector"  
import utils from "@/utils"  

export default function useChart(refs, options) {  
    let chartInst  
    let chartRef = ref(null)  
    let erd = elementResizeDetectorMaker()  

    const handleResize = utils.debounce(() => {  
        chartInst.resize()  
    }, 100)  

    onMounted(() => {  
        if(refs.value) {  
            chartInst = echarts.init(refs.value)  
            chartInst.setOption(options)  
            chartRef.value = chartInst  
        }  
        // window.addEventListener('resize', handleResize)  
        erd.listenTo(refs.value, handleResize)  
    })  

    onBeforeUnmount(() => {  
        chartInst.dispose()  
        // window.removeEventListener('resize', handleResize)  
        erd.removeListener(refs.value, handleResize)  
    })  

    return chartRef  
}

Okay,基于vite.js+vue3+electron开发管理后台就分享到这里。希望对小伙伴们有些帮助!

img

链接:https://juejin.cn/post/6963310387945013261/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

继续阅读 »

上次有给大家分享一个Electron跨端仿抖音短视频项目,这次带来最新研发的vite.js+electron开发vue3中后台管理系统。

vite2-vue3-electronAdmin:一套基于electron+vite.js和element-plus组件库开发的客户端后台管理系统EXE。使用了最新的vue3全家桶技术,内置了 Vue-i18n 国际化解决方案,支持PC桌面端和平板自适应布局。

electron12 vite2.x仿制抖音短视频|直播聊天

img

基于最新的前端技术栈vite2+vue3全家桶+electron12+element-plus+echarts5开发而来。

img

技术栈

  • 编码器:VScode
  • 构建工具:Vitejs
  • vue3全家桶:Vue3.0+Vuex4+Vue-router@4
  • 跨端框架:Electron^12.0.4
  • 打包工具:vue-cli-plugin-electron-builder
  • UI组件库:element-plus^1.0.2 (饿了么vue3组件库)
  • 表格拖拽:Sortablejs^1.13
  • 图表组件:Echarts^5.1
  • 国际化:vue-i18n^9.1
  • 模拟请求:mockjs^1.1

img

特性

  • 使用最新前端技术栈开发
  • 支持桌面端及平板响应式布局
  • 支持组件式+指令式两种权限认证方式
  • 支持中英文/繁体国际化方案
  • 支持表格拖拽排序、全屏表格、树形表格等功能
  • 支持个性化换肤

img

项目结构

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

main.js配置

/**  
 * 渲染进程主入口  
 * @author XiaoYan  
 */  

import { createApp } from 'vue'  
import App from './App.vue'  
import Router from './router'  
import Store from './store'  

// 引入公共配置  
import gPlugins from './plugins'  

import { winCfg, loadWin } from './windows/actions'  

loadWin().then(config => {  
    winCfg.window = config  
    createApp(App)  
    .use(Router)  
    .use(Store)  
    .use(gPlugins)  
    .mount('#app')  
})

vue-router路由配置

项目中的路由采用了结构化分层加载,分为验证路由authRoutes.js和主模块路由mainRoutes.js两大部分。

/**  
 * 路由配置 Router util  
 * @author XiaoYan  
 */  

import { createRouter, createWebHashHistory } from "vue-router"  

import { ElLoading } from "element-plus"  
import { loginWin } from "@/windows/actions"  

import store from '@/store'  

// 导入公共模板/路由配置  
import mainLayout from "@/layouts/main"  
import authLayout from "@/layouts/auth"  
import mainRoutes from "@/layouts/main/routes.js"  
import authRoutes from "@/layouts/auth/routes.js"  

const RoutesLs = [  
    // 主页面模块  
    {  
        path: '/',  
        redirect: '/home/index',  
        component: mainLayout,  
        children: mainRoutes,  
    },  
    // 验证模块  
    {  
        path: '/auth',  
        redirect: '/auth/login',  
        component: authLayout,  
        children: authRoutes,  
    },  
    // 错误模块  
    {  
        path: '/:pathMatch(.*)*',  
        component: () => import('@/views/error/404.vue'),  
        meta: {  
            title: 'app__global-page-notfound',  
        }  
    }  
]  

const router = createRouter({  
    history: createWebHashHistory(),  
    routes: RoutesLs,  
})  

let loadingIns  
router.beforeEach((to, from, next) => {  
    // 开启加载提示  
    loadingIns = ElLoading.service({  
        lock: true,  
        text: 'Loading...',  
        spinner: 'el-icon-loading',  
        background: 'rgba(19, 209, 122, .1)'  
    })  

    // 判断当前路由状态  
    const isLogined = store.state.isLogin  
    if(to.meta.auth) {  
        if(isLogined) {  
            next()  
        }else {  
            loginWin()  
            loadingIns.close()  
        }  
    }else {  
        next()  
    }  
})  

router.afterEach(() => {  
    loadingIns.close()  
})

electron-vue3自定义仿Mac导航栏

项目中顶部导航条采用的是mac导航条风格,关闭/最小化/最大化按钮在左侧。
img

<!-- //仿Mac导航条 -->  
<template>  
    <WinBar zIndex="1000">  
        <template #wbtn>  
            <MsgMenu />  
            <Lang />  
            <a class="wbtn" @click="handleSkinWin"><i class="iconfont icon-huanfu"></i></a>  
            <Setting />  
            <a class="wbtn" @click="handleRefresh"><i class="iconfont el-icon-refresh"></i></a>  
            <a class="wbtn" :class="{'on': isAlwaysOnTop}" :title="isAlwaysOnTop ? '取消置顶' : '置顶'" @click="handleAlwaysTop"><i class="iconfont icon-ding"></i></a>  
            <Avatar @logout="handleLogout" />  
        </template>  
    </WinBar>  
</template>

vue-i18n国际化方案

img

新建一个locale目录用来存放项目中语言文件。

img

/**  
 * @desc    vue-i18n国际化配置文件  
 * @Time    andy by 2021-05  
 * @Author      Q:282310962  wx:xy190310  
 */  

import { createI18n } from 'vue-i18n'  
import Storage from '@/utils/storage'  

// 默认设置  
export const langKey = 'lang'  
export const langVal = 'zh-CN'  

/**  
 * 引入element-plus国际化包  
 */  
import enUS from 'element-plus/lib/locale/lang/en'  
import zhCN from 'element-plus/lib/locale/lang/zh-cn'  
import zhTW from 'element-plus/lib/locale/lang/zh-tw'  
export const ElPlusLang = {  
    'en-US': enUS,  
    'zh-CN': zhCN,  
    'zh-TW': zhTW  
}  

/**  
 * 初始化多语言  
 */  
export const $messages = importLang()  
export const $lang = getLang()  
const i18n = createI18n({  
    legacy: false,  
    locale: $lang,  
    messages: $messages  
})  

/**  
 * 自动导入语言配置  
 */  
export function importLang() {  
    const localeModule = {}  
    try {  
        // 导入 @/layouts 文件夹下包含子目录locale中的xxx.js文件  
        const layoutsCtx = require.context('@/layouts', true, /[/\\]locale[/\\]([a-z]{2})-?([A-Z]{2})?\.js$/)  
        layoutsCtx.keys().map(path => {  
            const pathCtx = layoutsCtx(path)  
            if(pathCtx.default) {  
                const pathName = path.replace(/(.*\/)*([^.]+).*/ig, '$2')  
                if(localeModule[pathName]) {  
                    localeModule[pathName] = {  
                        ...localeModule[pathName], ...pathCtx.default  
                    }  
                }else {  
                    localeModule[pathName] = pathCtx.default  
                }  
            }  
        })  
    } catch (error) {  
        console.log(error)  
    }  

    return localeModule  
}  

/**  
 * 存储设置语言  
 * @param lang 语言类型 zh-CN | zh-TW | en-US  
 */  
export function setLang(lang, reload = false) {  
    if(getLang() !== lang) {  
        Storage.set(langKey, lang || '')  
        // 设置全局语言  
        i18n.global.locale.value = lang  

        if(reload) {  
            window.location.reload()  
        }  
    }  
}  

/**  
 * 获取语言  
 */  
export function getLang() {  
    const lang = Storage.get(langKey)  
    return lang || langVal  
}

vite2+electron主模板布局

项目整体分为顶部导航条、侧边栏、路由菜单、右侧上面包屑导航、右侧下主体内容。

<!-- //Main主模块模板 -->  
<template>  
    <div class="vadmin__wrapper" :style="{'--themeSkin': store.state.skin}">  
        <div v-if="!route.meta.isNewin" class="vadmin__layouts-main flexbox flex-col">  
            <!-- //顶部导航 -->  
            <div class="layout__topbar">  
                <TopNav />  
            </div>  

            <div class="layout__workpanel flex1 flexbox">  
                <!-- //侧边栏 -->  
                <div v-show="rootRouteEnable" class="panel__leftlayer">  
                    <SideMenu :routes="mainRoutes" :rootRoute="rootRoute" />  
                </div>  

                <!-- //中间栏 -->  
                <div class="panel__middlelayer" :class="{'collapsed': collapsed}">  
                    <RouteMenu   
                        :routes="getAllRoutes"   
                        :rootRoute="rootRoute"   
                        :defaultActive="defaultActive"   
                        :rootRouteEnable="rootRouteEnable"   
                    />  
                </div>  

                <!-- //右边栏 -->  
                <div class="panel__rightlayer flex1 flexbox flex-col">  
                    <!-- 面包屑导航 -->  
                    <BreadCrumb />  

                    <!-- 主内容区 -->  
                    <v3-scroll autohide>  
                        <div class="lay__container">  
                            <!-- //路由权限控制 -->  
                            <permission :roles="route.meta.roles">  
                                <template #tooltips>  
                                    <Forbidden />  
                                </template>  
                                <router-view></router-view>  
                            </permission>  
                        </div>  
                    </v3-scroll>  
                </div>  
            </div>  
        </div>  
        <router-view v-else class="vadmin__layouts-main flexbox flex-col"></router-view>  
    </div>  
</template>

Vue3图表化Hook

项目中多个地方需要使用到图表功能,于是就封装了一个图表hook函数。

/**  
 * 封装图表Hook  
 * @author XiaoYan  
 */  

import { onMounted, onBeforeUnmount, ref } from "vue"  
import * as echarts from "echarts"  
import elementResizeDetectorMaker from "element-resize-detector"  
import utils from "@/utils"  

export default function useChart(refs, options) {  
    let chartInst  
    let chartRef = ref(null)  
    let erd = elementResizeDetectorMaker()  

    const handleResize = utils.debounce(() => {  
        chartInst.resize()  
    }, 100)  

    onMounted(() => {  
        if(refs.value) {  
            chartInst = echarts.init(refs.value)  
            chartInst.setOption(options)  
            chartRef.value = chartInst  
        }  
        // window.addEventListener('resize', handleResize)  
        erd.listenTo(refs.value, handleResize)  
    })  

    onBeforeUnmount(() => {  
        chartInst.dispose()  
        // window.removeEventListener('resize', handleResize)  
        erd.removeListener(refs.value, handleResize)  
    })  

    return chartRef  
}

Okay,基于vite.js+vue3+electron开发管理后台就分享到这里。希望对小伙伴们有些帮助!

img

链接:https://juejin.cn/post/6963310387945013261/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

收起阅读 »

uview组件from-item在小程序与h5里表现一不致(附解决方案)

在使用uview组件开发项目时,使用下面代码,碰到一个问题:
代码为:

        <u-form class="from-submit" ref="uForm" label-width="160" :error-type="['toast', 'border-bottom']">  
            <u-form-item label="上课时间" prop="beginTime" class="u-flex" :required="true">  
                <view>xxx</view>  
                <text class="label-text">至</text>  
                <view>xxx</view>  
            </u-form-item>  
        </u-form>

大家看图:

可以发现,同一套代码,在两个平台,表现的却不是一致的。

同样是选择from-item,他们的显示区域却不尽相同。

虽然看起来样式差不多,但表现却不一致,通过调试,最终得到解决方案:

给from-item下面的view元素,添加 display:inline-flex 样式即可

最终代码(非优化代码,仅作示例):

        <u-form class="from-submit" ref="uForm" label-width="160" :error-type="['toast', 'border-bottom']">  
            <u-form-item label="上课时间" prop="beginTime" class="u-flex" :required="true">  
                <view style="display: inline-flex;">xxx</view>  
                <text class="label-text">至</text>  
                <view style="display: inline-flex;">xxx</view>  
            </u-form-item>  
        </u-form>

最终效果,”鸡乎一样“ 了

继续阅读 »

在使用uview组件开发项目时,使用下面代码,碰到一个问题:
代码为:

        <u-form class="from-submit" ref="uForm" label-width="160" :error-type="['toast', 'border-bottom']">  
            <u-form-item label="上课时间" prop="beginTime" class="u-flex" :required="true">  
                <view>xxx</view>  
                <text class="label-text">至</text>  
                <view>xxx</view>  
            </u-form-item>  
        </u-form>

大家看图:

可以发现,同一套代码,在两个平台,表现的却不是一致的。

同样是选择from-item,他们的显示区域却不尽相同。

虽然看起来样式差不多,但表现却不一致,通过调试,最终得到解决方案:

给from-item下面的view元素,添加 display:inline-flex 样式即可

最终代码(非优化代码,仅作示例):

        <u-form class="from-submit" ref="uForm" label-width="160" :error-type="['toast', 'border-bottom']">  
            <u-form-item label="上课时间" prop="beginTime" class="u-flex" :required="true">  
                <view style="display: inline-flex;">xxx</view>  
                <text class="label-text">至</text>  
                <view style="display: inline-flex;">xxx</view>  
            </u-form-item>  
        </u-form>

最终效果,”鸡乎一样“ 了

收起阅读 »

有丰富的uniapp开发经验,后端技术栈java,全栈工程师,接单

有丰富的uniapp开发经验,
后端技术栈java,
全栈工程师,
有充足的时间,
有需要的可以联系我

接单:微信小程序应用、uniapp开发、java开发、后台管理系统、APP、网站、vue开发。
联系方式Q.Q,V.X号:443409972
淘宝开发小店:https://item.taobao.com/item.htm?id=630595051308

继续阅读 »

有丰富的uniapp开发经验,
后端技术栈java,
全栈工程师,
有充足的时间,
有需要的可以联系我

接单:微信小程序应用、uniapp开发、java开发、后台管理系统、APP、网站、vue开发。
联系方式Q.Q,V.X号:443409972
淘宝开发小店:https://item.taobao.com/item.htm?id=630595051308

收起阅读 »

Android应用市场上架uni-app(5+App)应用合规指南,以及收到工信部或应用市场合规整改通知的解决办法

审核 合规 应用上架 非法获取 违规获取 android ID 隐私政策 合规指南 上架被拒 不合规

此文档将不再维护,请参考新文档:https://uniapp.dcloud.net.cn/tutorial/android-store

背景

为有效治理App强制授权、过度索权、超范围收集个人信息等现象,落实《网络安全法》《消费者权益保护法》的要求,保障个人信息安全,2019年1月,中央网信办、工信部、公安部、市场监管总局等四部委发布了《关于开展App违法违规收集使用个人信息专项治理的公告》,在全国范围组织开展App违法违规收集使用个人信息专项治理,并陆续出台完善了《App违法违规收集使用个人信息行为认定方法》、《GB/T 35273-2020 信息安全技术 个人信息安全规范》等标准规范。

根据以上规范要求,各大应用市场都加强应用的检测,要求应用必须符合相关政策,否则应用将有被通报或下架的风险。

APP因合规问题无法上架

请认真的阅读以下步骤来检测自己的APP!有效的解决上架问题

  • APP不是由HbuilderX3.6.1+云打包生产的请抓紧时间升级到HbuilderX3.6.1+版本。重新打包!
  • APP是离线打包请升级SDK到3.6.1+版本重新编辑打包!下载地址
  • 不要将自定义基座提交平台审核。调试模式下不会处理合规问题。需要注意!
  • APP没有配置隐私与政策提示框。请认真阅读Android平台隐私与政策提示框配置方法配置你APP的隐私弹窗。
  • 配置隐私弹窗时一定要配置使用template模式。否则无法上架应用市场。应用内部自己实现的隐私弹窗也不行。一定要使用uni提供的隐私弹窗并使用template模式切记!
    //androidPrivacy.json  
    {    
    "version": "1",      
    "prompt": "template",    
    "title": "服务协议和隐私政策",    
    "message": "..."  
    }  
  • 填写隐私协一定要结合实际使用的模块功能。填写相关隐私条款!不能含糊不清。模块收集了什么信息都要填写完整。否则影响上架!请参考当前文档中的隐私政策注意事项
  • 查看是否集成uni原生插件。有些权限或是违规获取可能是uni原生插件引发的。建议使用排除法删除插件重新打包检测
  • 检查是否集成了fcm推送(包含unipush中的fcm)、google统计、google推送、google登录模块。由于这些模块都集成google的gms服务会提前获取android id导致无法在国内正常上架。打包时请在manifest.json配置中排除这些功能模块。
  • APP都符合以上条件要求。上架依然失败!请向检测平台要求提供代码调用堆栈。请拿着堆栈信息去ASK论坛发帖说明问题并@管理人员反馈

<a id="zhuyishixiang">隐私政策注意事项</a>

  • 必须确保应用存在《隐私政策》,在应用首次启动时弹出提示并取得用户同意。
  • 一定要配置使用template模式隐私与政策提示框 详情参考
  • 必须在“隐私与政策”非常清楚、全面地说明(不要用可能收集、了解用户信息这种模糊不清晰的词语)收集用户个人信息的目的、方式和范围,用户个人信息包括但不限于mac地址、设备序列号、imei、imsi、软件安装列表、通讯录信息、短信信息等。
  • 如果反馈说有违规获取敏感信息行为,请查看Android平台各功能模块隐私合规协议各功能模块隐私协议。如果你集成了相关模块就一定要写入到app的隐私协议中。
  • 必须在《隐私政策》中必告知用户您的应用基于DCloud uni-app(5+ App/Wap2App)开发,添加如下协议:

    我们的产品基于DCloud uni-app(5+ App/Wap2App)开发,应用运行期间需要收集您的设备唯一识别码(IMEI/android ID/DEVICE_ID/IDFA、SIM 卡 IMSI 信息、OAID)以提供统计分析服务,并通过应用启动数据及异常错误日志分析改进性能和用户体验,为用户提供更好的服务。

各大应用市场上架合规审查细节可能存在差异,如果开发者碰到相关问题请及时反馈,我们会及时汇总整理供大家参考

相关参考

继续阅读 »

此文档将不再维护,请参考新文档:https://uniapp.dcloud.net.cn/tutorial/android-store

背景

为有效治理App强制授权、过度索权、超范围收集个人信息等现象,落实《网络安全法》《消费者权益保护法》的要求,保障个人信息安全,2019年1月,中央网信办、工信部、公安部、市场监管总局等四部委发布了《关于开展App违法违规收集使用个人信息专项治理的公告》,在全国范围组织开展App违法违规收集使用个人信息专项治理,并陆续出台完善了《App违法违规收集使用个人信息行为认定方法》、《GB/T 35273-2020 信息安全技术 个人信息安全规范》等标准规范。

根据以上规范要求,各大应用市场都加强应用的检测,要求应用必须符合相关政策,否则应用将有被通报或下架的风险。

APP因合规问题无法上架

请认真的阅读以下步骤来检测自己的APP!有效的解决上架问题

  • APP不是由HbuilderX3.6.1+云打包生产的请抓紧时间升级到HbuilderX3.6.1+版本。重新打包!
  • APP是离线打包请升级SDK到3.6.1+版本重新编辑打包!下载地址
  • 不要将自定义基座提交平台审核。调试模式下不会处理合规问题。需要注意!
  • APP没有配置隐私与政策提示框。请认真阅读Android平台隐私与政策提示框配置方法配置你APP的隐私弹窗。
  • 配置隐私弹窗时一定要配置使用template模式。否则无法上架应用市场。应用内部自己实现的隐私弹窗也不行。一定要使用uni提供的隐私弹窗并使用template模式切记!
    //androidPrivacy.json  
    {    
    "version": "1",      
    "prompt": "template",    
    "title": "服务协议和隐私政策",    
    "message": "..."  
    }  
  • 填写隐私协一定要结合实际使用的模块功能。填写相关隐私条款!不能含糊不清。模块收集了什么信息都要填写完整。否则影响上架!请参考当前文档中的隐私政策注意事项
  • 查看是否集成uni原生插件。有些权限或是违规获取可能是uni原生插件引发的。建议使用排除法删除插件重新打包检测
  • 检查是否集成了fcm推送(包含unipush中的fcm)、google统计、google推送、google登录模块。由于这些模块都集成google的gms服务会提前获取android id导致无法在国内正常上架。打包时请在manifest.json配置中排除这些功能模块。
  • APP都符合以上条件要求。上架依然失败!请向检测平台要求提供代码调用堆栈。请拿着堆栈信息去ASK论坛发帖说明问题并@管理人员反馈

<a id="zhuyishixiang">隐私政策注意事项</a>

  • 必须确保应用存在《隐私政策》,在应用首次启动时弹出提示并取得用户同意。
  • 一定要配置使用template模式隐私与政策提示框 详情参考
  • 必须在“隐私与政策”非常清楚、全面地说明(不要用可能收集、了解用户信息这种模糊不清晰的词语)收集用户个人信息的目的、方式和范围,用户个人信息包括但不限于mac地址、设备序列号、imei、imsi、软件安装列表、通讯录信息、短信信息等。
  • 如果反馈说有违规获取敏感信息行为,请查看Android平台各功能模块隐私合规协议各功能模块隐私协议。如果你集成了相关模块就一定要写入到app的隐私协议中。
  • 必须在《隐私政策》中必告知用户您的应用基于DCloud uni-app(5+ App/Wap2App)开发,添加如下协议:

    我们的产品基于DCloud uni-app(5+ App/Wap2App)开发,应用运行期间需要收集您的设备唯一识别码(IMEI/android ID/DEVICE_ID/IDFA、SIM 卡 IMSI 信息、OAID)以提供统计分析服务,并通过应用启动数据及异常错误日志分析改进性能和用户体验,为用户提供更好的服务。

各大应用市场上架合规审查细节可能存在差异,如果开发者碰到相关问题请及时反馈,我们会及时汇总整理供大家参考

相关参考

收起阅读 »

提示appkey未配置,请检查build.gradle

配置signingConfigs节点下的证书,
buildTypes节点下minifyEnabled改为true,官方给的demo这里是false,严重怀疑官方故意误导!

    signingConfigs {  
        config {  
            keyAlias ''  
            keyPassword ''  
            storeFile file('.jks')  
            storePassword ''  
            v1SigningEnabled true  
            v2SigningEnabled true  
        }  
    }  

    buildTypes {  
        debug {  
            signingConfig signingConfigs.config  
            minifyEnabled true  
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'  
        }  
        release {  
            signingConfig signingConfigs.config  
            minifyEnabled true  
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'  
        }  
    }
继续阅读 »

配置signingConfigs节点下的证书,
buildTypes节点下minifyEnabled改为true,官方给的demo这里是false,严重怀疑官方故意误导!

    signingConfigs {  
        config {  
            keyAlias ''  
            keyPassword ''  
            storeFile file('.jks')  
            storePassword ''  
            v1SigningEnabled true  
            v2SigningEnabled true  
        }  
    }  

    buildTypes {  
        debug {  
            signingConfig signingConfigs.config  
            minifyEnabled true  
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'  
        }  
        release {  
            signingConfig signingConfigs.config  
            minifyEnabled true  
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'  
        }  
    }
收起阅读 »

95 后大学生利用漏洞免费吃肯德基,获刑2年半!

法律科普

日前,在校大学生徐某利用肯德基App客户端和微信客户端之间数据不同步的漏洞,骗取兑换券或取餐码,售与他人牟利,并将诈骗方法传授给同学,造成肯德基品牌所有者百胜公司损失20余万元。

近日,上海市徐汇区人民法院开庭审理此案。徐某等五人因犯诈骗罪、传授犯罪方法罪被判有期徒刑,并处罚金。

大学生钻肯德基系统漏洞,生出意外“副业”获利

徐某是江苏某大学的一名在校生。2018年4月,在用肯德基客户端点餐时,徐某无意发现两个“生财小门道”

  • 一是在App客户端用套餐兑换券下单,进入待支付状态后暂不支付,之后在微信客户端对兑换券进行退款操作,然后再将之前客户端的订单取消,此时竟可以重新获取兑换券,这种方式等于分文未付骗取一份兑换券

  • 二是先在App客户端用套餐兑换券下单待支付,在微信客户端退掉兑换券,再在App客户端支付,此时便可以支付成功并获得取餐码,这种方式等于分文未付骗取一份套餐。

发现这个漏洞后,徐某“喜出望外”。从当年4月起,除了自己这样点餐操作外,徐某还做起了“副业”:将诈骗得来的套餐产品通过线上交易软件低价出售给他人,从中非法获利。

同时,他还将犯罪方法当面或通过网络传授给丁某等四名同学。截至同年10月案发,徐某的行为造成百胜公司损失5.8万余元,丁某等四人造成百胜公司损失0.89万元至4.7万元不等。

法院:符合诈骗罪构成要件,5名大学生悉数获刑

上海市徐汇区人民法院审理查明,各被告人利用系统的数据不同步来实施犯罪,并非系统本身发生的机械故障或者缺陷,其行为存在欺骗性

法院认定,各被告人明知百胜公司旗下品牌肯德基App客户端和微信客户端自助点餐系统存在数据不同步的漏洞,仍以非法占有为目的,进行虚假交易,进而非法获取财物的行为认定为诈骗罪。

法院审理后认为,被告人徐某以非法占有为目的,诈骗单位财物,数额巨大,并传授他人犯罪方法,其行为分别构成诈骗罪、传授犯罪方法罪。

徐某自动投案,如实供述诈骗和传授犯罪方法罪行,均系自首,依法分别予以减轻、从轻处罚。同时,徐某积极赔偿被害单位损失并获谅解,酌情予以从轻处罚。

最终,徐某因犯诈骗罪,被判处有期徒刑两年,并处罚金人民币六千元;犯传授犯罪方法罪,判处有期徒刑十个月,决定执行有期徒刑两年六个月,并处罚金人民币六千元。

丁某等四人皆因相同案由被分别认定为诈骗罪或诈骗罪、传授犯罪方法罪,分别被判处有期徒刑两年至一年三个月,并处罚金人民币四千元至一千元不等的刑罚。

网友:聪明脑袋算了笔糊涂账

对此,网友纷纷表示,“聪明用错了地方”“做任何事不能违背法律”

【来源:光明日报】,声明:转载此文是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢。 邮箱地址:pufa@dcloud.io 。

原文链接

继续阅读 »

日前,在校大学生徐某利用肯德基App客户端和微信客户端之间数据不同步的漏洞,骗取兑换券或取餐码,售与他人牟利,并将诈骗方法传授给同学,造成肯德基品牌所有者百胜公司损失20余万元。

近日,上海市徐汇区人民法院开庭审理此案。徐某等五人因犯诈骗罪、传授犯罪方法罪被判有期徒刑,并处罚金。

大学生钻肯德基系统漏洞,生出意外“副业”获利

徐某是江苏某大学的一名在校生。2018年4月,在用肯德基客户端点餐时,徐某无意发现两个“生财小门道”

  • 一是在App客户端用套餐兑换券下单,进入待支付状态后暂不支付,之后在微信客户端对兑换券进行退款操作,然后再将之前客户端的订单取消,此时竟可以重新获取兑换券,这种方式等于分文未付骗取一份兑换券

  • 二是先在App客户端用套餐兑换券下单待支付,在微信客户端退掉兑换券,再在App客户端支付,此时便可以支付成功并获得取餐码,这种方式等于分文未付骗取一份套餐。

发现这个漏洞后,徐某“喜出望外”。从当年4月起,除了自己这样点餐操作外,徐某还做起了“副业”:将诈骗得来的套餐产品通过线上交易软件低价出售给他人,从中非法获利。

同时,他还将犯罪方法当面或通过网络传授给丁某等四名同学。截至同年10月案发,徐某的行为造成百胜公司损失5.8万余元,丁某等四人造成百胜公司损失0.89万元至4.7万元不等。

法院:符合诈骗罪构成要件,5名大学生悉数获刑

上海市徐汇区人民法院审理查明,各被告人利用系统的数据不同步来实施犯罪,并非系统本身发生的机械故障或者缺陷,其行为存在欺骗性

法院认定,各被告人明知百胜公司旗下品牌肯德基App客户端和微信客户端自助点餐系统存在数据不同步的漏洞,仍以非法占有为目的,进行虚假交易,进而非法获取财物的行为认定为诈骗罪。

法院审理后认为,被告人徐某以非法占有为目的,诈骗单位财物,数额巨大,并传授他人犯罪方法,其行为分别构成诈骗罪、传授犯罪方法罪。

徐某自动投案,如实供述诈骗和传授犯罪方法罪行,均系自首,依法分别予以减轻、从轻处罚。同时,徐某积极赔偿被害单位损失并获谅解,酌情予以从轻处罚。

最终,徐某因犯诈骗罪,被判处有期徒刑两年,并处罚金人民币六千元;犯传授犯罪方法罪,判处有期徒刑十个月,决定执行有期徒刑两年六个月,并处罚金人民币六千元。

丁某等四人皆因相同案由被分别认定为诈骗罪或诈骗罪、传授犯罪方法罪,分别被判处有期徒刑两年至一年三个月,并处罚金人民币四千元至一千元不等的刑罚。

网友:聪明脑袋算了笔糊涂账

对此,网友纷纷表示,“聪明用错了地方”“做任何事不能违背法律”

【来源:光明日报】,声明:转载此文是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢。 邮箱地址:pufa@dcloud.io 。

原文链接

收起阅读 »

uni-rate 评分 点击评分失效问题解决

uniapp插件 uniapp 星星评分
  • 定位到 _getRateCount(获取星星个数) 方法,进行替换,替换代码如下。

    /**  
    * 获取星星个数  
    */  
    _getRateCount(clientX) {  
    this._getSize()  
    const size = Number(this.size)  
    if(size === NaN){  
    return new Error('size 属性只能设置为数字')  
    }  
    const rateMoveRange = clientX - this._rateBoxLeft  
    let index = parseInt(rateMoveRange / (size/2 + this.marginNumber))  
    index = index < 0 ? 0 : index;  
    index = index > this.max ? this.max : index;  
    const range = parseInt(rateMoveRange - (size/2 + this.marginNumber) * index);  
    let value = 0;  
    if (this._oldValue === index && !this.PC) return;  
    this._oldValue = index;  
    if (this.allowHalf) {  
    if (range > (size / 2)) {  
      value = index + 1  
    } else {  
      value = index + 0.5  
    }  
    } else {  
    value = index + 1  
    }  
    
    value = Math.max(0.5, Math.min(value, this.max))  
    this.valueSync = value  
    this._onChange()  
    },

原因

rpx和px问题

let index = parseInt(rateMoveRange / (size + this.marginNumber)) -> let index = parseInt(rateMoveRange / (size/2 + this.marginNumber))
const range = parseInt(rateMoveRange - (size + this.marginNumber) index); -> const range = parseInt(rateMoveRange - (size/2 + this.marginNumber) index

继续阅读 »
  • 定位到 _getRateCount(获取星星个数) 方法,进行替换,替换代码如下。

    /**  
    * 获取星星个数  
    */  
    _getRateCount(clientX) {  
    this._getSize()  
    const size = Number(this.size)  
    if(size === NaN){  
    return new Error('size 属性只能设置为数字')  
    }  
    const rateMoveRange = clientX - this._rateBoxLeft  
    let index = parseInt(rateMoveRange / (size/2 + this.marginNumber))  
    index = index < 0 ? 0 : index;  
    index = index > this.max ? this.max : index;  
    const range = parseInt(rateMoveRange - (size/2 + this.marginNumber) * index);  
    let value = 0;  
    if (this._oldValue === index && !this.PC) return;  
    this._oldValue = index;  
    if (this.allowHalf) {  
    if (range > (size / 2)) {  
      value = index + 1  
    } else {  
      value = index + 0.5  
    }  
    } else {  
    value = index + 1  
    }  
    
    value = Math.max(0.5, Math.min(value, this.max))  
    this.valueSync = value  
    this._onChange()  
    },

原因

rpx和px问题

let index = parseInt(rateMoveRange / (size + this.marginNumber)) -> let index = parseInt(rateMoveRange / (size/2 + this.marginNumber))
const range = parseInt(rateMoveRange - (size + this.marginNumber) index); -> const range = parseInt(rateMoveRange - (size/2 + this.marginNumber) index

收起阅读 »

Vue3简单整合uView@1.8.4解决方案

仅仅可以跑DEMO,嘿嘿嘿

问题描述

在这里插入图片描述

问题分析

在这里插入图片描述

官方文档

globalProperties

解决方案

切换到下载安装方式
https://www.uviewui.com/components/install.html#下载安装
修改源代码
index.js
在这里插入图片描述

Vue3 filter也没了,几个时间函数不重要吧?
在这里插入图片描述

在这里插入图片描述

const install = Vue => {  
    Vue.mixin(mixin)   
    if (Vue.config.globalProperties.openShare) {  
        Vue.mixin(mpShare);  
    }  
    // Vue.mixin(vuexStore);  
    // 时间格式化,同时两个名称,date和timeFormat  
    Vue.config.globalProperties.$filter = {  
        timeFormat(timestamp, format) {  
            return timeFormat(timestamp, format)  
        },  
        date(timestamp, format) {  
            return timeFormat(timestamp, format)  
        },  
        // 将多久以前的方法,注入到全局过滤器  
        timeFrom(timestamp, format) {  
            return timeFrom(timestamp, format)  
        }  
    }  
    Vue.config.globalProperties.$u = $u  
}

参考文章

vue 3.0 prototype 替代用法

继续阅读 »

仅仅可以跑DEMO,嘿嘿嘿

问题描述

在这里插入图片描述

问题分析

在这里插入图片描述

官方文档

globalProperties

解决方案

切换到下载安装方式
https://www.uviewui.com/components/install.html#下载安装
修改源代码
index.js
在这里插入图片描述

Vue3 filter也没了,几个时间函数不重要吧?
在这里插入图片描述

在这里插入图片描述

const install = Vue => {  
    Vue.mixin(mixin)   
    if (Vue.config.globalProperties.openShare) {  
        Vue.mixin(mpShare);  
    }  
    // Vue.mixin(vuexStore);  
    // 时间格式化,同时两个名称,date和timeFormat  
    Vue.config.globalProperties.$filter = {  
        timeFormat(timestamp, format) {  
            return timeFormat(timestamp, format)  
        },  
        date(timestamp, format) {  
            return timeFormat(timestamp, format)  
        },  
        // 将多久以前的方法,注入到全局过滤器  
        timeFrom(timestamp, format) {  
            return timeFrom(timestamp, format)  
        }  
    }  
    Vue.config.globalProperties.$u = $u  
}

参考文章

vue 3.0 prototype 替代用法

收起阅读 »

不能获取到别人帮我买的付费插件

HBuilder X

别人帮我购买了一个付费插件, appid和package name 都填写正确。 却在HbuilderX中获取不到这个插件

别人帮我购买了一个付费插件, appid和package name 都填写正确。 却在HbuilderX中获取不到这个插件

nvue waterfall原生组件返回顶部

滚动 nvue

在解决这个问题之前,可是浪费了我好久的时间
也有其他人在发布了问题,但是没有人回答
在详细查阅文档后,还是找到了答案
确实还是对文档的不够熟悉
在此记录下,也给后面的小白找好捷径,代码已精简

    <template>  
         <waterfall column-count="2" column-width="auto" :show-scrollbar="false" :column-gap="5" :left-gap="5"  
            :right-gap="5" :bounce="false" :loadmoreoffset="500" @loadmore="loadmore" alwaysScrollableVertical="true"  
            :style="{height: contentHeight + 'px'}">  
            <header>  
                <view ref="topRef" style="height: 0;">顶部标志</view>  
            </header>  
            <!-- 注意事项: 不能使用 index 作为 key 的唯一标识 -->  
            <cell v-for="(item, index) in dataList" :key="'list_'+index">  

            </cell>  
        </waterfall>  
        <cover-view style="position: fixed;right:10rpx;bottom:20rpx;background-color: #ffe563;" @click="goTop()">  
            <text>返回顶部</text>  
        </cover-view>  
   <template>  
<script>  
    const dom = uni.requireNativePlugin('dom')  
    export default {  
        props: {  
            contentHeight: {  
                type: Number,  
                default: 800  
            }  
        },  
        data() {  
            return {  
                dataList: []  
            }  
        },  
        methods: {  
            goTop() {  
                dom.scrollToElement(this.$refs.topRef, {  
                    offset: 0  
                })  
            }  
        }  
    }  
</script>
继续阅读 »

在解决这个问题之前,可是浪费了我好久的时间
也有其他人在发布了问题,但是没有人回答
在详细查阅文档后,还是找到了答案
确实还是对文档的不够熟悉
在此记录下,也给后面的小白找好捷径,代码已精简

    <template>  
         <waterfall column-count="2" column-width="auto" :show-scrollbar="false" :column-gap="5" :left-gap="5"  
            :right-gap="5" :bounce="false" :loadmoreoffset="500" @loadmore="loadmore" alwaysScrollableVertical="true"  
            :style="{height: contentHeight + 'px'}">  
            <header>  
                <view ref="topRef" style="height: 0;">顶部标志</view>  
            </header>  
            <!-- 注意事项: 不能使用 index 作为 key 的唯一标识 -->  
            <cell v-for="(item, index) in dataList" :key="'list_'+index">  

            </cell>  
        </waterfall>  
        <cover-view style="position: fixed;right:10rpx;bottom:20rpx;background-color: #ffe563;" @click="goTop()">  
            <text>返回顶部</text>  
        </cover-view>  
   <template>  
<script>  
    const dom = uni.requireNativePlugin('dom')  
    export default {  
        props: {  
            contentHeight: {  
                type: Number,  
                default: 800  
            }  
        },  
        data() {  
            return {  
                dataList: []  
            }  
        },  
        methods: {  
            goTop() {  
                dom.scrollToElement(this.$refs.topRef, {  
                    offset: 0  
                })  
            }  
        }  
    }  
</script>
收起阅读 »

在线接单, 5k优惠1k,1w优惠2k,2w优惠4k,以此类推,承接H5、小程序、、PC端网站、后台系统、UI等外包

外包接单 uniapp

,享受满减优惠,
5k-1k,1w-2k,2w-4k,以此类推,

承接UI、H5、小程序、、PC端网站、后台系统等产品

vx:web9688

微信

,享受满减优惠,
5k-1k,1w-2k,2w-4k,以此类推,

承接UI、H5、小程序、、PC端网站、后台系统等产品

vx:web9688

微信

遍地的开源商城,为啥我们还要做Leadshop开源系统?

Leadshop的开发背景

传统的电商平台(这里指的是淘宝、京东、拼多多这类型的中心化平台)早已是红海,商家越来越难生存,平台规则越来越严格,稍有不慎,前功尽弃,商家长期苦不堪言。

有痛点就有市场机会,这是市场规律。

近年来崛起的私域saas电商平台如雨后春笋般侵袭而来,如有赞、微盟等。商家也逐步觉醒,不再单一的依赖传统中心化大平台了,逐步布局自己的私域流量平台。

私域电商软件成了必不可少的工具之一,大批saas服务商尝到了甜头。

但是好景不长,这块蛋糕不仅被腾讯盯上了,腾讯还想做规则制定者,微信即微信小店之后又推出了微信小商店,无缝衔接视频号及直播带货,同时开放了服务市场,将私域电商推向高潮,大批saas类的服务商开始坐不住了,跟微信小商店竞争胜算如何呢?

传统电商,saas私域电商好像和我们开发者关系不是很大,在电商领域我们开发者有什么机会呢?

随着商家越来越重视私域流量、客户数据、个性化的商业模式,私域saas电商模式很难满足这么多个性化需求,不少商家开始选择招技术团队或外包公司进行个性化的定制开发,但是从0开发一套成熟的电商系统要付出的成本是极大,可以说是无底洞,说实话没几个商家能够承受的了。

Leadshop非常想解决这个行业痛点,所以Leadshop诞生了!它是为终端商家,为开发者而生的一款免费且开源的电商系统。

Leadshop一款提供持续更新服务的免费开源商城系统,旨在打造极致的用户体验。
Leadshop已经实现了从0到1的研发,我们开发者只需要在此基础上进行客户的个性化需求开发便可满足客户需求,从而以最低成本创造增值收益。

Leadshop主要特性

Leadshop 开源系统,基于Yii2开发,支持composer,优化核心,减少依赖,基于全新的架构思想和命名空间

  • 基于命名空间和PSR-4规范,加入PHP7新特性
  • 核心功能模块化,方便开发和维护
  • 强化路由功能,采用RESTful接口标准
  • 灵活创建模型控制器,易于扩展开发
  • 配置文件可分离,方便管理
  • 重写的自动验证和完成
  • 简化扩展机制,提升开发速度
  • API支持完善,方便二次开发
  • 内置WeChat微信开发框架,微信接入更加快捷,简单
  • 使用ORM自动创建表结构,提升开发速度
  • 支持数据库结构、数据、模板在线缓存清除,提升用户体验
  • 客户端完善的交互效果和动画,提升用户端视觉体验
  • 支持在线一键安装,方便快捷。
  • 可视化DIY店铺装修,方便、快捷、直观,可以随心所欲装扮自己的店铺
  • 高效的笛卡尔乘积运算,8000条规格秒加载
  • 拟态Windows文件夹的素材管理结构,操作更熟悉随心

运行环境

Linux+Nginx+PHP7.4+MySQL5.7.3以上

插件市场的地址

https://ext.dcloud.net.cn/plugin?id=4699

体验后台

地址:https://demo.leadshop.vip
账号:18888888888
密码:123456
tiyan.png

Leadshop页面展示

展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图

Leadshop微商城

论坛交流

地址:https://forum.leadshop.vip/

开源无加密

基于Apache License 2.0开源协议,前后端代码开源无加密,支持二次开发,支持商用。

核心技术

前端技术栈 ES6、vue、vuex、vue-router、vue-cli、axios、element-ui、uni-app

后端技术栈 Yii2、Jwt、Mysql、Easy-SMS

接口标准

采用标准RESTful API ,高效的API阅读性,具有扩展性强、结构清晰的特点

数据交互

采用JSON API 标准,用以定义客户端如何获取与修改资源,以及服务器如何响应对应请求。高效实现的同时,无需牺牲可读性、灵活性和可发现性

认证方式

目前所有的接口使用 Oauth2 Password 方式,也就是 JWT Authorization Bearer header 进认证。支持扩语言扩展,多平台扩展。

数据表格导出

采用高性能的 js-xlsx数据导出,易于扩展,兼容性强。

接口文档:http://www.leadshop.vip/api.html

安装

一键安装

1.上传你的代码

2.项目目录设置755权限

3.设置代码执行目录为/web

注:如果使用Apache环境 需要在.htaccess 中添加

 SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

否则会导致OAuth登录模式获取不到Authorization

4.检查php禁用函数列表,symlink函数不能被禁用,否则后台页面无法访问。

5.在浏览器中输入你的域名或IP

( 例如:www.yourdomain.com),安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装。

6.后台访问地址:
域名/index.php?r=admin

7.公众号首页访问地址:
域名/index.php?r=wechat

重新安装

  1. 清除数据库
  2. 删除/server/install.lock 文件

目录说明

 站点根目录  
    ├─api                               //后台接口  
    ├─app                               //客户端(微信小程序,公众号)  
    ├─applet                            //打包后的微信小程序源码包  
    ├─components                        //通用组件  
    ├─config                            //配置文件目录  
    ├─controllers                       //控制器  
    ├─datamodel                         //模型  
    ├─forms                               
    │  └─install  
    ├─modules                           //模块       
    ├─stores                            //应用配置文件  
    ├─system                            //系统核心目录  
    │  ├─common  
    │  ├─config  
    │  ├─phpqrcode  
    │  └─wechat  
    ├─vendor                            //依赖  
    ├─views  
    │  ├─admin                          //后台编译包目录,其中index.php不可删除  
    │  ├─wechat                         //公众号编译包目录,其中index.php不可删除  
    │  └─site  
    └─web  
        ├─assets  
        ├─static                        //静态文件  
        ├─img                           //H5端图片目录  
        ├─temp  
        └─upload                        //上传文件

使用须知

1.允许用于个人学习、毕业设计、教学案例、公益事业;

2.支持企业/个人免费商业使用,但必须保留leadshop版权信息;

版权信息

Powered By Leadshop © 2021

继续阅读 »

Leadshop的开发背景

传统的电商平台(这里指的是淘宝、京东、拼多多这类型的中心化平台)早已是红海,商家越来越难生存,平台规则越来越严格,稍有不慎,前功尽弃,商家长期苦不堪言。

有痛点就有市场机会,这是市场规律。

近年来崛起的私域saas电商平台如雨后春笋般侵袭而来,如有赞、微盟等。商家也逐步觉醒,不再单一的依赖传统中心化大平台了,逐步布局自己的私域流量平台。

私域电商软件成了必不可少的工具之一,大批saas服务商尝到了甜头。

但是好景不长,这块蛋糕不仅被腾讯盯上了,腾讯还想做规则制定者,微信即微信小店之后又推出了微信小商店,无缝衔接视频号及直播带货,同时开放了服务市场,将私域电商推向高潮,大批saas类的服务商开始坐不住了,跟微信小商店竞争胜算如何呢?

传统电商,saas私域电商好像和我们开发者关系不是很大,在电商领域我们开发者有什么机会呢?

随着商家越来越重视私域流量、客户数据、个性化的商业模式,私域saas电商模式很难满足这么多个性化需求,不少商家开始选择招技术团队或外包公司进行个性化的定制开发,但是从0开发一套成熟的电商系统要付出的成本是极大,可以说是无底洞,说实话没几个商家能够承受的了。

Leadshop非常想解决这个行业痛点,所以Leadshop诞生了!它是为终端商家,为开发者而生的一款免费且开源的电商系统。

Leadshop一款提供持续更新服务的免费开源商城系统,旨在打造极致的用户体验。
Leadshop已经实现了从0到1的研发,我们开发者只需要在此基础上进行客户的个性化需求开发便可满足客户需求,从而以最低成本创造增值收益。

Leadshop主要特性

Leadshop 开源系统,基于Yii2开发,支持composer,优化核心,减少依赖,基于全新的架构思想和命名空间

  • 基于命名空间和PSR-4规范,加入PHP7新特性
  • 核心功能模块化,方便开发和维护
  • 强化路由功能,采用RESTful接口标准
  • 灵活创建模型控制器,易于扩展开发
  • 配置文件可分离,方便管理
  • 重写的自动验证和完成
  • 简化扩展机制,提升开发速度
  • API支持完善,方便二次开发
  • 内置WeChat微信开发框架,微信接入更加快捷,简单
  • 使用ORM自动创建表结构,提升开发速度
  • 支持数据库结构、数据、模板在线缓存清除,提升用户体验
  • 客户端完善的交互效果和动画,提升用户端视觉体验
  • 支持在线一键安装,方便快捷。
  • 可视化DIY店铺装修,方便、快捷、直观,可以随心所欲装扮自己的店铺
  • 高效的笛卡尔乘积运算,8000条规格秒加载
  • 拟态Windows文件夹的素材管理结构,操作更熟悉随心

运行环境

Linux+Nginx+PHP7.4+MySQL5.7.3以上

插件市场的地址

https://ext.dcloud.net.cn/plugin?id=4699

体验后台

地址:https://demo.leadshop.vip
账号:18888888888
密码:123456
tiyan.png

Leadshop页面展示

展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图

<br/>

展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图
展示图

Leadshop微商城

论坛交流

地址:https://forum.leadshop.vip/

开源无加密

基于Apache License 2.0开源协议,前后端代码开源无加密,支持二次开发,支持商用。

核心技术

前端技术栈 ES6、vue、vuex、vue-router、vue-cli、axios、element-ui、uni-app

后端技术栈 Yii2、Jwt、Mysql、Easy-SMS

接口标准

采用标准RESTful API ,高效的API阅读性,具有扩展性强、结构清晰的特点

数据交互

采用JSON API 标准,用以定义客户端如何获取与修改资源,以及服务器如何响应对应请求。高效实现的同时,无需牺牲可读性、灵活性和可发现性

认证方式

目前所有的接口使用 Oauth2 Password 方式,也就是 JWT Authorization Bearer header 进认证。支持扩语言扩展,多平台扩展。

数据表格导出

采用高性能的 js-xlsx数据导出,易于扩展,兼容性强。

接口文档:http://www.leadshop.vip/api.html

安装

一键安装

1.上传你的代码

2.项目目录设置755权限

3.设置代码执行目录为/web

注:如果使用Apache环境 需要在.htaccess 中添加

 SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

否则会导致OAuth登录模式获取不到Authorization

4.检查php禁用函数列表,symlink函数不能被禁用,否则后台页面无法访问。

5.在浏览器中输入你的域名或IP

( 例如:www.yourdomain.com),安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装。

6.后台访问地址:
域名/index.php?r=admin

7.公众号首页访问地址:
域名/index.php?r=wechat

重新安装

  1. 清除数据库
  2. 删除/server/install.lock 文件

目录说明

 站点根目录  
    ├─api                               //后台接口  
    ├─app                               //客户端(微信小程序,公众号)  
    ├─applet                            //打包后的微信小程序源码包  
    ├─components                        //通用组件  
    ├─config                            //配置文件目录  
    ├─controllers                       //控制器  
    ├─datamodel                         //模型  
    ├─forms                               
    │  └─install  
    ├─modules                           //模块       
    ├─stores                            //应用配置文件  
    ├─system                            //系统核心目录  
    │  ├─common  
    │  ├─config  
    │  ├─phpqrcode  
    │  └─wechat  
    ├─vendor                            //依赖  
    ├─views  
    │  ├─admin                          //后台编译包目录,其中index.php不可删除  
    │  ├─wechat                         //公众号编译包目录,其中index.php不可删除  
    │  └─site  
    └─web  
        ├─assets  
        ├─static                        //静态文件  
        ├─img                           //H5端图片目录  
        ├─temp  
        └─upload                        //上传文件

使用须知

1.允许用于个人学习、毕业设计、教学案例、公益事业;

2.支持企业/个人免费商业使用,但必须保留leadshop版权信息;

版权信息

Powered By Leadshop © 2021

收起阅读 »