
推荐 微信开发者工具Linux版
可以在星火应用商店安装,也可以在github下载
https://github.com/msojocs/wechat-web-devtools-linux/releases/tag/v1.06.2407120-1
可以在星火应用商店安装,也可以在github下载
https://github.com/msojocs/wechat-web-devtools-linux/releases/tag/v1.06.2407120-1

vue3+tauri2.0+element-plus桌面端exe聊天模板|vite5+tauri2仿QQ/微信客户端程序
趁着国庆假期,我的又一款原创重磅新作Vue3.5+Tauri2.0+Vite5.4+Pinia2+ElementPlus
跨平台实战仿QQ/微信电脑端聊天Exe程序Vue3Tauri2Chat,正式的完结了。整体UI采用全新无边框透明圆角阴影窗体。
Vue3+Tauri2.0聊天实例|tauri2+vite5+element-plus仿微信|tauri聊天应用
封装tauri2.x多开窗口管理、换肤壁纸、自定义系统托盘闪烁/右键菜单功能。实现聊天、联系人、收藏、朋友圈、短视频、我的等页面模块。
运用技术
- 编码工具:Vscode
- 技术框架:tauri2.0+vite^5.4+vue^3.5+vue-router^4.4.5
- 状态管理:pinia^2.2.2
- 本地存储插件:pinia-plugin-persistedstate^4.0.2
- 组件库:element-plus^2.8.3
- 富文本编辑器:@vueup/vue-quill^1.2.0
- 样式预处理:sass^1.79.3
- 视频滑动组件:swiper^11.1.14
目前tauri2-vue3chat聊天项目已经发布到我的原创作品集,有需要的话可以去瞅瞅~
https://gf.bilibili.com/item/detail/1107133011
tauri2-vue3chat项目布局模板
<template>
<div class="vu__chatbox">
<template v-if="!route?.meta?.isNewWin">
<div class="vu__container flexbox flex-alignc flex-justifyc">
<div class="vu__layout flexbox flex-col">
<div class="vu__layout-body flex1 flexbox" @contextmenu.prevent>
<!-- 菜单栏 -->
<slot v-if="!route?.meta?.hideMenuBar" name="menubar">
<MenuBar />
</slot>
<!-- 侧边栏 -->
<div v-if="route?.meta?.showSideBar" class="vu__layout-sidebar flexbox">
<aside class="vu__layout-sidebar__body flexbox flex-col">
<slot name="sidebar">
<SideBar />
</slot>
</aside>
</div>
<!-- 主内容区 -->
<div class="vu__layout-main flex1 flexbox flex-col">
<ToolBar v-if="!route?.meta?.hideToolBar" />
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</div>
</div>
</div>
</div>
</template>
<template v-else>
<WinLayout />
</template>
</div>
</template>
tauri2多窗口实践
// 朋友圈窗口
const handleFzone = () => {
winCreate({
label: 'win-fzone',
url: '/win/fzone',
title: '朋友圈',
width: 500,
height: 695,
minWidth: 350,
minHeight: 500,
maximizable: false,
})
}
// 短视频窗口
const handleFvideo = () => {
winCreate({
label: 'win-fvideo',
url: '/win/fvideo',
title: '短视频',
width: 575,
height: 675,
minWidth: 415,
minHeight: 545
})
}
// 换肤壁纸窗口
const handleSkin = () => {
winCreate({
label: 'win-skin',
url: '/win/skin',
title: '壁纸',
width: 375,
height: 480,
resizable: false,
maximizable: false,
visible: true,
})
}
// 界面管理器
const handleManageUI = () => {
winCreate({
label: 'win-manage',
url: '/win/manage',
title: '界面管理器',
width: 320,
height: 360,
resizable: false,
maximizable: false,
})
}
之前有过一篇关于tauri2创建多窗口应用的分享文章,可以去看看。
基于Tauri2+Vite5搭建桌面端程序|tauri2+vue3多窗口|消息提醒|托盘闪烁
vue3+tauri2自定义透明圆角阴影窗体
.vu__chatbox {height: calc(100vh); padding: 5px; overflow: hidden;}
.vu__layout {
background-color: #f5f5f5;
overflow: hidden;
height: 100%; width: 100%;
position: relative; z-index: 100;
border-radius: 8px;
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.15),0 1px 5px -1px rgba(0, 0, 0, 0.1),0 2px 5px rgba(0, 0, 0, 0.1);
}
<script setup>
/**
* tauri2.0自定义系统最大化/最小化/关闭 by andy Q:282310962
*/
// ...
const props = defineProps({
color: String,
// 窗口是否可最小化
minimizable: {type: [Boolean, String], default: true},
// 窗口是否可最大化
maximizable: {type: [Boolean, String], default: true},
// 窗口是否可关闭
closable: {type: [Boolean, String], default: true},
// 层级
zIndex: {type: [Number, String], default: 2024},
// 关闭前回调,会暂停实例关闭 function(done),done用于关闭
beforeClose: Function
})
const hasMaximized = ref(false)
const isResizable = ref(true)
const isMaximizable = ref(true)
// 用户是否可以手动调整窗口大小
getCurrentWindow().isResizable().then(res => {
isResizable.value = res
})
// 窗口是否可以最大化
getCurrentWindow().isMaximizable().then(res => {
isMaximizable.value = res
})
// 初始监听窗口是否最大化
getCurrentWindow().isMaximized().then(res => {
hasMaximized.value = res
})
// 实时监听窗口是否最大化
listen('tauri://resize', async() => {
hasMaximized.value = await getCurrentWindow().isMaximized()
})
// 最小化
const handleWinMin = async() => {
// winSet('minimize')
await getCurrentWindow().minimize()
}
// 最大化/还原
const handleWinToggle = async() => {
// winSet('max2min')
await getCurrentWindow().toggleMaximize()
}
// 关闭
const handleClose = async() => {
const isMajor = getCurrentWindow().label.indexOf('main') > -1
if(isMajor) {
let el = layer({
type: 'android',
content: '是否最小化到托盘,不退出程序?',
layerStyle: 'background: #f9f9f9; border-radius: 8px;',
closable: false,
resize: false,
btns: [
{
text: '最小化托盘',
style: 'color: #646cff',
click: () => {
layer.close(el)
// winSet('hide')
await getCurrentWindow().hide()
}
},
{
text: '退出程序',
style: 'color: #fa5151',
click: async() => {
authstate.logout()
await exit()
}
}
]
})
}else {
// winSet('close')
await getCurrentWindow().close()
}
}
</script>
<template>
<div class="ev__winbtns vu__drag" :style="{'z-index': zIndex}">
<div class="ev__winbtns-actions vu__undrag" :style="{'color': color}">
<a v-if="isTrue(minimizable)" class="wbtn min" title="最小化" @click="handleWinMin"><i class="wicon elec-icon elec-icon-min"></i></a>
<a v-if="isTrue(maximizable) && isResizable && isMaximizable" class="wbtn toggle" :title="hasMaximized ? '向下还原' : '最大化'" @click="handleWinToggle">
<i class="wicon elec-icon iconfont" :class="hasMaximized ? 've-icon-shrink' : 've-icon-arrowsalt'"></i>
</a>
<a v-if="isTrue(closable)" class="wbtn close" title="关闭" @click="handleClose"><i class="wicon elec-icon elec-icon-quit"></i></a>
</div>
</div>
</template>
综上就是vue3+tauri2.x实战桌面端聊天项目的一些知识分享。
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000045331960
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
趁着国庆假期,我的又一款原创重磅新作Vue3.5+Tauri2.0+Vite5.4+Pinia2+ElementPlus
跨平台实战仿QQ/微信电脑端聊天Exe程序Vue3Tauri2Chat,正式的完结了。整体UI采用全新无边框透明圆角阴影窗体。
Vue3+Tauri2.0聊天实例|tauri2+vite5+element-plus仿微信|tauri聊天应用
封装tauri2.x多开窗口管理、换肤壁纸、自定义系统托盘闪烁/右键菜单功能。实现聊天、联系人、收藏、朋友圈、短视频、我的等页面模块。
运用技术
- 编码工具:Vscode
- 技术框架:tauri2.0+vite^5.4+vue^3.5+vue-router^4.4.5
- 状态管理:pinia^2.2.2
- 本地存储插件:pinia-plugin-persistedstate^4.0.2
- 组件库:element-plus^2.8.3
- 富文本编辑器:@vueup/vue-quill^1.2.0
- 样式预处理:sass^1.79.3
- 视频滑动组件:swiper^11.1.14
目前tauri2-vue3chat聊天项目已经发布到我的原创作品集,有需要的话可以去瞅瞅~
https://gf.bilibili.com/item/detail/1107133011
tauri2-vue3chat项目布局模板
<template>
<div class="vu__chatbox">
<template v-if="!route?.meta?.isNewWin">
<div class="vu__container flexbox flex-alignc flex-justifyc">
<div class="vu__layout flexbox flex-col">
<div class="vu__layout-body flex1 flexbox" @contextmenu.prevent>
<!-- 菜单栏 -->
<slot v-if="!route?.meta?.hideMenuBar" name="menubar">
<MenuBar />
</slot>
<!-- 侧边栏 -->
<div v-if="route?.meta?.showSideBar" class="vu__layout-sidebar flexbox">
<aside class="vu__layout-sidebar__body flexbox flex-col">
<slot name="sidebar">
<SideBar />
</slot>
</aside>
</div>
<!-- 主内容区 -->
<div class="vu__layout-main flex1 flexbox flex-col">
<ToolBar v-if="!route?.meta?.hideToolBar" />
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</div>
</div>
</div>
</div>
</template>
<template v-else>
<WinLayout />
</template>
</div>
</template>
tauri2多窗口实践
// 朋友圈窗口
const handleFzone = () => {
winCreate({
label: 'win-fzone',
url: '/win/fzone',
title: '朋友圈',
width: 500,
height: 695,
minWidth: 350,
minHeight: 500,
maximizable: false,
})
}
// 短视频窗口
const handleFvideo = () => {
winCreate({
label: 'win-fvideo',
url: '/win/fvideo',
title: '短视频',
width: 575,
height: 675,
minWidth: 415,
minHeight: 545
})
}
// 换肤壁纸窗口
const handleSkin = () => {
winCreate({
label: 'win-skin',
url: '/win/skin',
title: '壁纸',
width: 375,
height: 480,
resizable: false,
maximizable: false,
visible: true,
})
}
// 界面管理器
const handleManageUI = () => {
winCreate({
label: 'win-manage',
url: '/win/manage',
title: '界面管理器',
width: 320,
height: 360,
resizable: false,
maximizable: false,
})
}
之前有过一篇关于tauri2创建多窗口应用的分享文章,可以去看看。
基于Tauri2+Vite5搭建桌面端程序|tauri2+vue3多窗口|消息提醒|托盘闪烁
vue3+tauri2自定义透明圆角阴影窗体
.vu__chatbox {height: calc(100vh); padding: 5px; overflow: hidden;}
.vu__layout {
background-color: #f5f5f5;
overflow: hidden;
height: 100%; width: 100%;
position: relative; z-index: 100;
border-radius: 8px;
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.15),0 1px 5px -1px rgba(0, 0, 0, 0.1),0 2px 5px rgba(0, 0, 0, 0.1);
}
<script setup>
/**
* tauri2.0自定义系统最大化/最小化/关闭 by andy Q:282310962
*/
// ...
const props = defineProps({
color: String,
// 窗口是否可最小化
minimizable: {type: [Boolean, String], default: true},
// 窗口是否可最大化
maximizable: {type: [Boolean, String], default: true},
// 窗口是否可关闭
closable: {type: [Boolean, String], default: true},
// 层级
zIndex: {type: [Number, String], default: 2024},
// 关闭前回调,会暂停实例关闭 function(done),done用于关闭
beforeClose: Function
})
const hasMaximized = ref(false)
const isResizable = ref(true)
const isMaximizable = ref(true)
// 用户是否可以手动调整窗口大小
getCurrentWindow().isResizable().then(res => {
isResizable.value = res
})
// 窗口是否可以最大化
getCurrentWindow().isMaximizable().then(res => {
isMaximizable.value = res
})
// 初始监听窗口是否最大化
getCurrentWindow().isMaximized().then(res => {
hasMaximized.value = res
})
// 实时监听窗口是否最大化
listen('tauri://resize', async() => {
hasMaximized.value = await getCurrentWindow().isMaximized()
})
// 最小化
const handleWinMin = async() => {
// winSet('minimize')
await getCurrentWindow().minimize()
}
// 最大化/还原
const handleWinToggle = async() => {
// winSet('max2min')
await getCurrentWindow().toggleMaximize()
}
// 关闭
const handleClose = async() => {
const isMajor = getCurrentWindow().label.indexOf('main') > -1
if(isMajor) {
let el = layer({
type: 'android',
content: '是否最小化到托盘,不退出程序?',
layerStyle: 'background: #f9f9f9; border-radius: 8px;',
closable: false,
resize: false,
btns: [
{
text: '最小化托盘',
style: 'color: #646cff',
click: () => {
layer.close(el)
// winSet('hide')
await getCurrentWindow().hide()
}
},
{
text: '退出程序',
style: 'color: #fa5151',
click: async() => {
authstate.logout()
await exit()
}
}
]
})
}else {
// winSet('close')
await getCurrentWindow().close()
}
}
</script>
<template>
<div class="ev__winbtns vu__drag" :style="{'z-index': zIndex}">
<div class="ev__winbtns-actions vu__undrag" :style="{'color': color}">
<a v-if="isTrue(minimizable)" class="wbtn min" title="最小化" @click="handleWinMin"><i class="wicon elec-icon elec-icon-min"></i></a>
<a v-if="isTrue(maximizable) && isResizable && isMaximizable" class="wbtn toggle" :title="hasMaximized ? '向下还原' : '最大化'" @click="handleWinToggle">
<i class="wicon elec-icon iconfont" :class="hasMaximized ? 've-icon-shrink' : 've-icon-arrowsalt'"></i>
</a>
<a v-if="isTrue(closable)" class="wbtn close" title="关闭" @click="handleClose"><i class="wicon elec-icon elec-icon-quit"></i></a>
</div>
</div>
</template>
综上就是vue3+tauri2.x实战桌面端聊天项目的一些知识分享。
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000045331960
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

生鲜配送系统具备哪些核心功能?搭建生鲜配送系统有哪些显著优势?
生鲜配送系统是一种专门为生鲜产品配送设计的软件系统,它通过整合供应链中的各个环节,实现生鲜产品的高效管理和配送。
生鲜配送系统的主要功能:
订单管理:
用户可以通过系统快速下单,商家可以在线接收订单,有效防止错单和漏单,提高接单效率。

智能采购:
系统可以根据销售数据智能预测需求,实现以销定采,减少生鲜产品的浪费和损耗。
价格管理:
支持智能批量改价,商家可以根据市场变化快速调整价格,实现精细化运营。
库存管理:
实时监控库存情况,自动补货提醒,确保库存的合理性。
分拣系统:
自动化分拣系统,提高分拣效率和准确性。
打印系统:
自动化打印订单、标签等,减少人工操作。
配送管理:
集成配送路线规划,优化配送路径,提高配送效率。
报表统计:
提供销售、库存、配送等数据的报表统计,帮助商家分析业务情况,做出更好的决策。
客户关系管理:
管理客户信息,维护客户关系,提高客户满意度。
质量控制:
监控生鲜产品的质量,确保食品安全。
搭建生鲜配送系统的好处:
提高效率:
自动化和智能化的功能减少了人工操作,提高了整体的工作效率。
减少损耗:
通过智能采购和库存管理,减少了生鲜产品的浪费和损耗。
提升客户满意度:
快速响应客户需求,提供更好的客户服务。
优化成本:
通过精细化运营,降低运营成本。
增强竞争力:
提供更好的服务和产品,增强市场竞争力。
数据分析:
通过报表统计,帮助商家更好地理解市场和客户需求,做出更明智的业务决策。
食品安全:
通过质量控制,确保生鲜产品的安全。
可扩展性:系统可以根据业务的发展进行扩展,适应不断变化的市场。
提高透明度:提供订单和配送的实时跟踪,提高业务的透明度。
环境友好:减少浪费,符合可持续发展的要求。
生鲜配送系统通过整合技术和资源,为生鲜配送行业提供了一种高效、智能的解决方案,帮助商家在竞争激烈的市场中获得优势。
联系我们
生鲜配送系统是一种专门为生鲜产品配送设计的软件系统,它通过整合供应链中的各个环节,实现生鲜产品的高效管理和配送。
生鲜配送系统的主要功能:
订单管理:
用户可以通过系统快速下单,商家可以在线接收订单,有效防止错单和漏单,提高接单效率。
智能采购:
系统可以根据销售数据智能预测需求,实现以销定采,减少生鲜产品的浪费和损耗。
价格管理:
支持智能批量改价,商家可以根据市场变化快速调整价格,实现精细化运营。
库存管理:
实时监控库存情况,自动补货提醒,确保库存的合理性。
分拣系统:
自动化分拣系统,提高分拣效率和准确性。
打印系统:
自动化打印订单、标签等,减少人工操作。
配送管理:
集成配送路线规划,优化配送路径,提高配送效率。
报表统计:
提供销售、库存、配送等数据的报表统计,帮助商家分析业务情况,做出更好的决策。
客户关系管理:
管理客户信息,维护客户关系,提高客户满意度。
质量控制:
监控生鲜产品的质量,确保食品安全。
搭建生鲜配送系统的好处:
提高效率:
自动化和智能化的功能减少了人工操作,提高了整体的工作效率。
减少损耗:
通过智能采购和库存管理,减少了生鲜产品的浪费和损耗。
提升客户满意度:
快速响应客户需求,提供更好的客户服务。
优化成本:
通过精细化运营,降低运营成本。
增强竞争力:
提供更好的服务和产品,增强市场竞争力。
数据分析:
通过报表统计,帮助商家更好地理解市场和客户需求,做出更明智的业务决策。
食品安全:
通过质量控制,确保生鲜产品的安全。
可扩展性:系统可以根据业务的发展进行扩展,适应不断变化的市场。
提高透明度:提供订单和配送的实时跟踪,提高业务的透明度。
环境友好:减少浪费,符合可持续发展的要求。
生鲜配送系统通过整合技术和资源,为生鲜配送行业提供了一种高效、智能的解决方案,帮助商家在竞争激烈的市场中获得优势。
联系我们
收起阅读 »
eportJSException >>>> exception function:createInstanceContext,
需求:uniapp开发项目最终运行在Android真机;
操作:uniapp开发过程中全程在chrome浏览器中运行,开发完成后在Android真机运行,之后出现如下错误
这里重点关注划线区域,具体的错误就是这里
> Cannot read property 'http' of undefined
参考这篇文章找到解决方案:关于Vue3中调试APP触发异常
我的修改如下:
就是把const http = uni.$uv.http 放在了函数中,至此问题解决。
最后吐槽一下,这个问题编辑面板真的难用
需求:uniapp开发项目最终运行在Android真机;
操作:uniapp开发过程中全程在chrome浏览器中运行,开发完成后在Android真机运行,之后出现如下错误
这里重点关注划线区域,具体的错误就是这里
> Cannot read property 'http' of undefined
参考这篇文章找到解决方案:关于Vue3中调试APP触发异常
我的修改如下:
就是把const http = uni.$uv.http 放在了函数中,至此问题解决。
最后吐槽一下,这个问题编辑面板真的难用
收起阅读 »
为什么发布tm还要我登录啊,紧接着就是登录、验证、手机绑定验证、到最后发布,跟我说什么该应用不属于我,我真的会谢
为什么发布tm还要我登录啊,紧接着就是登录、验证、手机绑定验证、到最后发布,跟我说什么该应用不属于我,我真的会谢
国产,你这样玩,我还用你干嘛
为什么发布tm还要我登录啊,紧接着就是登录、验证、手机绑定验证、到最后发布,跟我说什么该应用不属于我,我真的会谢
国产,你这样玩,我还用你干嘛

uni.onBLECharacteristicValueChange 遇到的问题
问题:uni.onBLECharacteristicValueChange 无法监听到第二次 uni.writeBLECharacteristicValue 特征值写入。
ps:代码就不描述了,写一下流程
描述:初始化蓝牙->启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值->监听蓝牙特征值变化->writeBLECharacteristicValue 下发参数给设备
->onBLECharacteristicValueChange 正常监听到特征值变化,成功获取报文->此时获取到成功报文后我又执行了,启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值(此时的uuid,服务id,特征值id,都应需求原因不予第一次获取的一致)->未调用蓝牙特征值变化方法,因为第一次已经调用(后续试过再次调用结果也一致,失败)
->onBLECharacteristicValueChange 未监听到特征值变化,无报文。
解决:在onBLECharacteristicValueChange 中获取到第一次成功报文后,断开与低功耗蓝牙设备的连接uni.closeBLEConnection,再次初始化蓝牙->启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值->监听蓝牙特征值变化->writeBLECharacteristicValue 下发参数给设备 -> 又可以成功获取到 onBLECharacteristicValueChange 特征值变化,成功获取报文。
问题:uni.onBLECharacteristicValueChange 无法监听到第二次 uni.writeBLECharacteristicValue 特征值写入。
ps:代码就不描述了,写一下流程
描述:初始化蓝牙->启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值->监听蓝牙特征值变化->writeBLECharacteristicValue 下发参数给设备
->onBLECharacteristicValueChange 正常监听到特征值变化,成功获取报文->此时获取到成功报文后我又执行了,启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值(此时的uuid,服务id,特征值id,都应需求原因不予第一次获取的一致)->未调用蓝牙特征值变化方法,因为第一次已经调用(后续试过再次调用结果也一致,失败)
->onBLECharacteristicValueChange 未监听到特征值变化,无报文。
解决:在onBLECharacteristicValueChange 中获取到第一次成功报文后,断开与低功耗蓝牙设备的连接uni.closeBLEConnection,再次初始化蓝牙->启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值->监听蓝牙特征值变化->writeBLECharacteristicValue 下发参数给设备 -> 又可以成功获取到 onBLECharacteristicValueChange 特征值变化,成功获取报文。

Ai绘图系统搭建教程
应用名称:Aai绘图工具
支持Ai功能:文生图、图生图、艺术二维码、Ai消除去水印、局部重绘、老照片修复、高清放大、图片转漫画、图片扩展、Ai抠图
绘图费用
一般生图费用:0.09/张,包含高清修复的:0.15/张
如果用量较多可以拿到半价:0.045/张,包含高清修复的:0.075/张
如果用量更多,联系开发者可以拿到更低价
支持平台(支持uniCloud阿里云空间)
1:支持微信H5公众号版 PC电脑版。(需要已认证的微信公众号)
2:支持微信小程序。(上架需申请Ai绘图类目,可使用第三方合同申请Ai类目,使用第三个合同比较简单,开发者可指导协作完成)
3:支持支付宝小程序。(无需Ai类目,工具类目即可上架)
4:支持抖音小程序。(必须深度算法合成备案才能上架)
应用演示
1:H5客户端体验地址(手机版更优) [http://www.msshequ.cn/ai/](http://www.msshequ.cn/ai/#/)
2:微信小程序
3:支付宝小程序
源码下载
客户端(ai-image):https://ext.dcloud.net.cn/plugin?id=12217
ai-image可打包成 H5、微信小程序、支付宝小程序、抖音小程序 并发布
管理端(ai-image-admin):https://ext.dcloud.net.cn/plugin?id=12211
ai-image-admin可打包成H5发布,用于管理配置客户端,或者说是站长的控制台,站长自己用不要对外开放
开通uniCloud阿里云服务空间
开通地址:https://unicloud.dcloud.net.cn/
建议按量付费,请使用阿里云服务,其他服务可能不兼容
下载HBuilder开发工具:https://www.dcloud.io/hbuilderx.html
如果图片不显示无法看到截图教程请看
csdn文章教程:https://blog.csdn.net/weixin_43197263/article/details/142580962
掘金文章教程:https://juejin.cn/post/7418548134593396745
小程序域名白名单
请求域名:api.next.bspapp.com、sd-json.oss-cn-hongkong.aliyuncs.com
下载域名:sd-json.oss-cn-hongkong.aliyuncs.com
除了阿里云自带的请求域名外,请求和下载还要额外添加:sd-json.oss-cn-hongkong.aliyuncs.com,该域名是Ai绘图回调的文件地址,
Ai回调有些是JSON数据,有些是图片地址,所有需要把该域名添加到请求域名,和下载域名
同时你unicloud的上传域名,和下载域名也要添加,unicloud空间查看域名
安装教程
先安装ai-image-admin,导入HBuilder 后关联阿里云空间,HBuilder下载地址:https://www.dcloud.io/hbuilderx.html
初始化云数据库
如果弹窗窗口直接覆盖
等待初始化完成
上传所有云函数及公共模块
如果弹出窗口直接替换
等待上传完成
再安装ai-image,必须一起安装完在测试使用,步骤与上面都差不多
导入HBuilder后关联阿里云空间
初始化云数据库
如果弹出询问窗直接覆盖
等待初始化完成
上传所有云函数及公共模块
如果弹出询问窗直接替换
等待上传完成
发布管理端(ai-image-admin)得先发布管理端完成小程序配置才能发布小程序端
ai-image-admin发行 网站-PC,并关联你的uniCloud阿里云空间一般会自动上传
如果无法自动上传,需要手动上传,先等待打包完成
打开打包完成的目录地址,把web改成admin,方便上传,因为打包的H5运行路径(会改的话可以自己改路径)就是admin,所有要用admin
上传文件到云空间,这里上传的是unicloud,如果你用其他云空间托管也可以上传其他云空间,记得配置跨域
配置跨域
访问管理端,在默认域名后面添加目录/admin
管理端初始化账号:admin
管理端初始化密码:112233
添加一个小程序,获取mymp_id,这里以支付宝小程序为例
在ai-image客户端配置mymp_id,就可以运行或者打包ai-image项目了
不用全部配置,要发布支付宝小程序,就修改mp-alipay的参数,要上架哪个平台就修改对应平台的mymp_id就行
发布到支付宝小程序
注意:是ai-image项目。建议先运行测试没问题在打包发布,不会运行测试的直接打包发布应该也没问题(开发者已经测试好没问题了)
应用名称:Aai绘图工具
支持Ai功能:文生图、图生图、艺术二维码、Ai消除去水印、局部重绘、老照片修复、高清放大、图片转漫画、图片扩展、Ai抠图
绘图费用
一般生图费用:0.09/张,包含高清修复的:0.15/张
如果用量较多可以拿到半价:0.045/张,包含高清修复的:0.075/张
如果用量更多,联系开发者可以拿到更低价
支持平台(支持uniCloud阿里云空间)
1:支持微信H5公众号版 PC电脑版。(需要已认证的微信公众号)
2:支持微信小程序。(上架需申请Ai绘图类目,可使用第三方合同申请Ai类目,使用第三个合同比较简单,开发者可指导协作完成)
3:支持支付宝小程序。(无需Ai类目,工具类目即可上架)
4:支持抖音小程序。(必须深度算法合成备案才能上架)
应用演示
1:H5客户端体验地址(手机版更优) [http://www.msshequ.cn/ai/](http://www.msshequ.cn/ai/#/)
2:微信小程序
3:支付宝小程序
源码下载
客户端(ai-image):https://ext.dcloud.net.cn/plugin?id=12217
ai-image可打包成 H5、微信小程序、支付宝小程序、抖音小程序 并发布
管理端(ai-image-admin):https://ext.dcloud.net.cn/plugin?id=12211
ai-image-admin可打包成H5发布,用于管理配置客户端,或者说是站长的控制台,站长自己用不要对外开放
开通uniCloud阿里云服务空间
开通地址:https://unicloud.dcloud.net.cn/
建议按量付费,请使用阿里云服务,其他服务可能不兼容
下载HBuilder开发工具:https://www.dcloud.io/hbuilderx.html
如果图片不显示无法看到截图教程请看
csdn文章教程:https://blog.csdn.net/weixin_43197263/article/details/142580962
掘金文章教程:https://juejin.cn/post/7418548134593396745
小程序域名白名单
请求域名:api.next.bspapp.com、sd-json.oss-cn-hongkong.aliyuncs.com
下载域名:sd-json.oss-cn-hongkong.aliyuncs.com
除了阿里云自带的请求域名外,请求和下载还要额外添加:sd-json.oss-cn-hongkong.aliyuncs.com,该域名是Ai绘图回调的文件地址,
Ai回调有些是JSON数据,有些是图片地址,所有需要把该域名添加到请求域名,和下载域名
同时你unicloud的上传域名,和下载域名也要添加,unicloud空间查看域名
安装教程
先安装ai-image-admin,导入HBuilder 后关联阿里云空间,HBuilder下载地址:https://www.dcloud.io/hbuilderx.html
初始化云数据库
如果弹窗窗口直接覆盖
等待初始化完成
上传所有云函数及公共模块
如果弹出窗口直接替换
等待上传完成
再安装ai-image,必须一起安装完在测试使用,步骤与上面都差不多
导入HBuilder后关联阿里云空间
初始化云数据库
如果弹出询问窗直接覆盖
等待初始化完成
上传所有云函数及公共模块
如果弹出询问窗直接替换
等待上传完成
发布管理端(ai-image-admin)得先发布管理端完成小程序配置才能发布小程序端
ai-image-admin发行 网站-PC,并关联你的uniCloud阿里云空间一般会自动上传
如果无法自动上传,需要手动上传,先等待打包完成
打开打包完成的目录地址,把web改成admin,方便上传,因为打包的H5运行路径(会改的话可以自己改路径)就是admin,所有要用admin
上传文件到云空间,这里上传的是unicloud,如果你用其他云空间托管也可以上传其他云空间,记得配置跨域
配置跨域
访问管理端,在默认域名后面添加目录/admin
管理端初始化账号:admin
管理端初始化密码:112233
添加一个小程序,获取mymp_id,这里以支付宝小程序为例
在ai-image客户端配置mymp_id,就可以运行或者打包ai-image项目了
不用全部配置,要发布支付宝小程序,就修改mp-alipay的参数,要上架哪个平台就修改对应平台的mymp_id就行
发布到支付宝小程序
注意:是ai-image项目。建议先运行测试没问题在打包发布,不会运行测试的直接打包发布应该也没问题(开发者已经测试好没问题了)

智慧社区管理系统平台:城市管理好助手(附源码)
智慧社区:构建未来生活的新篇章
在信息化与智能化浪潮的推动下,智慧社区作为一种全新的社区治理模式正悄然兴起。它深度融合大数据、云计算、人工智能等前沿技术,整合社区各类服务资源,旨在打造一个安全、便捷、高效的居住环境。本文将从智慧安防、智慧服务、智慧物业、智慧生活四个方面,深入剖析智慧社区的建设实践及其带来的变革。
一、智慧社区的核心功能
社区信息管理:作为智慧社区的基础,社区信息管理涵盖了小区院落、人员信息、组织机构等多个方面。通过构建全面的社区数据库,实现对社区内各类信息的集中管理和实时更新,为社区管理和居民服务提供有力支撑。
人房关系管理:智慧社区通过人房关系管理系统,能够清晰地掌握社区内居民与房屋之间的对应关系。这不仅有助于提升社区管理的精准度,还能在紧急情况下迅速定位到相关人员,确保社区安全。
居民信息审核:为了保障社区的安全与秩序,智慧社区对居民信息进行严格的审核与管理。通过线上提交、线下审核的方式,确保居民信息的真实性和准确性,为社区提供更加可靠的居民服务。
组织机构管理:智慧社区还注重组织机构的管理与协调。通过构建完善的组织机构管理体系,明确各职能部门的职责与权限,实现社区管理的规范化和高效化。
二、智慧物业:高效管理的创新实践
智慧物业是智慧社区的重要组成部分。通过引入智能化管理系统,物业公司能够实现对社区设施、环境、人员等要素的精细化管理。利用物联网技术,对社区内的照明、安防、消防等设备进行远程监控和智能控制,降低能耗和维护成本。同时,建立居民反馈机制,及时收集和处理居民的意见和建议,提升物业服务质量和效率。智慧物业不仅减轻了物业公司的管理负担,还提高了居民对物业服务的满意度和信任度。
代码示例:
//智慧社区大屏Jenkinsfile
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
stage('npm install') {
steps {
sh 'npm install'
}
}
stage('npm build') {
steps {
sh 'npm run build'
}
}
stage('tar and rsync') {
steps {
sh 'tar zcvf dist.tar.gz dist/'
sh 'rsync -avzt dist.tar.gz rsync@192.168.201.73::zhsq-dp --password-file=/etc/rsync.pass'
sh 'rsync -avzt dist.tar.gz rsync@192.168.201.74::zhsq-dp --password-file=/etc/rsync.pass'
}
}
}
}
联系我们
智慧社区:构建未来生活的新篇章
在信息化与智能化浪潮的推动下,智慧社区作为一种全新的社区治理模式正悄然兴起。它深度融合大数据、云计算、人工智能等前沿技术,整合社区各类服务资源,旨在打造一个安全、便捷、高效的居住环境。本文将从智慧安防、智慧服务、智慧物业、智慧生活四个方面,深入剖析智慧社区的建设实践及其带来的变革。
一、智慧社区的核心功能
社区信息管理:作为智慧社区的基础,社区信息管理涵盖了小区院落、人员信息、组织机构等多个方面。通过构建全面的社区数据库,实现对社区内各类信息的集中管理和实时更新,为社区管理和居民服务提供有力支撑。
人房关系管理:智慧社区通过人房关系管理系统,能够清晰地掌握社区内居民与房屋之间的对应关系。这不仅有助于提升社区管理的精准度,还能在紧急情况下迅速定位到相关人员,确保社区安全。
居民信息审核:为了保障社区的安全与秩序,智慧社区对居民信息进行严格的审核与管理。通过线上提交、线下审核的方式,确保居民信息的真实性和准确性,为社区提供更加可靠的居民服务。
组织机构管理:智慧社区还注重组织机构的管理与协调。通过构建完善的组织机构管理体系,明确各职能部门的职责与权限,实现社区管理的规范化和高效化。
二、智慧物业:高效管理的创新实践
智慧物业是智慧社区的重要组成部分。通过引入智能化管理系统,物业公司能够实现对社区设施、环境、人员等要素的精细化管理。利用物联网技术,对社区内的照明、安防、消防等设备进行远程监控和智能控制,降低能耗和维护成本。同时,建立居民反馈机制,及时收集和处理居民的意见和建议,提升物业服务质量和效率。智慧物业不仅减轻了物业公司的管理负担,还提高了居民对物业服务的满意度和信任度。
代码示例:
//智慧社区大屏Jenkinsfile
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
stage('npm install') {
steps {
sh 'npm install'
}
}
stage('npm build') {
steps {
sh 'npm run build'
}
}
stage('tar and rsync') {
steps {
sh 'tar zcvf dist.tar.gz dist/'
sh 'rsync -avzt dist.tar.gz rsync@192.168.201.73::zhsq-dp --password-file=/etc/rsync.pass'
sh 'rsync -avzt dist.tar.gz rsync@192.168.201.74::zhsq-dp --password-file=/etc/rsync.pass'
}
}
}
}
联系我们

生鲜配送系统软件推荐:鲜橙生鲜配送系统(附源码)
一、解决传统痛点,提升运营效率
传统生鲜配送模式面临着诸多痛点:人工分拣效率低下、数据记录易出错、仓储物流管理复杂等。这些问题不仅增加了企业的运营成本,还严重影响了客户体验。而一款优秀的生鲜配送系统,能够全面解决这些痛点。通过自动化、智能化的技术手段,系统能够大幅提升分拣效率,减少人为错误,实现数据的实时同步与精准管理。同时,系统还能优化仓储布局和物流配送路线,降低物流成本,提升整体运营效率。
二、功能全面,满足多元化需求
一款优秀的生鲜配送系统,其功能应当全面而强大,以满足企业多元化的需求。从商品管理到价格管理,从采购管理到库存管理,再到财务管理和数据分析,系统应涵盖生鲜配送的各个环节。具体而言,系统应支持商品多规格管理、价格差异化设置、自动化采购单汇总、库存实时监控等功能;
三、灵活定制,适应企业发展
每个生鲜企业都有其独特的发展阶段和业务模式,因此一款优秀的生鲜配送系统应具备高度的灵活性和可定制性。系统应能够根据企业的实际需求进行个性化定制,以适应不同规模、不同业态的生鲜企业。无论是初创型企业还是成熟的大型企业,都能在系统中找到适合自己的解决方案。
**Jeecg-Boot 低代码开发平台
当前最新版本: 3.2.0(发布日期:20220425)
后端技术架构
基础框架:Spring Boot 2.6.6
持久层框架:Mybatis-plus 3.5.1
安全框架:Apache Shiro 1.8.0,Jwt 3.11.0
数据库连接池:阿里巴巴Druid 1.1.22
缓存框架:redis
日志打印:logback
其他:fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
开发环境
语言:Java 8
IDE(JAVA): Eclipse安装lombok插件 或者 IDEA
依赖管理:Maven
数据库:MySQL5.7+ & Oracle 11g & SqlServer & postgresql & 国产等更多数据库
缓存:Redis
代码示例:
@GetMapping(value = "/list")
public Result<IPage<JeecgDemo>> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<JeecgDemo>> result = new Result<IPage<JeecgDemo>>();
//调用QueryGenerator的initQueryWrapper
QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize);
IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}**
联系我们:
一、解决传统痛点,提升运营效率
传统生鲜配送模式面临着诸多痛点:人工分拣效率低下、数据记录易出错、仓储物流管理复杂等。这些问题不仅增加了企业的运营成本,还严重影响了客户体验。而一款优秀的生鲜配送系统,能够全面解决这些痛点。通过自动化、智能化的技术手段,系统能够大幅提升分拣效率,减少人为错误,实现数据的实时同步与精准管理。同时,系统还能优化仓储布局和物流配送路线,降低物流成本,提升整体运营效率。
二、功能全面,满足多元化需求
一款优秀的生鲜配送系统,其功能应当全面而强大,以满足企业多元化的需求。从商品管理到价格管理,从采购管理到库存管理,再到财务管理和数据分析,系统应涵盖生鲜配送的各个环节。具体而言,系统应支持商品多规格管理、价格差异化设置、自动化采购单汇总、库存实时监控等功能;
三、灵活定制,适应企业发展
每个生鲜企业都有其独特的发展阶段和业务模式,因此一款优秀的生鲜配送系统应具备高度的灵活性和可定制性。系统应能够根据企业的实际需求进行个性化定制,以适应不同规模、不同业态的生鲜企业。无论是初创型企业还是成熟的大型企业,都能在系统中找到适合自己的解决方案。
**Jeecg-Boot 低代码开发平台
当前最新版本: 3.2.0(发布日期:20220425)
后端技术架构
基础框架:Spring Boot 2.6.6
持久层框架:Mybatis-plus 3.5.1
安全框架:Apache Shiro 1.8.0,Jwt 3.11.0
数据库连接池:阿里巴巴Druid 1.1.22
缓存框架:redis
日志打印:logback
其他:fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
开发环境
语言:Java 8
IDE(JAVA): Eclipse安装lombok插件 或者 IDEA
依赖管理:Maven
数据库:MySQL5.7+ & Oracle 11g & SqlServer & postgresql & 国产等更多数据库
缓存:Redis
代码示例:
@GetMapping(value = "/list")
public Result<IPage<JeecgDemo>> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<JeecgDemo>> result = new Result<IPage<JeecgDemo>>();
//调用QueryGenerator的initQueryWrapper
QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize);
IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}**
联系我们:
收起阅读 »
uniapp-x不支持瀑布流列表,望解决
uniapp-x 希望可以支持最基本,瀑布流,和普通的,一行显示2个或者多个item的情况 这也算最基本的列表功能了吧
uniapp-x 希望可以支持最基本,瀑布流,和普通的,一行显示2个或者多个item的情况 这也算最基本的列表功能了吧

uniapp App map地图组件+subnvues弹窗,路由跳转后再进页面时subnvues弹窗有缓存的问题!
hbuildX版本:4.24
uniapp:vue3(默认模板,不包含uniapp-x)
注:只是分享,之前是做pc端的,刚接触uniapp,不清楚这个问题在历代uniapp更新中是否被解决,但是我在开发中遇到了,所以就发出来了。
情景描述:在一个除顶部菜单的全屏地图中,添加自定义控件,因为map地图层级很高,故使用subnvues,进行控件展示,包含两个方形小按钮,一个是定位自己,一个是点击进行弹窗,在弹窗中在进行操作,然后就发现了退出当前路由,再进入时,弹窗会出现重复!
解决办法:反正是困扰了一下午,无意中发现,将地图代码注释之后,再执行退出进入的操作,就不会出现这种情况,经过漫长的时间琢磨,给地图组件加上v-if,一是在subnvues弹窗之前将地图隐掉,执行完弹窗操作后,再显示出来,就只是一瞬,有用,二是,在退出当前页面时提前将地图隐掉,再执行页面跳转,就一个异步执行代码;
//打开菜单弹窗
const OpenMenuPopu = ()=>{
MapIsShow.value = false;
ChoiceMenuExample.value = uni.getSubNVueById('MultipleChoiceMenu');
ChoiceMenuExample.value.show('slide-in-bottom',600);
uni.$emit('FatherCheckboxValue',FatherCheckboxValue.value)
MapIsShow.value = true;
}
//返回首页
const GoHome = () => {
MapIsShow.value = false;
MyAMap.value = null;
let time = setTimeout(()=>{
uni.redirectTo({
url: '/pages/Home/index'
});
clearTimeout(time);
},10)
uni.$emit('FatherCheckboxValue',[]);
uni.$off('SearchData')
uni.$off('FatherCheckboxValue')
uni.$off('ControlID')
uni.$off('CheckboxValue')
}
onBackPress(()=>{
GoHome();
return true;
})
hbuildX版本:4.24
uniapp:vue3(默认模板,不包含uniapp-x)
注:只是分享,之前是做pc端的,刚接触uniapp,不清楚这个问题在历代uniapp更新中是否被解决,但是我在开发中遇到了,所以就发出来了。
情景描述:在一个除顶部菜单的全屏地图中,添加自定义控件,因为map地图层级很高,故使用subnvues,进行控件展示,包含两个方形小按钮,一个是定位自己,一个是点击进行弹窗,在弹窗中在进行操作,然后就发现了退出当前路由,再进入时,弹窗会出现重复!
解决办法:反正是困扰了一下午,无意中发现,将地图代码注释之后,再执行退出进入的操作,就不会出现这种情况,经过漫长的时间琢磨,给地图组件加上v-if,一是在subnvues弹窗之前将地图隐掉,执行完弹窗操作后,再显示出来,就只是一瞬,有用,二是,在退出当前页面时提前将地图隐掉,再执行页面跳转,就一个异步执行代码;
//打开菜单弹窗
const OpenMenuPopu = ()=>{
MapIsShow.value = false;
ChoiceMenuExample.value = uni.getSubNVueById('MultipleChoiceMenu');
ChoiceMenuExample.value.show('slide-in-bottom',600);
uni.$emit('FatherCheckboxValue',FatherCheckboxValue.value)
MapIsShow.value = true;
}
//返回首页
const GoHome = () => {
MapIsShow.value = false;
MyAMap.value = null;
let time = setTimeout(()=>{
uni.redirectTo({
url: '/pages/Home/index'
});
clearTimeout(time);
},10)
uni.$emit('FatherCheckboxValue',[]);
uni.$off('SearchData')
uni.$off('FatherCheckboxValue')
uni.$off('ControlID')
uni.$off('CheckboxValue')
}
onBackPress(()=>{
GoHome();
return true;
})
收起阅读 »

【经验分享】【微信小程序】简单在已有账号系统基础上引入uni-id使用clientDB的权限管理
折腾了一下午,终于给我的小程序成功引入了uni-id,之前每次想到要迁移就头大,今天终于下定决心换到clientDB了,也是为了减少云函数的用量。在这里就简单分享一下校验。
参考:https://en.uniapp.dcloud.io/uniCloud/uni-id.html(这个教程是老的uni-id,对我够用了,不想迁移到新版)
安装uni-id
- 导入插件。
- 写config-center的配置,复制上面教程的文件只需要改mp-weixin.oauth.weixin内的appid和secret。
- 创建uni-id-users和opendb-verify-codes表,后者用于验证码对小程序其实不必要,但我不知道删了能不能跑。
以上几步可以简单的安装好uni-id,然后便是迁移工作了。
迁移
首先我希望我的权限是依赖于openid的,所以我便利了我自己搭建的账号数据库,并逐条写入uni-id-user表,只需要写两个字段_id和wx_openid.mp-weixin,这两个字段同时设置为原先的openid。
登录
之后按照文档的微信登录段,新建一个云函数,内容如下
const uniID = require("uni-id");
exports.main = async function (event, context) {
// const res = await uniID.loginByWeixin(event.code)
const res = await uniID.loginByWeixin({
code: event.code,
});
return res;
};
注意这个云函数要选择公共依赖uni-id,安装的uni-id也需要选择公共依赖uni-open-bridge-common(我不知道为什么默认没选)。
以上是官方文档的,我将其修改为了
'use strict';
const uniID = require('uni-id');
const db = uniCloud.database();
const dbUID = db.collection('uni-id-users');
exports.main = async function (event) {
const res = await uniID.loginByWeixin({ code: event.code });
if (res.uid !== res.openid) {
await dbUID.doc(res.openid).set((await dbUID.doc(res.uid).field({ _id: false }).get()).data[0]);
await dbUID.doc(res.uid).remove();
res.uid = res.openid;
res.tokenExpired = 0;
}
return res;
};
因为默认第一次登录的账户他会新建一条记录,而这条记录的uid不是原有的openid,所以需要手动修改。
同时修改以后原先的token是作废的,所以使用tokenExpired=0来让客户端手动重新二次调用。(每次都需要上传一个只能用一次的code)
然后我客户端用这个云函数取代了我原先用于获取openid的云函数,因为这个也会返回openid,正好还能登录一举两得。
角色
另一方面为了用上uni-id的角色系统,我还在我自己的关于权限变更的云函数里同时变更uni-id-users表的role字段,这样clientDB也可以用角色控制了xd
折腾了一下午,终于给我的小程序成功引入了uni-id,之前每次想到要迁移就头大,今天终于下定决心换到clientDB了,也是为了减少云函数的用量。在这里就简单分享一下校验。
参考:https://en.uniapp.dcloud.io/uniCloud/uni-id.html(这个教程是老的uni-id,对我够用了,不想迁移到新版)
安装uni-id
- 导入插件。
- 写config-center的配置,复制上面教程的文件只需要改mp-weixin.oauth.weixin内的appid和secret。
- 创建uni-id-users和opendb-verify-codes表,后者用于验证码对小程序其实不必要,但我不知道删了能不能跑。
以上几步可以简单的安装好uni-id,然后便是迁移工作了。
迁移
首先我希望我的权限是依赖于openid的,所以我便利了我自己搭建的账号数据库,并逐条写入uni-id-user表,只需要写两个字段_id和wx_openid.mp-weixin,这两个字段同时设置为原先的openid。
登录
之后按照文档的微信登录段,新建一个云函数,内容如下
const uniID = require("uni-id");
exports.main = async function (event, context) {
// const res = await uniID.loginByWeixin(event.code)
const res = await uniID.loginByWeixin({
code: event.code,
});
return res;
};
注意这个云函数要选择公共依赖uni-id,安装的uni-id也需要选择公共依赖uni-open-bridge-common(我不知道为什么默认没选)。
以上是官方文档的,我将其修改为了
'use strict';
const uniID = require('uni-id');
const db = uniCloud.database();
const dbUID = db.collection('uni-id-users');
exports.main = async function (event) {
const res = await uniID.loginByWeixin({ code: event.code });
if (res.uid !== res.openid) {
await dbUID.doc(res.openid).set((await dbUID.doc(res.uid).field({ _id: false }).get()).data[0]);
await dbUID.doc(res.uid).remove();
res.uid = res.openid;
res.tokenExpired = 0;
}
return res;
};
因为默认第一次登录的账户他会新建一条记录,而这条记录的uid不是原有的openid,所以需要手动修改。
同时修改以后原先的token是作废的,所以使用tokenExpired=0来让客户端手动重新二次调用。(每次都需要上传一个只能用一次的code)
然后我客户端用这个云函数取代了我原先用于获取openid的云函数,因为这个也会返回openid,正好还能登录一举两得。
角色
另一方面为了用上uni-id的角色系统,我还在我自己的关于权限变更的云函数里同时变更uni-id-users表的role字段,这样clientDB也可以用角色控制了xd
收起阅读 »