first commit

This commit is contained in:
wtq
2025-11-28 10:35:11 +08:00
commit 9ed8a3de94
121 changed files with 30962 additions and 0 deletions

18
src/App.vue Normal file
View File

@@ -0,0 +1,18 @@
<script>
const dialog = require("@/components/dialog/dialogUtil");
export default {
data: function () {
return {};
},
onLaunch: function () {
uni["dialog"] = dialog;
},
methods: {},
};
</script>
<style lang="scss">
@import "./uni.scss";
</style>

3
src/androidPrivacy.json Normal file
View File

@@ -0,0 +1,3 @@
{
"prompt" : "template"
}

19
src/api/common/config.js Normal file
View File

@@ -0,0 +1,19 @@
/**
* model: 配置文件
* 作者zhang-shu-wei
* 日期2022年8月10日
* 邮箱2966211270@qq.com
*/
let url_config = '' // 用户登录
if (process.env.NODE_ENV === 'development') {
// 开发环境 配置域名
url_config = "https://print.jxc4.com/"
} else {
// 生产环境
url_config = "https://print.jxc4.com/"
}
export default url_config

171
src/api/common/index.js Normal file
View File

@@ -0,0 +1,171 @@
/**
* model: 接口大全
* 作者zhang-shu-wei
* 日期2022年8月10日
* 邮箱2966211270@qq.com
* 注意POST, GET 必须大写要兼容其他应用
* 1是需要token 2是不需要token
*/
import request from '@/api/common/request.js'
import { param } from '@dcloudio/vue-cli-plugin-uni/packages/postcss/tags'
const api = {}
// 获取微信手机号 不需要token
api.login = async params => {
let data = {
code: params
}
return await request.allRequest('v1/app_no/getUserPhone', 'POST', data, 2)
}
// 微信登录 不需要token
api.wxLogin = async params => {
return await request.allRequest('v1/app_no/login', 'POST', params, 2)
}
// 获取手机验证码 不需要token
api.getPhoneCode = async params => {
let data = {
phone_number: params
}
return await request.allRequest('v1/app_no/sendVerifyCode', 'POST', data, 2)
}
// 使用手机验证码登录
api.phoneLogin = async params => {
return await request.allRequest('v1/app_no/loginMobile', 'POST', params, 2)
}
// 查询打印机是否绑定 不需要token
api.setPrinterBind = async params => {
return await request.allRequest('v1/app_no/getPrintIsUse', 'GET', params, 2)
}
// 添加打印机 需要token
api.addPrinter = async params => {
return await request.allRequest('v2/app_need/addPrinters', 'POST', params, 1)
}
// 查询打印机列表 需要token
api.setPrinterList = async params => {
return await request.allRequest('v2/app_need/getPrinters', 'GET', params, 1)
}
// 删除打印机 需要token (没有使用删除,打印机坏掉了或者没有用了直接显示下线就可以了)
api.delPrinter = async params => {
return await request.allRequest('v2/app_need/delPrinters', 'POST', params, 1)
}
// 修改打印机 需要token
api.determinePrinter = async params => {
return await request.allRequest('v2/app_need/updatePrinter', 'POST', params, 1)
}
// 打印机 信息统计 需要token
api.printerMsgSum = async params => {
return await request.allRequest('v2/app_need/statPrinter', 'GET', params, 1)
}
// 测试打印机打印内容 需要token
api.printerText = async params => {
return await request.allRequest('v2/app_need/testPrinter', 'POST', params, 1)
}
// 获取用户模板 需要token
api.getUserModel = async params => {
return await request.allRequest('v2/app_need/temp/getUserTempList', 'GET', params, 1)
}
// 添加模板
api.addModel = async params => {
return await request.allRequest('v2/app_need/temp/addOrUpdateTemp', 'POST', params, 1)
}
// 删除用户模板
api.delModel = async params => {
return await request.allRequest('v2/app_need/temp/deleteTemp', 'DELETE', params, 1)
}
// 切换用户自定义模板
api.setModel = async params => {
return await request.allRequest('v2/app_need/temp/switchTemp', 'GET', params, 1)
}
// 查询用户打印机生硬设置
api.setModelSound = async params => {
return await request.allRequest('v2/app_need/setting/getPrintSetting', 'GET', params, 1)
}
// 修改打印机声音
api.updataMOdelSound = async params => {
return await request.allRequest('v2/app_need/setting/updatePrintSetting', 'POST', params, 1)
}
// 获取首页轮播图、公告、帮助
api.img_notice_help = async params => {
return await request.allRequest('v2/notice/selectNoticeAddress', 'POST', params, 2)
}
// 获取管理系统token
api.getMengerToken = async params => {
return await request.allRequest('v2/app_need/getToken4Jxc4', 'POST', params, 1)
}
/**
* 导出请求
*/
export default api

132
src/api/common/request.js Normal file
View File

@@ -0,0 +1,132 @@
/**
* model: 接口请求配置文件
* 作者zhang-shu-wei
* 日期2022年8月10日
* 邮箱2966211270@qq.com
*/
import urlConfig from '@/api/common/config.js'
import zsw from '@/utils/tool.js'
import Vue from 'vue'
let newThis = new Vue()
const request = {}
request.allRequest = (url, methos, data, power) => {
// 在500 毫秒内数据就返回了就不展示加载图 防止闪屏 优化用户体验
newThis.$wx.showLoading()
// console.log
/**
* 权限判断 不一样的接口headers里面携带的参数是不一样的
* 1 === 需要 token 的接口
* 2 === 不需要 token 的接口
*/
// 先从vuex 里面读取数据提高效率
var token = 'null'
if (power == 1) {
if (newThis.$store.state.Authorization) {
token = `token=${newThis.$store.state.Authorization}`
} else {
token = `token=${uni.getStorageSync('token')}`
newThis.$store.commit('setToken', uni.getStorageSync('token'))
}
}
/**
* 全局存储userid 防止刷新页面丢失
*/
if (!newThis.$store.state.userId) {
newThis.$store.commit('setUserId', uni.getStorageSync('userId'))
}
/**
* 判断是啥请求
* post 需要携带 content-type
* get 不用携带 content-type
* DELETE 要携带 custom-header: 'delete'
*
*/
switch (methos) {
case 'POST':
var options = {
'content-type': 'application/x-www-form-urlencoded',
'cookie': token,
}
break
case 'GET':
var options = {
'content-type': 'application/x-www-form-urlencoded',
'cookie': token,
}
break
case 'DELETE':
var options = {
'content-type': 'application/json',
'custom-header': 'delete',
'cookie': token,
}
break
}
/**
* 请求接口
*/
return new Promise((resolve, reject) => {
uni.request({
url: urlConfig + url,
method: methos,
data: data,
timeout: 10000,
dataType: 'json',
header: {
...options
},
success: (res) => {
newThis.$wx.hideLoading()
if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data.code == 0) {
resolve(res.data)
} else if (res.data.code == -1000) {
uni.dialog.alert("温馨提示", "身份认证失败,请登录", () => {
uni.removeStorageSync('token')
uni.removeStorageSync('userInfor')
uni.removeStorageSync('userPhone')
uni.removeStorageSync('peinterList')
uni.setStorageSync('printerName', 'null')
uni.removeStorageSync('userId')
newThis.$store.commit('setUserPhone', null)
newThis.$store.commit('setToken', null)
newThis.$store.commit('setMyUserDat', null)
newThis.$store.commit('setUserId', null)
uni.reLaunch({
url: '/subPackages/login/loginPhone/loginPhone'
})
}, "好的")
} else {
// zsw.toast('请求出错', 2) 暂时只把错误丢出去
resolve(res.data)
}
} else if (res.statusCode >= 400 && res.statusCode < 500) {
zsw.toast('客户端错误', 2)
} else if (res.statusCode >= 500) {
zsw.toast('服务器错误', 2)
} else {
zsw.toast('网络错误', 2)
}
},
fail: (err) => {
newThis.$wx.hideLoading()
zsw.toast('网络请求超时', 2)
console.log(err, '网络请求超时抛出错误 -- request.js')
}
})
})
}
export default request

View File

@@ -0,0 +1,53 @@
export default {
/* 链接处理 */
getLink(params){
let url = "/components/dialog/dialog";
if(params){
let paramStr = "";
for(let name in params){
paramStr+=`&${name}=${params[name]}`
}
if(paramStr){
url +=`?${paramStr.substr(1)}`
}
}
return url;
},
/* APP全局弹窗 */
dialog(params={},callback){
uni.navigateTo({
url:this.getLink(params),
success(e) {
uni.$off("wujw_common_dialog");
uni.$on("wujw_common_dialog",(type)=>{
callback&&callback(type)
})
}
})
},
/*弹出提示弹窗 */
alert(data={},callback,close){
let params = {type:"alert",isCloseBtn:'0',isMaskClose:'0',...data};
this.dialog(params,(type)=>{
if("confirm"==type){
callback&&callback()
}else {
close&&close()
}
})
},
/*确认提示框弹窗 */
confirm(data={},confirm,cancel,close){
let params = {type:"confirm",isCloseBtn:'0',isMaskClose:'0',...data};
this.dialog(params,(type)=>{
if("confirm"==type){
confirm&&confirm()
}else if("cancel"==type){
cancel&&cancel()
}else if("close"==type){
close&&close()
}
})
},
}

View File

@@ -0,0 +1,147 @@
<template>
<view @click="itemClick('mask')" class="mask-content">
<view class="dialog-content" @click.stop="">
<view class="head-content " v-if="info.title" :style="info.content?'':'min-height:90rpx;padding:30rpx'">
<text >{{info.title}}</text>
</view>
<scroll-view class="main-content" scroll-y v-if="info.content">
<view class="info-content">
<text >{{info.content}}</text>
</view>
</scroll-view>
<view class="foot-content alert" v-if="'alert'==info.type" >
<view class="btn active" @click.stop="itemClick('confirm')">
{{info.confirmText}}
</view>
</view>
<view class="foot-content confirm" v-if="'confirm'==info.type" >
<view class="btn cancel" @click="itemClick('cancel')">
{{info.cancelText}}
</view>
<view class="btn active" @click.stop="itemClick('confirm')">
{{info.confirmText}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
info:{
type:"alert",//alert:单按钮,confirm:双按钮
title:"",//
content:"",
cancelText:"取消",
confirmText:"确定",
isMaskClose:"1",//1点击遮罩层关闭弹窗
}
}
},
onLoad(info={}) {
this.info = {...this.info,...info};
},
methods: {
itemClick(type){
if(type=="mask"&&this.info.isMaskClose!='1'){
return;
}
uni.navigateBack()
uni.$emit("wujw_common_dialog",type);
}
}
}
</script>
<style lang="scss">
$btncolor: $zsw-prinmary-color;
page {
background: transparent;
}
.mask-content {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.4);
.dialog-content {
background-color: #FFFFFF;
width: 560rpx;
border-radius: 25rpx;
.head-content{
display: flex;
align-items: center;
justify-content: center;
color: #343434;
font-weight: bold;
font-size: 32rpx;
padding: 20rpx 30rpx;
}
.main-content{
max-height: 350rpx;
.info-content{
min-height: 80rpx;
padding: 10rpx 30rpx;
color: #636463;
font-size: 30rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
.foot-content{
display: flex;
justify-content: center;
align-items: center;
border-top: 1rpx solid #e4e4e4;
height: 110rpx;
.btn{
font-size: 28rpx;
height: 66rpx;
display: flex;
justify-content: center;
align-items: center;
}
&.alert{
.btn{
color: $btncolor;
font-size: 28rpx;
height: 66rpx;
width: 300rpx;
padding: 0 40rpx;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
}
}
&.confirm{
justify-content: space-around;
.btn{
min-width: 230rpx;
&.active{
border-left: 1rpx solid #e4e4e4;
color: $btncolor;
font-weight: bold;
}
&.cancel{
color: rgb(77, 77, 77);
font-weight: bold;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,55 @@
import dialog from "@/components/dialog/dialog.js"
module.exports = {
/**
* 弹出提示
*/
alert(title = "", content = "", callback,confirmText = '确定') {
// #ifdef APP-PLUS
dialog.alert({
content,
title,confirmText
}, callback)
// #endif
// #ifndef APP-PLUS
uni.showModal({
title,
content,confirmText,
showCancel: false,
confirmColor: "#007aff",
success: callback
})
// #endif
},
/**
* 确认提示框
*/
confirm(title = "", content = "", confirm, cancel, confirmText = '确定', cancelText = '取消') {
// #ifdef APP-PLUS
dialog.confirm({
content,
title,
confirmText,
cancelText,
}, confirm, cancel)
// #endif
// #ifndef APP-PLUS
uni.showModal({
title,
content,
cancelText,
confirmText,
confirmColor: "#007aff",
success: (e) => {
if (e.confirm) {
confirm && confirm()
} else if (e.cancel) {
cancel && cancel()
}
},
fail: (e) => {
console.log(e)
}
})
// #endif
},
}

View File

@@ -0,0 +1,70 @@
<template>
<view class="noList" :style="{'marginTop': top}">
<img :src="iconImg" v-if="iconImg != ''" alt="">
<i class="iconfont" :class="icon" v-else></i>
<span :style="{'color': textColor}">{{title}}</span>
</view>
</template>
<script>
/**
* 空状态组件
* 作者zhagn-shu-wei
* 日期2022年8月16日
* 邮箱2966211270@qq.com
*
* title // 空状态提示文字
* icon // 空状态图标
* iconImg // 空状态图片
* textColor // 空状态颜色
* top: // 空状态距离顶部位置
*/
export default {
props: {
'title': {
type: String,
default: '暂无此类信息!'
},
'icon': {
type: String,
default: 'icon-empty'
},
'iconImg': {
type: String,
default: ''
},
'textColor': {
type: String,
default: 'rgb(116, 116, 116)'
},
'top': {
type: String,
default: '25vh'
}
}
}
</script>
<style lang="scss" scoped>
.noList{
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
font-size: 34rpx;
text-align: center;
color: #d5d5d5;
.iconfont{
font-size: 200rpx;
}
img{
width: 250rpx;
height: 250rpx;
margin-bottom: -40rpx;
}
}
</style>

View File

@@ -0,0 +1,91 @@
const popUp = (url) => {
let time = undefined
// 加载弹窗
const showLoading = ({title='加载中...'}={}) => {
let iconUrl = url || ''
//#ifdef APP-PLUS
plus.nativeUI.showWaiting(title, {
color : '#646464',
background : 'rgba(255,255,255,0.5)',
round : '10px',
size: '23px',
loading : {
display : 'block',
icon : '/static/img/demo.png',
height:'60px',
interval : '50ms'
}
});
//#endif
//#ifdef H5
let div = document.createElement('div')
div.className = 'loadingDiv'
let loadingHtml = `
<div class="loadingDiv-box">
<div class="loadingDiv-box-window">
<img src="${iconUrl}" style="display : none; mode="widthFix" alt="加载中..." class="loadingDiv-box-img" />
<div class="loadingDiv-box-icon" style="background-image: url(${iconUrl});"></div>
</div>
<div class="loadingDiv-box-title">${title}</div>
</div>`
;
div.innerHTML = loadingHtml
document.body.appendChild(div);
let imgData = document.querySelector('.loadingDiv-box-img');
let scale = imgData.naturalHeight ? imgData.naturalWidth/imgData.naturalHeight : 0
let img = document.querySelector('.loadingDiv-box-icon');
let n = 0
time = setInterval(() => {
img.style.backgroundPosition = `${-n*30}px 0px`;
n++;
if(n >= scale){
n = 0
}
}, 100)
//#endif
//#ifndef APP-PLUS || H5
uni.showLoading({
title: title
});
//#endif
}
// 取消加载弹窗
const hideLoading = () => {
//#ifdef APP-PLUS
plus.nativeUI.closeWaiting()
//#endif
//#ifdef H5
let parent = document.querySelector('.loadingDiv');
document.body.removeChild(parent)
clearInterval(time)
time = undefined
//#endif
//#ifndef APP-PLUS || H5
uni.hideLoading();
//#endif
}
// 普通弹窗提示
const showToast = ({title='',duration=1500,icon='none'}) => {
//#ifdef APP-PLUS
plus.nativeUI.toast(title,{
duration : duration
})
//#endif
//#ifndef APP-PLUS
uni.showToast({
title : title,
duration : duration,
icon : icon
});
//#endif
}
return {
showLoading,
hideLoading,
showToast
}
}
export {
popUp
}

View File

@@ -0,0 +1,242 @@
<template>
<view>
<uni-popup ref="popup" :mask-click="false" :is-mask-click="false">
<view class="popup-root">
<p>{{title}}</p>
<span class="prompt">注意{{promptText}}<span class="complaint" @tap="playPhone">点击拨号</span></span>
<view class="input">
<view class="input-item mask" :class="{'error': rulerPhone}">
<i class="iconfont icon-shoujihaoma" :class="{'font-error': rulerPhone}"></i>
<input v-model="userPhoneSlice" disabled type="text" :placeholder="phoneText">
</view>
<view class="input-item send-code" :class="{'error': rulerCode}">
<i class="iconfont icon-yanzhengyanzhengma" :class="{'font-error': rulerCode}"></i>
<input v-model="code" type="text" placeholder="验证码">
<span @tap="sendCode">{{sendCOde}}</span>
</view>
</view>
<view class="foot-btn">
<p @tap="$refs.popup.close()">{{leftText}}</p>
<p @tap="removePrinter">{{rightText}}</p>
</view>
</view>
</uni-popup>
<uni-popup ref="message" type="message">
<uni-popup-message style="text-align: center;" :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
/**
* 手机号验证模态框
* 作者: zhang-shu-wei
* 日期2022年8月15日
* 邮箱2966211270@qq.com
*
* data()
* rulerPhone: false, // 手机号验证
* code: null, // 手机验证码
* rulerCode: false, // 验证码验证
* msgType: null, // 顶部提示信息
* messageText: null, // 提示文字
*
* props[]
* sendCOde // 按钮提示文字
* title // 标题提示文字
* phoneText // 手机号码提示文字
* promptText // 注意提示文字
* leftText // 取消按钮文字
* rightText // 确定按钮文字
* Unbinding // 解绑打印机的手机号码
*
* 方法
* @determine // 确定按钮 可以获取到手机号 验证码
* @send // 发送验证码按钮 不传递参数
*/
export default {
props: {
sendCOde: {
type: String,
default: '发送验证码'
},
title: {
type: String,
default: '提示标题'
},
phoneText: {
type: String,
default: '提示文字'
},
promptText: {
type: String
},
leftText: {
type: String,
default: '取消'
},
rightText: {
type: String,
default: '确定'
},
Unbinding: {
type: String,
default: ''
}
},
data() {
return {
rulerPhone: false, // 手机号验证
code: null, // 手机验证码
rulerCode: false, // 验证码验证
msgType: null, // 顶部提示信息
messageText: null, // 提示文字
}
},
methods: {
removePrinter() {
this.rulerPhone = false
let rulerCode = /^\d{6}$/
if(!rulerCode.test(this.code)) {
this.rulerCode = true
this.msgType = 'error'
this.messageText = '验证码输入错误'
this.$refs.message.open()
return
}
this.rulerCode = false
this.$emit('determine', {
phone: this.Unbinding,
code: this.code
})
},
sendCode() {
this.rulerPhone = false
this.$emit('send', this.Unbinding)
},
playPhone() {
//#ifdef MP-WEIXIN
uni.makePhoneCall({
phoneNumber: '18048531223'
});
//#endif
//#ifdef APP-PLUS
plus.device.dial('18048531223', true);
//#endif
}
},
computed: {
userPhoneSlice() {
let s = this.Unbinding
let result1 = s.slice(0,3)
let result2 = s.slice(7)
let newPhone = result1 + '****' + result2
return newPhone
},
}
}
</script>
<style lang="scss" scoped>
.popup-root{
box-sizing: border-box;
margin: 0 25rpx;
background-color: #fff;
border-radius: 25rpx;
padding: 30rpx 30rpx 0rpx 30rpx;
&>span{
display: inline-block;
color: #e70808;
margin-top: 30rpx;
font-size: 26rpx;
padding: 0 15rpx;
}
&>p{
text-align: center;
color: #858585;
}
.prompt{
line-height: 50rpx;
}
.complaint{
height: 50rpx;
line-height: 50rpx;
padding: 0 25rpx;
display: inline-block;
background-color: #0a99ff;
color: #fff;
display: inline-block;
margin-left: 15rpx;
border-radius: 6rpx;
}
.input{
.mask{
background-color: #eeeeee;
}
}
.input>view{
box-sizing: border-box;
display: flex;
align-items: center;
border: 1rpx solid #dddddd;
border-radius: 15rpx;
padding: 20rpx 15rpx;
margin-top: 20rpx;
i{
margin-right: 15rpx;
}
input{
width: 100%;
}
span{
white-space: nowrap;
padding: 8rpx 15rpx;
border-radius: 10rpx;
white-space: nowrap;
font-size: 25rpx;
background-color: $zsw-prinmary-color;
color: #fff;
}
}
.foot-btn{
display: flex;
margin-top: 30rpx;
border-top: 1rpx solid #dddddd;
height: 80rpx;
line-height: 80rpx;
p{
width: 100%;
text-align: center;
}
p:nth-child(2) {
color: $zsw-prinmary-color;
border-left: 1rpx solid #dddddd;
}
}
}
.error{
border: 1rpx solid #e70808 !important;
}
.font-error {
color: #e70808;
}
</style>

25
src/main.js Normal file
View File

@@ -0,0 +1,25 @@
import Vue from 'vue'
import App from './App'
import store from './store'
import api from '@/api/common/index.js'
import zsw from '@/utils/tool.js'
import {popUp as wx} from '@/components/zsw-loading/index.js'
// 全局mixins用于实现setData, 用于wifi 配置网等功能,请勿删除!';
import Mixin from './utils/polyfill/mixins';
Vue.mixin(Mixin);
Vue.prototype.$wx = wx('../../static/img/demo.png')//加载动画的图片地址
Vue.config.productionTip = false
Vue.prototype.$store = store
Vue.prototype.$api = api
Vue.prototype.$zsw = zsw
App.mpType = 'app'
const app = new Vue({
...App,
store
})
app.$mount()

145
src/manifest.json Normal file
View File

@@ -0,0 +1,145 @@
{
"name" : "京西云",
"appid" : "__UNI__5FD9BBB",
"description" : "",
"versionName" : "2.7.4",
"versionCode" : 274,
"transformPx" : false,
/* 5+App */
"app-plus" : {
"compatible" : {
"runtimeVersion" : "3.5.3", //根据实际情况填写
"compilerVersion" : "3.6.5" //根据实际情况填写
},
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {
"OAuth" : {},
"Payment" : {},
"Share" : {}
},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
],
"abiFilters" : [ "armeabi-v7a", "x86" ]
},
/* ios */
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {
"ad" : {},
"oauth" : {
"weixin" : {
"appid" : "wx02f8a2b1bb111064",
"UniversalLinks" : ""
}
},
"payment" : {
"weixin" : {
"__platform__" : [ "android" ],
"appid" : "wx02f8a2b1bb111064",
"UniversalLinks" : ""
}
},
"push" : {},
"share" : {
"weixin" : {
"appid" : "wx02f8a2b1bb111064",
"UniversalLinks" : ""
}
}
},
"icons" : {
"android" : {
"hdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/logo/72.png",
"xhdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/logo/96.png",
"xxhdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/logo/144.png",
"xxxhdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/logo/192.png"
},
"ios" : {
"appstore" : "E:/wtq/交接文档new/京西云打印机/其它/素材/logo/1024.png"
}
},
"splashscreen" : {
"androidStyle" : "default",
"android" : {
"hdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/启动开屏图/480x762_png.png",
"xhdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/启动开屏图/720x1242_png.png",
"xxhdpi" : "E:/wtq/交接文档new/京西云打印机/其它/素材/启动开屏图/1080x1882_png.png"
},
"useOriginalMsgbox" : true
}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx2bfbc02e6251b71b",
"setting" : {
"urlCheck" : true,
"minified" : true,
"postcss" : true
},
"usingComponents" : true,
"plugins" : {
"airkiss" : {
"version" : "1.1.2",
"provider" : "wx610ea582556c983e"
}
},
"optimization" : {
"subPackages" : true
},
"lazyCodeLoading" : "requiredComponents"
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2",
"h5" : {
"title" : "京西云",
"router" : {
"mode" : "hash",
"base" : "/printer/"
}
}
}

229
src/pages.json Normal file
View File

@@ -0,0 +1,229 @@
{
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false
}
},
{
"path": "pages/printerSetUp/printerSetUp",
"style": {
"navigationBarTitleText": "打印设置",
"enablePullDownRefresh": true
}
},
{
"path": "pages/personalCenter/personalCenter",
"style": {
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": true
}
},
{
"path": "components/dialog/dialog",
"style": {
"navigationStyle": "custom",
// #ifdef APP-PLUS
"backgroundColor": "transparent",
"backgroundColorTop": "transparent",
"backgroundColorBottom": "transparent",
// #endif
"app-plus": {
"animationType": "fade-in",
"background": "transparent",
"popGesture": "none"
}
}
}
],
"subPackages": [
{
"root": "subPackages/home-sub",
"pages": [
{
"path": "addPrinter/addPrinter",
"style": {
"navigationBarTitleText": "添加打印机"
}
},
{
"path": "printerList/printerList",
"style": {
"navigationBarTitleText": "打印机列表",
"enablePullDownRefresh": true
}
},
{
"path": "swichPrinter/swichPrinter",
"style": {
"navigationBarTitleText": "切换设备"
}
},
{
"path": "updateV/updateV",
"style": {
"navigationBarTitleText": "系统公告",
"enablePullDownRefresh": true
}
},
{
"path": "wifi/wifi",
"style": {
"navigationBarTitleText": "WIFI配网"
}
},
{
"path": "help/help",
"style": {
"navigationBarTitleText": "帮助中心",
"enablePullDownRefresh": true
}
},
{
"path": "helpDetails/helpDetails",
"style": {
"navigationBarTitleText": "教程"
}
},
{
"path": "testPrinter/testPrinter",
"style": {
"navigationBarTitleText": "打印测试"
}
}
]
},
{
"root": "subPackages/personalCenter-sub",
"pages": [
{
"path": "feedback/feedback",
"style": {
"navigationBarTitleText": "问题反馈"
}
},
{
"path": "JXTEXT/JXTEXT",
"style": {
"navigationBarTitleText": "京西云"
}
},
{
"path": "topUp/topUp",
"style": {
"navigationBarTitleText": "充值京豆"
}
}
]
},
{
"root": "subPackages/printerModel",
"pages": [
{
"path": "printerModel/printerModel",
"style": {
"navigationBarTitleText": "模板管理"
}
},
{
"path": "model/model",
"style": {
"navigationBarTitleText": "自定义模板"
}
}
]
},
{
"root": "subPackages/App",
"pages": [
{
"path": "appPower/appPower",
"style": {
"navigationBarTitleText": "应用授权",
"enablePullDownRefresh": true
}
},
{
"path": "helpPower/helpPower",
"style": {
"navigationBarTitleText": "应用授权"
}
}
]
},
{
"root": "subPackages/login",
"pages": [
{
"path": "loginPhone/loginPhone",
"style": {
"navigationBarTitleText": "用户登录"
}
},
{
"path": "userInfor/userInfor",
"style": {
"navigationBarTitleText": "微信授权"
}
}
]
}
],
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#0a99ff",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/home/home",
"iconPath": "static/img/check-sel.png",
"selectedIconPath": "static/img/check.png",
"text": "首页"
},
{
"pagePath": "pages/printerSetUp/printerSetUp",
"iconPath": "static/img/printer-sel.png",
"selectedIconPath": "static/img/printer.png",
"text": "打印设置"
},
{
"pagePath": "pages/personalCenter/personalCenter",
"iconPath": "static/img/store-sel.png",
"selectedIconPath": "static/img/store.png",
"text": "个人中心"
}
]
},
"easycom": {
"autoscan": true,
"custom": {
// uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
// 全局样式
"globalStyle": {
"navigationBarTextStyle": "black", // 导航栏字体颜色
"navigationBarTitleText": "京西云", // 导航栏标题
"navigationBarBackgroundColor": "#F8F8F8", // 导航栏背景颜色
"backgroundColor": "#F8F8F8", // 窗口背景颜色
"enablePullDownRefresh": false, // 是否开启全局下拉
"backgroundTextStyle": "light", // 下拉加载样式亮色
"rpxCalcMaxDeviceWidth": 960, // rpx 计算所支持的最大设备宽度,单位 px默认值为 960
"rpxCalcBaseDeviceWidth": 375, // rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px默认值为 375
"rpxCalcIncludeWidth": 750 // rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx默认值为 750
},
"uniIdRouter": {},
"condition":{
"current": 0,
"list": [
{
"name": "登录",
"path": "subPackages/login/loginPhone/loginPhone"
}
]
}
}

77
src/pages/home/data.js Normal file
View File

@@ -0,0 +1,77 @@
/**
* 首页data数据
* 作者: zhangshuwei
* 日期: 2022年8月12日
* 邮箱: 2966211270@qq.com
*/
export const allData = {
data() {
return {
noticeData: '',
list: [
{
url: "http://image.jxc4.com/image/f0e1de394882a0f61b67802b60aa93e5.tem.png",
text: "添加设备",
type: "line",
id: 1
},
{
url: "http://image.jxc4.com/image/9abb806c2cdbc1d0d4b4ce37921fa562.tem.png",
text: "打印模板",
type: "line",
id: 2
},
{
url: "http://image.jxc4.com/image/4af18988a807f25cecbf464c22a3be0f.tem.png",
text: "客户模板",
type: "line",
id: 3
},
{
url: "http://image.jxc4.com/image/cea425858fb8d6bec573506ffcdf1c18.tem.png",
text: "wifi配网",
type: "line",
id: 4
},
{
url: "http://image.jxc4.com/image/6614dcc65143a0cd399e5c3d15bcca34.tem.png",
text: "帮助中心",
type: "line",
id: 5
},
{
url: "http://image.jxc4.com/image/b406243c39cc1edd6c13c031c62bc917.tem.png",
text: "软件分享",
type: "line",
id: 6
},
{
url: "http://image.jxc4.com/image/0a079d6881689fbb956df649c900f42b.tem.png",
text: "官方客服",
type: "line",
id: 7
},
{
url: "http://image.jxc4.com/image/f917ce30af33e614f2245fcb32cdb5ab.tem.png",
text: "购买打印机",
type: "line",
id: 8
},
{
url: "http://image.jxc4.com/image/4f2e389e922f5baa81d0c2e5666a3cf8.tem.png",
text: "测试打印",
type: "line",
id: 9
}
],
modelHtml: '', // 商户预览信息
isModelShow: false, // 弹窗展示信息
isModelShowCusctomer: false, // 商户模板
isHeader: false, // 小票头是否展示
printerName: 'null', // 当前设备名字
banner: [],
}
}
}

360
src/pages/home/home.scss Normal file
View File

@@ -0,0 +1,360 @@
page{
background-color: $zsw-aux-color;
// background-color: #eee;
}
.notice-bar{
box-sizing: border-box;
margin: 15rpx 25rpx 0rpx 25rpx;
position: relative;
border-radius: 15rpx;
overflow: hidden;
// #ifdef MP-WEIXIN
.new{
background-color: #ca0000;
font-size: 26rpx;
color: #fff;
}
.new::before{
position: absolute;
content: '';
border: 10rpx solid;
top: 8rpx;
left: -20rpx;
border-color: transparent #ca0000 transparent transparent;
}
// #endif
// #ifdef APP-PLUS
.new{
position: absolute;
background-color: #ca0000;
font-size: 20rpx;
color: #fff;
padding: 3rpx 13rpx;
right: 30rpx;
top: 15rpx;
}
.new::before{
position: absolute;
content: '';
border: 10rpx solid;
top: 8rpx;
left: -20rpx;
border-color: transparent #ca0000 transparent transparent;
}
// #endif
}
.swiper-item{
position: relative;
height: 100%;
width: 100%;
text-align: center;
//#ifdef MP-WEIXIN
img{
width: 100%;
height: 100%;
}
//#endif
//#ifdef APP-PLUS
img{
width: 100%;
height: 100%;
}
//#endif
}
// addPrinter
.addPrinter{
display: flex;
justify-content: space-between;
background-color: #3788fe;
margin: 0rpx 25rpx 25rpx 25rpx;
box-shadow: -1px 0px 15px #e6e4e4,
0px -0px 15px #ffffff;
border-radius: 7px;
padding: 30rpx;
.addIcon{
display: inline-block;
background-color: #a9cdff;
width: 100rpx;
height: 100rpx;
text-align: center;
line-height: 100rpx;
border-radius: 20rpx;
color: #3788fe;
font-size: 50rpx;
}
.addText{
display: flex;
align-items: center;
justify-content: center;
width: 540rpx;
color: #fff;
}
}
// three-root
.three-root{
display: flex;
justify-content: space-between;
margin: 25rpx;
// right
.right{
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: #ffaf32;
padding: 40rpx 40rpx 20rpx 40rpx;
width: 260rpx;
height: 240rpx;
border-radius: 7px;
box-shadow: -1px 0px 15px #e6e4e4,
0px -0px 15px #ffffff;
overflow: hidden;
// right-text
.right-text{
.s1{
display: inline-block;
font-size: 35rpx;
margin-bottom: 15rpx;
font-weight: bold;
color: #fff;
}
.s2{
font-size: 30rpx;
color: #fff4e2;
}
}
// icon
.icon-chengxinhezuowoshou{
position: relative;
bottom: -15rpx;
right: -30rpx;
text-align: right;
font-size: 190rpx;
color: #ffd086;
transform: rotateZ(-35deg);
}
}
// left
.left{
display: flex;
flex-direction: column;
justify-content: space-between;
width: 340rpx;
height: 300rpx;
border-radius: 7px;
// left-top
.left-top{
box-sizing: border-box;
padding: 20rpx;
background-color: #f65c5c;
height: 140rpx;
box-shadow: -1px 0px 15px #e6e4e4,
0px -0px 15px #ffffff;
border-radius: 7px;
.s1{
color: #fff;
font-weight: bold;
}
.top-icon{
display: flex;
justify-content: space-between;
.s2{
margin-top: 15rpx;
font-size: 24rpx;
color: #fdedec;
}
.iconfont{
font-size: 70rpx;
color: #f99d9e;
}
}
}
// left-foot
.left-foot{
box-sizing: border-box;
padding: 20rpx;
background-color: #20d2d4;
height: 140rpx;
box-shadow: -1px 0px 15px #e6e4e4,
0px -0px 15px #ffffff;
border-radius: 7px;
.s1{
color: #fff;
font-weight: bold;
}
.foot-icon{
display: flex;
justify-content: space-between;
.s2{
margin-top: 15rpx;
font-size: 24rpx;
color: #d0f5f5;
}
.iconfont{
font-size: 70rpx;
color: #7ae4e4;
}
}
}
}
}
.swiper-box{
height: 295rpx;
width: 100%;
}
.more-common{
border-radius: 15rpx;
overflow: hidden;
background-color: #fff;
margin: 0 25rpx;
padding-bottom: 20rpx;
// one-title
.one-title{
display: inline-block;
position: relative;
margin-top: 30rpx;
font-size: 700;
padding-left: 55rpx;
}
.one-title::before{
content: '';
position: absolute;
width: 10rpx;
height: 42rpx;
left: 30rpx;
background: linear-gradient(to bottom, $zsw-prinmary-color, $zsw-grey-color);
border-radius: 10rpx;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 10px;
.image{
width: 75rpx;
height: 75rpx;
}
.text{
font-size: 28rpx;
}
}
.image {
width: 35px;
height: 35px;
}
.text {
font-size: 18px;
margin-top: 5px;
}
}
.share-root{
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
p{
text-align: center;
padding: 20rpx 0;
font-size: 37rpx;
}
// #ifdef MP-WEIXIN
button{
background-color: #fff;
border: transparent;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding-top: 25rpx;
i{
color: #fff;
background-color: #03bb5c;
font-size: 60rpx;
padding: 10rpx;
width: 70rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 50%;
margin-bottom: -15rpx;
}
text{
color: #747474;
}
}
// #endif
// #ifdef APP-PLUS
.button{
background-color: #fff;
border: transparent;
display: flex;
padding-top: 25rpx;
border-top: 1rpx solid rgb(230, 230, 230);
border-bottom: 1rpx solid rgb(230, 230, 230);
.friend{
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
img{
width: 55px;
}
text{
color: #747474;
margin-bottom: 20rpx;
}
}
}
// #endif
}

175
src/pages/home/home.vue Normal file
View File

@@ -0,0 +1,175 @@
<template>
<view style="padding-bottom: 20rpx">
<!-- #ifdef APP-PLUS -->
<wrap-version-update id="630db9b1e3e39a00017828f0"></wrap-version-update>
<!-- #endif -->
<!-- 轮播图123 -->
<swiper
class="swiper-box"
@change="change"
autoplay="true"
circular="true"
duration="1000"
interval="4000"
>
<swiper-item v-for="item in banner" :key="item.id">
<view class="swiper-item">
<img :src="item.link" alt="" />
</view>
</swiper-item>
</swiper>
<!-- 最新版本公告 -->
<view class="notice-bar" @tap="updateVer">
<uni-notice-bar
background-color="#fff"
scrollable
color="#000"
:speed="50"
moreColor="rgb(163, 163, 163)"
show-get-more
show-icon
more-text="查看更多 >"
:text="noticeData"
/>
</view>
<!-- 样式一添加打印机等样式 -->
<view>
<!-- 添加打印机 -->
<view class="addPrinter" @tap="addPrinter">
<span class="addIcon">+</span>
<view class="addText" v-if="printerName == 'null'"
>点此添加打印设备</view
>
<view class="addText" style="font-weight: bold" v-else
>当前设备:{{ printerName }}</view
>
</view>
<!-- 上元素排列 -->
<view class="three-root">
<!-- 右边平台管理 -->
<view class="right" @tap="appPower">
<!-- 头部 -->
<view class="right-text">
<span class="s1">平台管理</span>
<br />
<span class="s2">美团/饿了么/...</span>
</view>
<!-- 图标 -->
<span class="iconfont icon-chengxinhezuowoshou"></span>
</view>
<!-- 左边两个记录 -->
<view class="left">
<view class="left-top" @tap="printerList">
<span class="s1">打印机管理</span>
<view class="top-icon">
<span class="s2">修改/测试打印/...</span>
<span class="iconfont icon-24gl-printer"></span>
</view>
</view>
<view class="left-foot" @tap="switchPrinter">
<span class="s1">切换打印机</span>
<view class="foot-icon">
<span class="s2">切换/设置...</span>
<span class="iconfont icon-xuanzhuan"></span>
</view>
</view>
</view>
</view>
</view>
<!-- 更多功能 -->
<view class="more-common">
<span class="one-title">更多功能</span>
<uni-grid
:column="4"
:show-border="false"
:square="false"
@change="change"
>
<uni-grid-item
v-for="(item, index) in list"
:index="index"
:key="index"
>
<view class="grid-item-box">
<img class="image" :src="item.url" mode="aspectFill" />
<text class="text">{{ item.text }}</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
<!-- 分享面板 -->
<uni-popup ref="share">
<view class="share-root">
<p>分享至</p>
<!-- #ifdef MP-WEIXIN -->
<button open-type="share">
<i class="iconfont icon-iconfontweixin"></i>
<text>微信好友</text>
</button>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="button">
<view class="friend" @tap="weixinShare">
<img
src="http://image.jxc4.com/image/8616dd55c218b769afc0e8e2e0206798.tem.png"
alt=""
/>
<text>微信好友</text>
</view>
<view class="friend" @tap="weixinFriend">
<img
src="http://image.jxc4.com/image/a6baf4fe54795371f0cc4e6c27980e2f.tem.png"
alt=""
/>
<text>微信朋友圈</text>
</view>
</view>
<!-- #endif -->
</view>
</uni-popup>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
import { allData } from "./data.js";
export default {
data() {
return {
...allData.data(),
};
},
onShareAppMessage(res) {
return {
title: "京西云打印机",
path: "/pages/home/home",
};
},
onShow() {
if (!uni.getStorageSync("printerName")) {
uni.setStorageSync("printerName", "null");
}
this.printerName = uni.getStorageSync("printerName");
this.getImgNoticeHelp();
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./home.scss";
</style>

310
src/pages/home/methods.js Normal file
View File

@@ -0,0 +1,310 @@
/**
* 首页户方法
* 作者: zhang-shu-wei
* 日期: 2022年8月12日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 查询轮播图、公告、帮助
* @notice_type 1、轮播图 2、公告
*/
async getImgNoticeHelp() {
let ImgPlayload = {
notice_type: 1,
page_number: 1,
page_size: 100
}
let imgData = await this.$api.img_notice_help(ImgPlayload)
if (imgData.code == 0) {
this.banner = JSON.parse(imgData.data).result
} else {
this.$zsw.toast('系统异常', 2)
}
let noticePlayload = {
notice_type: 2,
page_number: 1,
page_size: 1
}
let noticeData = await this.$api.img_notice_help(noticePlayload)
if (imgData.code == 0) {
this.noticeData = JSON.parse(noticeData.data).result[0].msg
} else {
this.$zsw.toast('系统异常', 2)
}
},
/**
* 跳转添加打印机
*/
addPrinter() {
uni.navigateTo({ url: '/subPackages/home-sub/addPrinter/addPrinter' })
},
/**
* 跳转打印机列表
*/
async printerList() {
if (!uni.getStorageSync('peinterList')) {
this.$zsw.toast(`你还没有打印设备,请先添加打印设备`)
return
}
uni.navigateTo({ url: '/subPackages/home-sub/printerList/printerList' })
},
/**
* 更过功能
*/
change(e) {
switch (e.detail.index) {
case 0:
this.addPrinter()
break
case 1:
this.mangerModel()
break
case 2:
this.userModel()
break
case 3:
this.wifiMethods()
break
case 4:
uni.navigateTo({ url: '/subPackages/home-sub/help/help' })
break
case 5:
this.shares()
break
case 6:
this.phone()
break
case 7:
this.playPrinter()
break
case 8:
uni.navigateTo({ url: '/subPackages/home-sub/testPrinter/testPrinter' })
break
}
},
/**
* WiFi授权
*/
wifiMethods() {
// #ifdef MP-WEIXIN
uni.navigateTo({ url: `/subPackages/home-sub/wifi/wifi?type="1"` })
// #endif
// #ifdef APP-PLUS
if (plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { // 判断用户是否安装了微信
// 跳转到微信小程序进行微信网路配置
plus.share.getServices(function (res) {
var sweixin = null;
for (var i = 0; i < res.length; i++) {
var t = res[i];
if (t.id == 'weixin') {
sweixin = t;
}
}
if (sweixin) {
sweixin.launchMiniProgram({
id: 'gh_d0aacb950a2a', //这里写你的小程序原始id以gh开头
type: 0, //这里是不同的环境( 0-正式版; 1-测试版; 2-体验版。 默认值为0。
path: 'subPackages/home-sub/wifi/wifi' //这里是指 定页的路径,如需传参直接字符串拼接(首页可以省略)
});
}
}, function (res) {
uni.dialog.alert('温馨提示', '打开小程序失败')
});
} else {
uni.dialog.alert('温馨提示', '请先下载微信')
}
// #endif
},
/**
* 购买打印机
*/
playPrinter() {
// #ifdef MP-WEIXIN
uni.navigateToMiniProgram({
appId: 'wx4b5930c13f8b1170',
path: 'pages/index/index?storeID=666666&fromStoreID=668470&storeType=c4',
extraData: {
'data1': 'test'
}
})
// #endif
// #ifdef APP-PLUS
if (plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { // 判断用户是否安装了微信
// 跳转到微信小程序进行微信网路配置
plus.share.getServices(function (res) {
var sweixin = null;
for (var i = 0; i < res.length; i++) {
var t = res[i];
if (t.id == 'weixin') {
sweixin = t;
}
}
if (sweixin) {
sweixin.launchMiniProgram({
id: 'gh_0d7e2243b51f', //这里写你的小程序原始id以gh开头
type: 0, //这里是不同的环境( 0-正式版; 1-测试版; 2-体验版。 默认值为0。
path: 'pages/index/index?storeID=666666&fromStoreID=668470&storeType=c4' //这里是指 定页的路径,如需传参直接字符串拼接(首页可以省略)
});
}
}, function (res) {
uni.dialog.alert('温馨提示', '打开小程序失败')
});
} else {
uni.dialog.alert('温馨提示', '请先下载微信')
}
// #endif
},
/**
* 分享软件
*/
shares() {
// #ifdef MP-WEIXIN
this.$refs.share.open('bottom')
// #endif
// #ifdef APP-PLUS
this.$refs.share.open('bottom')
// #endif
},
/**
* 移动端分享软件
*/
weixinShare() {
if (plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { // 判断用户是否安装了微信
uni.share({
provider: 'weixin',
scene: "WXSceneSession",
type: 0,
title: '京西云打印机',
summary: '我正在使用京西云打印机打印小票,期待你的加入...',
imageUrl: 'http://image.jxc4.com/image/0e3fdce5fb639ba3aafde1ed7306a000.tem.png',
href: 'http://pweb.jxc4.com/printer/downLoad.html',
success: ret => {
this.$zsw.toast('分享成功')
this.$refs.share.close()
},
fail: res => {
this.$zsw.toast('分享取消')
this.$refs.share.close()
}
});
} else {
uni.dialog.alert('温馨提示', '请先下载微信')
}
},
weixinFriend() {
if (plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { // 判断用户是否安装了微信
uni.share({
provider: 'weixin',
scene: "WXSceneTimeline",
type: 0,
title: '京西云打印机',
summary: '我正在使用京西云打印机打印小票,期待你的加入...',
imageUrl: 'http://image.jxc4.com/image/0e3fdce5fb639ba3aafde1ed7306a000.tem.png',
href: 'http://pweb.jxc4.com/printer/downLoad.html',
success: ret => {
this.$zsw.toast('分享成功')
this.$refs.share.close()
},
fail: res => {
this.$zsw.toast('分享取消')
this.$refs.share.close()
}
});
} else {
uni.dialog.alert('温馨提示', '请先下载微信')
}
},
/**
* 跳转到商户模板
*/
async mangerModel() {
if (!uni.getStorageSync('peinterList')) {
this.$zsw.toast('你还没有打印设备,请先添加打印设备')
return
}
this.$store.commit('setModelTye', 1)
uni.navigateTo({ url: '/subPackages/printerModel/printerModel/printerModel' })
},
/**
* 跳转到客户模板
*/
async userModel() {
this.$wx.showLoading()
this.$zsw.toast('即将上线')
if (!uni.getStorageSync('peinterList')) {
this.$zsw.toast('你还没有打印设备,请先添加打印设备')
return
}
// this.$store.commit('setModelTye', 1)
// uni.navigateTo({ url: '/subPackages/printerModel/printerModel/printerModel' })
},
/**
* 官方客服
*/
phone() {
//#ifdef MP-WEIXIN
uni.makePhoneCall({
phoneNumber: '18048531223'
});
//#endif
//#ifdef APP-PLUS
plus.device.dial('18048531223', true);
//#endif
},
/**
* 跳转到应用授权页面
*/
async appPower() {
if (!uni.getStorageSync('peinterList')) {
this.$zsw.toast(`你还没有打印设备,请先添加打印设备`)
return
}
uni.navigateTo({ url: '/subPackages/App/appPower/appPower' })
},
/**
* 切换打印机
*/
async switchPrinter() {
// if (!uni.getStorageSync('peinterList')) {
// this.$zsw.toast('你还没有打印设备,请先添加打印设备')
// return
// }
uni.navigateTo({ url: '/subPackages/home-sub/swichPrinter/swichPrinter' })
},
/**
* 系统公告
*/
updateVer() {
uni.navigateTo({ url: '/subPackages/home-sub/updateV/updateV' })
},
}

View File

@@ -0,0 +1,45 @@
/**
* 个人中心数据
* 作者: zhang-shu-wei
* 日期: 2022年8月16日
* 邮箱: 2966211270@qq.com
*/
export const allData = {
data() {
return {
money: 0, // 用户金豆
userInforData: null, // 个人中心用户数据
// 关于打印机内容
centerList: [
{ title: '用户协议', id: 1 },
{ title: '隐私协议', id: 2 },
// #ifdef APP-PLUS
{ title: '检查更新', id: 3 },
// #endif
// #ifdef APP-PLUS
{ title: '问题反馈', id: 4 },
// #endif
// #ifdef MP-WEIXIN
{ title: '问题反馈', id: 5 },
// #endif
{ title: '关于京西', id: 6 }
],
printerMsgSUM: {
week_print_count: '0',
day_print_count: '0',
day_un_print_count: '0',
online_printer_count: '0',
offline_printer_count: '0',
flow_printer_count: '0',
paper_printer_count: '0'
}, // 打印机信息 统计
isChech: false, // 手动检查更新
version: '', // 版本号
isMoney: false, // 手机充值
loginText: '', // 点击登录
}
}
}

View File

@@ -0,0 +1,226 @@
/**
* 个人中心
* 作者: zhang-shu-wei
* 日期: 2022年8月16日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 获取用户个人信息数据
*/
getUserInfo() {
if (this.$store.state.myUserData) {
let userInfor = this.$store.state.myUserData
userInfor.name = this.userNameSlice(userInfor.name) // 格式化用户昵称过长
userInfor.mobile = this.userPhoneSlice(userInfor.mobile) // 格式化手机号码
this.userInforData = userInfor
} else {
let userInfor = null
if (!uni.getStorageSync('userInfor')) {
this.isMoney = true
userInfor = {
avatar: 'http://image.jxc4.com/image/51c6bbfdcda010510247fd5f545e70c7.tem.png',
name: '点击登录',
mobile: '请登录'
}
} else {
this.isMoney = false
userInfor = JSON.parse(uni.getStorageSync('userInfor'))
}
this.$store.commit('setMyUserDat', userInfor)
userInfor.name = this.userNameSlice(userInfor.name) // 格式化用户昵称过长
userInfor.mobile = this.userPhoneSlice(userInfor.mobile) // 格式化手机号码
this.userInforData = userInfor
}
},
/**
* 跟多功能
*/
menu(e) {
switch (e.id) {
case 1:
this.agreement('用户协议')
break
case 2:
this.agreement('隐私协议')
break
case 3:
this.appUpdate()
break
case 4:
uni.navigateTo({ url: '/subPackages/personalCenter-sub/feedback/feedback' })
break
case 5:
uni.navigateTo({ url: '/subPackages/personalCenter-sub/feedback/feedback' })
break
case 6:
this.agreement('关于京西')
break
}
},
/**
* 版本更新
*/
appUpdate() {
// #ifdef APP-PLUS
this.$refs.ref.check()
if (!this.isChech) {
uni.showToast({
title: '当前版本为最新版',
icon: 'none',
position: 'bottom'
});
}
// #endif
},
handleCheck(res) {
this.version = res.lodVersion
if (!res.needUpdate) {
this.centerList[2].title = '检查更新'
this.isChech = false
} else {
this.centerList[2].title = '发现新版本'
this.isChech = true
}
},
/**
* 用户协议等
*/
agreement(text) {
uni.navigateTo({ url: `/subPackages/personalCenter-sub/JXTEXT/JXTEXT?type=${text}` })
},
/**
* 退出登录
*/
exitLgin() {
let login = uni.getStorageSync('token')
if (login) {
uni.dialog.confirm("退出登录", "确定退出登录吗", () => {
uni.clearStorageSync()
this.$store.commit('setUserPhone', null)
this.$store.commit('setToken', null)
this.$store.commit('setMyUserDat', null)
this.$store.commit('setUserId', null)
uni.redirectTo({ url: '/subPackages/login/loginPhone/loginPhone' })
})
} else[
uni.redirectTo({ url: '/subPackages/login/loginPhone/loginPhone' })
]
},
/**
* 获取打印机打印 统计打印信息
*/
async getPrinterMsg() {
if (!uni.getStorageSync('token')) {
this.loginText = '点击登录'
return
}
this.loginText = '退出登录'
let res = await this.$api.printerMsgSum()
if (res.code == 0) {
let newData = JSON.parse(res.data)
if (newData == null) {
this.printerMsgSUM = {
week_print_count: 0,
day_print_count: 0,
day_un_print_count: 0,
online_printer_count: 0,
offline_printer_count: 0,
flow_printer_count: 0,
paper_printer_count: 0
}
return
}
this.printerMsgSUM = newData
} else {
this.$zsw.toast('打印机信息获取失败')
}
},
/**
* 处理用户名过长 使用vue 过滤器报错
*/
userNameSlice(val) {
if (!val) return '京西云'
if (val.length < 6) return val
let s = val
let result = s.slice(0, 5) + '**'
return result
},
/**
* 处理用户手机号码 使用vue 过滤器报错
*/
userPhoneSlice(val) {
if (!val) return '157****2580'
let s = val
let result1 = s.slice(0, 3)
let result2 = s.slice(7)
let newPhone = result1 + '****' + result2
return newPhone
},
/**
* 京豆充值
*/
topOUp() {
if (!uni.getStorageSync('token')) {
return
}
if (!uni.getStorageSync('peinterList')) {
this.$zsw.toast(`你还没有打印设备,请先添加打印设备`)
return
}
uni.navigateTo({ url: `/subPackages/personalCenter-sub/topUp/topUp?money=${this.money}&printerNum=${uni.getStorageSync('peinterList')}` })
},
async getPrinterMoney() {
if (!uni.getStorageSync('token')) {
return
}
let data = {
app_id: 1000,
print_no: uni.getStorageSync('peinterList'),
is_online: -9,
status: -9,
offset: 0,
page_size: 100
}
let resList = await this.$api.setPrinterList(data)
if (resList.code == 0) {
let newData = JSON.parse(resList.data).data[0]
this.money = newData.print_bill
} else {
this.money = 0
}
},
/**
* 出问题登录没有跳出去需要他点击登录
*/
goLogin() {
let login = uni.getStorageSync('token')
if (login) return
uni.reLaunch({ url: '/subPackages/login/loginPhone/loginPhone' })
}
}

View File

@@ -0,0 +1,226 @@
page{
background-color: #f7f8fa;
}
// 个人头像
.portrait{
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
box-sizing: border-box;
height: 260rpx;
overflow: hidden;
padding: 50rpx 60rpx 50rpx 60rpx;
background-image: url(@/static/img/personalcenter.jpg);
background-size:cover;
.img-root{
width: 150rpx;
height: 150rpx;
border-radius: 50%;
border: 4rpx solid #fff;
overflow: hidden;
img{
width: 150rpx;
height: 150rpx;
}
}
.name{
margin-left: 20rpx;
color: #fff;
p:nth-child(1){
display: flex;
align-items: center;
padding: 5rpx 0;
font-size: 36rpx;
font-weight: bold;
img{
width: 100rpx;
height: 30rpx;
margin-left: 20rpx;
}
}
p:nth-child(2){
padding: 5rpx 0;
font-size: 30rpx;
}
}
}
// 用户京豆余额
.money-root{
box-sizing: border-box;
display: flex;
padding: 20rpx 25rpx;
justify-content: space-between;
position: relative;
background-color: rgb(255, 255, 255);
margin: 0 40rpx 20rpx 40rpx;
color: #000;
border-radius: 15rpx;
margin-top: 280rpx;
.left-money{
display: flex;
align-items: center;
img{
width: 40rpx;
height: 40rpx;
margin-left: 7rpx;
}
}
.money-btn{
display: inline-block;
padding: 5rpx 20rpx;
background-color: $zsw-prinmary-color;
border-radius: 7rpx;
color: #fff;
}
.no-sufficient{
color: rgb(207, 0, 0);
}
}
// printer-msg
.printer-msg{
position: relative;
display: flex;
justify-content: space-evenly;
margin: 0rpx 40rpx 30rpx 40rpx;
padding: 20rpx 0rpx;
background-color: #fff;
border-radius: 10px;
.i{
padding: 10rpx;
border-radius: 50%;
}
.i1{
background-color: #0a99fe;
}
.i2{
background-color: #7cd52f;
}
.i3{
background-color: #ffaf32;
}
.i4{
background-color: #f65c5c;
}
span{
margin-bottom: 10rpx;
color: rgb(61, 61, 61);
}
// msg-item
.msg-item{
display: flex;
flex-direction: column;
align-items: center;
em{
margin-top: 5rpx;
font-weight: bold;
}
span{
color: #a1a1a1;
}
uni-icons{
// font-weight: 550;
}
}
}
// 打印数量
.printer-text-number{
position: relative;
display: flex;
justify-content: space-evenly;
margin:0 40rpx 20rpx 40rpx;
border-radius: 15rpx;
padding: 30rpx 0;
background-color: #fff;
// 数量项
.printer-item{
display: flex;
flex-direction: column;
align-items: center;
font-size: 28rpx;
// #ifdef MP-WEIXIN
b{
color: #000;
margin-top: 15rpx;
font-size: 40rpx;
font-weight: bold;
}
//#endif
span{
color: #a1a1a1;
}
}
}
// 内容开始
.centent{
box-sizing: border-box;
margin: 30rpx 40rpx 30rpx 40rpx;
background-color: #fff;
padding: 10rpx 30rpx 0 30rpx;
border-radius: 10rpx;
.item{
display: flex;
justify-content: space-between;
height: 100rpx;
line-height: 100rpx;
border-bottom: 1rpx solid $zsw-aux-color;
.version-root {
position: relative;
display: flex;
align-items: center;
.version{
display: inline;
height: 20rpx;
line-height: 15.5rpx;
padding: 3rpx 7rpx;
margin-right: 10rpx;
font-size: 22rpx;
background-color: red;
color: #fff;
}
}
}
}
.close-btn{
background-color: #fff;
margin: 0 40rpx;
text-align: center;
height: 100rpx;
line-height: 100rpx;
border-radius: 10rpx;
font-weight: bold;
}

View File

@@ -0,0 +1,182 @@
<template>
<view style="padding-bottom: 30rpx">
<!-- #ifdef APP-PLUS -->
<wrap-version-update
ref="ref"
:auto="false"
id="630db9b1e3e39a00017828f0"
@check="handleCheck"
></wrap-version-update>
<!-- #endif -->
<!-- 个人头像 -->
<view class="portrait" @tap="goLogin">
<view class="img-root">
<img v-if="userInforData.avatar != ''" :src="userInforData.avatar" />
<img
v-else
src="http://image.jxc4.com/image/51c6bbfdcda010510247fd5f545e70c7.tem.png"
alt=""
/>
</view>
<view class="name">
<p>
{{ userInforData.name }}
<img
src="http://image.jxc4.com/image/f6cb95b8e99f48cedaf88cd3c0874096.tem.jpg"
alt=""
/>
</p>
<p>{{ userInforData.mobile }}</p>
</view>
</view>
<!-- 用户京豆 -->
<view class="money-root">
<view class="left-money">
<view v-if="money > 100"
>京豆余额<span class="sufficient">{{ money }}</span></view
>
<view v-else
>京西豆余额<span class="no-sufficient">{{ money }}</span></view
>
<img
src="http://image.jxc4.com/image/9287b611859af0de50318e1b7f2d8a15.tem.png"
alt=""
/>
</view>
<view class="money-btn" @tap="topOUp">充值</view>
</view>
<!-- 打印机信息 -->
<view class="printer-msg">
<view class="msg-item">
<uni-icons
class="i i1"
custom-prefix="iconfont"
type="icon-24gl-printer"
size="37"
color="#fff"
></uni-icons>
<b>{{ printerMsgSUM.flow_printer_count }}</b>
<span>设备数量</span>
</view>
<view class="msg-item">
<uni-icons
class="i i2"
custom-prefix="iconfont"
type="icon-zaixian"
size="37"
color="#fff"
></uni-icons>
<b>{{ printerMsgSUM.online_printer_count }}</b>
<span>在线</span>
</view>
<view class="msg-item">
<uni-icons
class="i i3"
custom-prefix="iconfont"
type="icon-lixian"
size="37"
color="#fff"
></uni-icons>
<b>{{ printerMsgSUM.offline_printer_count }}</b>
<span>离线</span>
</view>
<view class="msg-item">
<uni-icons
class="i i4"
custom-prefix="iconfont"
type="icon-binglianrongque"
size="37"
color="#fff"
></uni-icons>
<b>{{ printerMsgSUM.paper_printer_count }}</b>
<span>缺纸</span>
</view>
</view>
<!-- 打印数量 -->
<view class="printer-text-number">
<view class="printer-item">
<b>{{ printerMsgSUM.day_print_count }}</b>
<span>今日打印量</span>
</view>
<view class="printer-item">
<b>{{ printerMsgSUM.day_un_print_count }}</b>
<span>今日未打印</span>
</view>
<view class="printer-item">
<b>{{ printerMsgSUM.week_print_count }}</b>
<span>周打印量</span>
</view>
</view>
<!-- 开始内容 -->
<view class="centent">
<view
class="item"
v-for="(item, i) in centerList"
:key="i"
@tap="menu(item)"
>
<view>
<span>{{ item.title }}</span>
</view>
<view class="version-root" v-if="item.id == 3">
<span class="version" v-show="isChech">new</span>
<span>{{ version }}</span>
<uni-icons
custom-prefix="iconfont"
type="icon-jinrujiantou"
size="30"
></uni-icons>
</view>
<uni-icons
v-else
custom-prefix="iconfont"
type="icon-jinrujiantou"
size="30"
></uni-icons>
</view>
</view>
<view class="close-btn" @tap="exitLgin">{{ loginText }}</view>
</view>
</template>
<script>
import { allMethods } from './methods.js'
import { allData } from './data.js'
export default {
data() {
return {
...allData.data(),
}
},
onLoad() {
this.getUserInfo()
this.getPrinterMsg() // 获取打印机 信息统计
this.getPrinterMoney()
},
onPullDownRefresh() {
this.getPrinterMsg() // 获取打印机 信息统计
this.getPrinterMoney()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1200)
},
methods: {
...allMethods,
},
}
</script>
<style lang="scss">
@import './personalCenter.scss';
</style>

View File

@@ -0,0 +1,67 @@
/**
* 新打印机设置
* 作者zhangshuwei
* 日期2022年9月23日
* 邮箱2966211270@qq.com
*/
export const allData = {
data() {
return {
callNamId: 64, // 当前称谓
activ: 0, // 默认高亮
mangerNum: 1, // 商家联打印数
userNum: 1, // 客户联打印数
titleList: [
{title: '基础设置', id: 1},
{title: '打印设置', id: 2},
{title: '语音设置', id: 3}
],
// 称为设置
callList: [
{
text: '老板',
value: 64
},
{
text: '大哥',
value: 65
},
{
text: '大姐',
value: 66
}
],
voice_setting: [], // 语音设置
print_setting: [], // 打印机设置
asic_setup: [], // 打印机基础设置
printerAllSetUp: {}, // 打印机全部设置数据
// 基础设置
basis: [
{title: '每日招呼语音提示'},{title: '店铺下线语音提示'},{title: '余额不足语音提示'}
],
// 打印设置
printerSetUpList: [
{title: '用户取消订单打印'},{title: '订单退款打印'},{title: '商家取消订单打印'},
{title: '骑手接单打印'},{title: '平台客服退款打印'},{title: '待接订单打印'},
{title: '申请取消定单'},{title: '申请退款/部分退款'},{title: '定单已取消'},
{title: '客户拒收打印'}
],
// 打印机声音设置
printerVoiceList: [
{title: '新定单提示'},{title: '骑手接单提示'},{title: '申请取消提示'},
{title: '申请退款提示'},{title: '申请退款提示'},{title: '定单已取消提示'},
{title: '定单已接单提示'},{title: '定单已完成提示'},{title: '客户咨询提示'},
{title: '客户催单提示'},{title: '客户拒收提示'},{title: '平台为客户退款提示'},
{title: '授权丢失提示'}
],
printerState: uni.getStorageSync('peinterList')
}
}
}

View File

@@ -0,0 +1,357 @@
/**
* 新打印机设置方法
* 作者zhangshuwei
* 日期2022年9月23日
* 邮箱2966211270@qq.com
*/
const innerAudioOne = uni.createInnerAudioContext() // 播放声音
const innerAudioTwo = uni.createInnerAudioContext() // 播放声音
const innerAudioThree = uni.createInnerAudioContext() // 播放声音
export const allMethods = {
/**
* 选择声音
*/
change(e) {
this.callNamId = e.detail.value
if (e.detail.value == 64) {
innerAudioOne.src = 'https://image.jxc4.com/image/e8b3ded400d7070b1b353c3c5f63f68c.jpg'
this.$nextTick(() => {
innerAudioOne.stop()
innerAudioOne.play()
})
}
if (e.detail.value == 65) {
innerAudioOne.src = 'https://image.jxc4.com/image/f1c9a95830cd5be7f17bc5102fd389a7.jpg'
this.$nextTick(() => {
innerAudioOne.stop()
innerAudioOne.play()
})
}
if (e.detail.value == 66) {
innerAudioOne.src = 'https://image.jxc4.com/image/9bdab42c1dfd1d3524eb6c38d0b641d0.jpg'
this.$nextTick(() => {
innerAudioOne.stop()
innerAudioOne.play()
})
}
},
/**
* 导航高亮
*/
tapTitle(i) {
this.activ = i
},
/**
* 打印设置
* @minus减号
* @add加号
*/
mMminus() {
if (this.mangerNum == '关') return
this.mangerNum--
},
mAdd() {
if (this.mangerNum == '关') this.mangerNum = 0
this.mangerNum++
},
uMinus() {
if (this.userNum == '关') return
this.userNum--
},
uAdd() {
if (this.userNum == '关') this.userNum = 0
this.userNum++
},
/**
* 打印机声
* 星期一https://image.jxc4.com/image/459470825cf00a62e0f786707152afdf.jpg
* 星期二https://image.jxc4.com/image/ac0a41df407c7165e3d03b99a8c7f8f3.jpg
* 星期三https://image.jxc4.com/image/56185fa5523a167d0863c036ea4ce506.jpg
* 星期四https://image.jxc4.com/image/b9114546ea7fdf627ec14e894929bc50.jpg
* 星期五https://image.jxc4.com/image/914579ec8c770724c41ee2cc68a4b62c.jpg
* 星期六https://image.jxc4.com/image/6f0af1d28d35aa1f6672a12de0841a48.jpg
* 星期日https://image.jxc4.com/image/e8fa1b1a3e3bca8b9675c9a5ac0262be.jpg
*
* 店铺下线https://image.jxc4.com/image/1751350e2652f890119643b019afc068.jpg
* 余额不足: https://image.jxc4.com/image/2796914d198c8cdc5cfab6e97b0153f2.jpg
*
* 新订单https://image.jxc4.com/image/92eda0c0dd166df5200a8795b81d5d5e.jpg
* 带拣货https://image.jxc4.com/image/7421dfa0db740c97113893066ad17d6e.jpg
* 骑手接单https://image.jxc4.com/image/ad2f3b4b815fcdf8e9aba8a93c99a898.jpg
* 申请取消https://image.jxc4.com/image/c4ab33395d0867d1c43ad2dc64bec674.jpg
* 申请退款https://image.jxc4.com/image/3062da24a23970bb938ad5a9775fea08.jpg
* 申请退货https://image.jxc4.com/image/9ab5545028d660686bfbbee8ed400083.jpg
* 订单已取消https://image.jxc4.com/image/e31f8aba06feaaec9e5247a0b60a42a6.jpg
* 订单已接单https://image.jxc4.com/image/e3ee22cace302b4085f592e6320f02d2.jpg
* 订单已完成https://image.jxc4.com/image/3527b1359123655d076c7f46984b098d.jpg
* 客户咨询https://image.jxc4.com/image/cd1ee893370d171d3c5d625f967d27c1.jpg
* 客户催单https://image.jxc4.com/image/c8d0317e7f1e7edc7b5704097f249afa.jpg
* 客户拒收https://image.jxc4.com/image/8b08a6925618eadd007f401448c918a9.jpg
* 平台客服退款https://image.jxc4.com/image/d50fd138742b35aa2103a554ed3e776e.jpg
* 失去授权https://image.jxc4.com/image/b39a7b0c4abd8487a44ba143a1b29cdb.jpg
*/
sound(title) {
uni.dialog.alert("声音预览", "当前正在播放打印机提示,关闭后打印机将不在播放此声音")
let voice = this.voiceSrc(title)
var src
switch (this.callNamId) {
case 64:
src = 'https://image.jxc4.com/image/e8b3ded400d7070b1b353c3c5f63f68c.jpg'
break;
case 65:
src = 'https://image.jxc4.com/image/f1c9a95830cd5be7f17bc5102fd389a7.jpg'
break
case 66:
src = 'https://image.jxc4.com/image/9bdab42c1dfd1d3524eb6c38d0b641d0.jpg'
break
}
innerAudioThree.src = src
this.$nextTick(() => {
innerAudioThree.stop()
innerAudioThree.play()
})
innerAudioTwo.src = voice
innerAudioThree.onEnded(() => {
this.$nextTick(() => {
innerAudioTwo.stop()
innerAudioTwo.play()
})
})
},
/**
* 获取当前星期几
*/
week(weekDate) {
var src
switch (weekDate) {
case '一':
src = 'https://image.jxc4.com/image/459470825cf00a62e0f786707152afdf.jpg'
break;
case '二':
src = 'https://image.jxc4.com/image/ac0a41df407c7165e3d03b99a8c7f8f3.jpg'
break;
case '三':
src = 'https://image.jxc4.com/image/56185fa5523a167d0863c036ea4ce506.jpg'
break;
case '四':
src = 'https://image.jxc4.com/image/b9114546ea7fdf627ec14e894929bc50.jpg'
break;
case '五':
src = 'https://image.jxc4.com/image/914579ec8c770724c41ee2cc68a4b62c.jpg'
break;
case '六':
src = 'https://image.jxc4.com/image/6f0af1d28d35aa1f6672a12de0841a48.jpg'
break;
case '天':
src = 'https://image.jxc4.com/image/e8fa1b1a3e3bca8b9675c9a5ac0262be.jpg'
break;
}
return src
},
/**
* 获取当前需要预览啥声音
*/
voiceSrc(title) {
// 获取当前周数
var weekDate = "天一二三四五六".charAt(new Date().getDay())
var voice
switch (title) {
case '每日招呼语音提示':
voice = this.week(weekDate)
break;
case '店铺下线语音提示':
voice = 'https://image.jxc4.com/image/1751350e2652f890119643b019afc068.jpg'
break;
case '余额不足语音提示':
voice = 'https://image.jxc4.com/image/2796914d198c8cdc5cfab6e97b0153f2.jpg'
break;
case '新定单提示':
voice = 'https://image.jxc4.com/image/92eda0c0dd166df5200a8795b81d5d5e.jpg'
break;
case '未接单提示':
voice = 'https://image.jxc4.com/image/7421dfa0db740c97113893066ad17d6e.jpg'
break;
case '骑手接单提示':
voice = 'https://image.jxc4.com/image/ad2f3b4b815fcdf8e9aba8a93c99a898.jpg'
break;
case '申请取消提示':
voice = 'https://image.jxc4.com/image/c4ab33395d0867d1c43ad2dc64bec674.jpg'
break;
case '申请退款提示':
voice = 'https://image.jxc4.com/image/3062da24a23970bb938ad5a9775fea08.jpg'
break;
case '申请退货提示':
voice = 'https://image.jxc4.com/image/9ab5545028d660686bfbbee8ed400083.jpg'
break;
case '定单已取消提示':
voice = 'https://image.jxc4.com/image/e31f8aba06feaaec9e5247a0b60a42a6.jpg'
break;
case '定单已接单提示':
voice = 'https://image.jxc4.com/image/e3ee22cace302b4085f592e6320f02d2.jpg'
break;
case '定单已完成提示':
voice = 'https://image.jxc4.com/image/3527b1359123655d076c7f46984b098d.jpg'
break;
case '客户咨询提示':
voice = 'https://image.jxc4.com/image/cd1ee893370d171d3c5d625f967d27c1.jpg'
break;
case '客户催单提示':
voice = 'https://image.jxc4.com/image/c8d0317e7f1e7edc7b5704097f249afa.jpg'
break;
case '客户拒收提示':
voice = 'https://image.jxc4.com/image/8b08a6925618eadd007f401448c918a9.jpg'
break;
case '平台为客户退款提示':
voice = 'https://image.jxc4.com/image/d50fd138742b35aa2103a554ed3e776e.jpg'
break;
case '授权丢失提示':
voice = 'https://image.jxc4.com/image/b39a7b0c4abd8487a44ba143a1b29cdb.jpg'
break;
}
return voice
},
/**
* 保存打印机设置
*/
async serveSetup() {
uni.dialog.confirm("温馨提示", "确定要保存吗", async () => {
let voice_setting = this.deleteSetup(this.voice_setting) // 语音设置
let print_setting = this.deleteSetup(this.print_setting) // 打印设置
let basic_setup = this.deleteSetup(this.asic_setup) // 基本设置
let data = {
print_no: uni.getStorageSync('peinterList'), // 打印机编号
call_name_setting: this.callNamId, // 称呼id
every_day_greet_voice: basic_setup.every_day_greet_voice, // 每日招呼
business_off_line_voice: basic_setup.business_off_line_voice, // 店铺离线
balance_not_enough_voice: basic_setup.balance_not_enough_voice, // 余额不足
business_print_num: this.mangerNum, // 商家联打印
customer_print_num: this.userNum, // 客户联打印
print_setting: JSON.stringify(print_setting), // 打印设置
voice_setting: JSON.stringify(voice_setting), // 打印机声音设置
}
console.log(data)
let newData = await this.$api.updataMOdelSound(data)
if (newData.code == 0) {
this.$zsw.toast('保存成功', 'success')
} else {
this.setUserMOdelSound()
this.$zsw.toast('保存失败')
}
}, () => {
this.setUserMOdelSound()
})
},
/**
* 删除重组打印机设置数据
*/
deleteSetup(data) {
let obj = {}
let i = 0
data.forEach(element => {
obj[data[i].title] = element.isOpen
i++
})
return obj
},
/**
* 获取打印机设置信息
*/
async setUserMOdelSound() {
let data = {
print_no: uni.getStorageSync('peinterList')
}
let newData = await this.$api.setModelSound(data)
if (newData.code != 0) {
this.printerState = false
return this.$zsw.toast('没有打印机或打印机参数错误!')
}
this.printerState = true
let setData = JSON.parse(newData.data)
this.callNamId = setData.call_name_setting // 打印机称呼
this.printerAllSetUp = setData // 总数据
this.mangerNum = setData.business_print_num // 客户联打印
this.userNum = setData.customer_print_num // 用户联打印
let voiceSetting = setData.voice_setting // 声音设置
let printSetting = setData.print_setting // 打印设置
let basic_settings = {}
basic_settings.every_day_greet_voice = setData.every_day_greet_voice // 每日招呼语言
basic_settings.business_off_line_voice = setData.business_off_line_voice // 店铺离线
basic_settings.balance_not_enough_voice = setData.balance_not_enough_voice // 用户余额不足
this.voice_setting = this.structuredData(voiceSetting, this.printerVoiceList) // 语音设置
this.print_setting = this.structuredData(printSetting, this.printerSetUpList) // 打印设置
this.asic_setup = this.structuredData(basic_settings, this.basis) // 基本设置
},
/**
* 数据同步根方法
*/
voiceSet(e, value, state) {
let switchOpen = e.detail.value ? 1 : 0
if (state === 3) {
this.switchState(this.voice_setting, value, switchOpen)
}
if (state === 2) {
this.switchState(this.print_setting, value, switchOpen)
}
if (state === 1) {
this.switchState(this.asic_setup, value, switchOpen)
}
},
/**
* switch 数据同步
*/
switchState(data, value, state) {
for (let i = 0; i < data.length; i++) {
if (value === data[i].title) {
return data[i].isOpen = state
}
}
},
/**
* 结构化数据
*/
structuredData(data, reference) {
let printerArr = []
let i = 0
for (let key in data) {
let obj = {}
obj.isOpen = data[key]
obj.title = key
obj.value = reference[i].title
i++
printerArr.push(obj)
}
return printerArr
}
}

View File

@@ -0,0 +1,155 @@
page{
background-color: $zsw-aux-color;
}
.printer-set{
position: relative;
padding-bottom: 155rpx;
}
// 打印机设置
.printer-root{
.title{
position: sticky;
top: 0;
z-index: 9999;
box-sizing: border-box;
display: flex;
justify-content: space-between;
width: 100%;
padding: 15rpx 30rpx 0 30rpx;
background-color: #ffffff;
border-bottom: 1rpx solid #ebebeb;
span{
padding: 15rpx 50rpx;
color: #696969;
}
.activt{
border-bottom: 4rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
}
}
// 内容
.setup{
margin-top: 15rpx;
// 称呼
.call-name{
display: flex;
background-color: #ffffff;
padding: 22rpx 30rpx;
align-items: center;
border-bottom: 1rpx solid #e2e2e2;
}
.item{
display: flex;
background-color: #ffffff;
padding: 20rpx 30rpx;
align-items: center;
border-bottom: 1rpx solid #e2e2e2;
// 基础设置
p{
width: 100%;
}
.center{
display: flex;
align-items: center;
.icon-laba{
font-size: 50rpx;
color: rgb(163, 163, 163);
margin-right: 15rpx;
}
}
}
// 打印设置
.item-neworder{
display: flex;
background-color: #ffffff;
padding: 20rpx 30rpx;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #e2e2e2;
.menger{
color: $zsw-prinmary-color;
border: 1rpx solid $zsw-prinmary-color;
padding: 0 15rpx;
border-radius: 5rpx;
}
.mode-size{
border-radius: 5rpx;
margin: 0 10rpx;
text-align: center;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #838181;
}
.num-root{
display: flex;
align-items: center;
color: #838181;
.num{
display: flex;
align-items: center;
color: #000;
.iconfont{
font-size: 60rpx;
color: #ebebeb;
}
.s2{
display: block;
width: 50rpx;
border-radius: 5rpx;
margin: 0 7rpx;
height: 40rpx;
text-align: center;
line-height: 40rpx;
border: 1rpx solid #ececec;
}
}
}
}
}
}
// 保存修改的按钮
.btn-root{
position: fixed;
bottom: 0;
left: 0;
display: flex;
align-items: center;
width: 100%;
height: 140rpx;
background-color: #ffffff;
.btn{
box-sizing: border-box;
padding: 30rpx 0;
width: 100%;
border-radius: 15rpx;
margin: 25rpx;
color: #ffffff;
text-align: center;
background-color: $zsw-prinmary-color;
}
}

View File

@@ -0,0 +1,160 @@
<template>
<view class="root">
<view v-if="printerState">
<!-- 打印机设置 -->
<view class="printer-set">
<!-- 打印机设置 -->
<view class="printer-root">
<!-- title头 -->
<view class="title">
<span
v-for="(item, i) in titleList"
:key="item.id"
:class="{'activt': activ == i}"
@tap="tapTitle(i)"
>{{item.title}}</span>
</view>
<!-- 基础设置 -->
<view class="setup" v-show="activ == 0">
<!-- 称为设置 -->
<view class="call-name">
<p>呼叫称谓</p>
<view class="center">
<uni-data-checkbox mode="tag" v-model="callNamId" :localdata="callList" @change="change"></uni-data-checkbox>
</view>
</view>
<!-- 基本设置 -->
<view class="item" v-for="(item, i) in asic_setup" :key="i">
<p class="title-left">{{item.value}}</p>
<view class="center">
<span class="iconfont icon-laba" @tap="sound(item.value)"></span>
<switch color="#0a99ff" :checked="item.isOpen == 1" style="transform:scale(0.9)" @change="voiceSet($event, item.title, 1)"/>
</view>
</view>
</view>
<!-- 打印设置 -->
<view class="setup" v-show="activ == 1">
<!-- 商家联 -->
<view class="item-neworder">
<view class="menger">商家联打印</view>
<!-- <view class="mode-size">我的模板</view> -->
<view class="num-root">
<span>打印联数</span>
<view class="num">
<span class="iconfont icon-jianhao-" @tap="mMminus"></span>
<span class="s2">{{mangerNum}}</span>
<span class="iconfont icon-jiahao2fill" @tap="mAdd"></span>
</view>
</view>
</view>
<!-- 客户联 -->
<view class="item-neworder">
<view class="menger">客户联打印</view>
<!-- <view class="mode-size">我的模板</view> -->
<view class="num-root">
<span>打印联数</span>
<view class="num">
<span class="iconfont icon-jianhao-" @tap="uMinus"></span>
<span class="s2">{{userNum}}</span>
<span class="iconfont icon-jiahao2fill" @tap="uAdd"></span>
</view>
</view>
</view>
<!-- 用户取消订单打印 -->
<view class="item" v-for="(item, i) in print_setting" :key="i">
<p class="title-left">{{item.value}}</p>
<view class="center">
<switch color="#0a99ff" :checked="item.isOpen == 1" style="transform:scale(0.9)" @change="voiceSet($event, item.title, 2)"/>
</view>
</view>
</view>
<!-- 声音设置 -->
<view class="setup" v-show="activ == 2">
<view class="item" v-for="(item, i) in voice_setting" :key="i">
<p class="title-left">{{item.value}}</p>
<view class="center">
<span class="iconfont icon-laba" @tap="sound(item.value)"></span>
<switch color="#0a99ff" :checked="item.isOpen == 1" style="transform:scale(0.9)" @change="voiceSet($event, item.title, 3)"/>
</view>
</view>
</view>
</view>
</view>
<!-- 保存修改 -->
<view class="btn-root">
<view class="btn" @tap="serveSetup">保存修改</view>
</view>
</view>
<zswEmpty v-else title="未找到打印设备,请先添加设备" top="35vh"></zswEmpty>
</view>
</template>
<script>
import { allData } from './data.js'
import { allMethods } from './methods.js'
import zswEmpty from "@/components/zsw-empty/zsw-empty.vue";
export default {
components: {
zswEmpty,
},
data() {
return {
...allData.data()
}
},
onPullDownRefresh() {
this.setUserMOdelSound()
// 关闭下拉刷新
setTimeout( () => {
uni.stopPullDownRefresh()
}, 1200)
},
async onShow() {
if (!uni.getStorageSync('peinterList')) return
this.setUserMOdelSound()
},
methods: {
...allMethods
},
watch: {
// 商家联判断
mangerNum(newVal, oldVal) {
if(newVal <= 0) {
this.$zsw.toast('商家联新订单打印已关闭')
this.mangerNum = '关'
}
if(newVal > 3) {
this.$zsw.toast('最多只能打印三份')
this.mangerNum = 3
}
},
// 客户联判断
userNum(newVal, oldVal) {
if(newVal <= 0) {
this.$zsw.toast('客户联新订单打印已关闭')
this.userNum = '关'
}
if(newVal > 3) {
this.$zsw.toast('最多只能打印三份')
this.userNum = 3
}
}
}
}
</script>
<style lang="scss">
@import "./printerSetUp.scss"
</style>

View File

@@ -0,0 +1,145 @@
@font-face {
font-family: "iconfont";
src: url('@/static/font-icon/iconfont.ttf') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-fuzhi:before {
content: "\e602";
}
.icon-jiantoushang:before {
content: "\e62e";
}
.icon-jiahao2fill:before {
content: "\e728";
}
.icon-chengxinhezuowoshou:before {
content: "\e60a";
}
.icon-xuanzhuan:before {
content: "\e79a";
}
.icon-ziyuan:before {
content: "\e60e";
}
.icon-jiantou:before {
content: "\e60c";
}
.icon-laba:before {
content: "\e601";
}
.icon-new:before {
content: "\e667";
}
.icon-sousuo:before {
content: "\e62f";
}
.icon-jinrujiantou:before {
content: "\e8f1";
}
.icon-empty:before {
content: "\e621";
}
.icon-weixin:before {
content: "\e609";
}
.icon-yanzhengyanzhengma:before {
content: "\e624";
}
.icon-beizhu:before {
content: "\e669";
}
.icon-shoujihaoma:before {
content: "\e6da";
}
.icon-he_16zhengjianbianhaoguanli:before {
content: "\e706";
}
.icon-iconfontweixin:before {
content: "\e635";
}
.icon-jianhao-:before {
content: "\e605";
}
.icon-chahao:before {
content: "\e68b";
}
.icon-jiantouxia:before {
content: "\e62d";
}
.icon-paixu:before {
content: "\e600";
}
.icon-bianjishuru-xianxing:before {
content: "\e8cc";
}
.icon-shanchu:before {
content: "\e8b6";
}
.icon-jiahao:before {
content: "\eaf3";
}
.icon-jilu:before {
content: "\e686";
}
.icon-dayin-dayinji:before {
content: "\e619";
}
.icon-yingyong:before {
content: "\e60d";
}
.icon-zuobofang:before {
content: "\e63a";
}
.icon-zaixian:before {
content: "\e640";
}
.icon-lixian:before {
content: "\e73e";
}
.icon-24gl-printer:before {
content: "\e9bd";
}
.icon-binglianrongque:before {
content: "\e606";
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
src/static/img/check.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/static/img/demo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/static/img/printer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
src/static/img/store.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

24
src/store/index.js Normal file
View File

@@ -0,0 +1,24 @@
/**
* 模块vuex
* 作者zhang-shu-wei
* 日期2022年8月11日
* 邮箱2966211270@qq.com
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import { stateUserInfor, stateModelList } from './methods/stateData.js'
import { setUserInfor } from './methods/mutationMethodes.js'
const store = new Vuex.Store({
state: {
...stateUserInfor, // 用户信息
...stateModelList // 打印机自定义模板
},
mutations: {
...setUserInfor // 用户信息
},
actions: {}
})
export default store

View File

@@ -0,0 +1,78 @@
/**
* 模块vuex 修改state数据方法
* 作者zhang-shu-wei
* 日期2022年8月11日
* 邮箱2966211270@qq.com
* 注意mutation里面只能写同步方法不能写异步方法
*/
/**
* 存储用户数据
*/
export const setUserInfor = {
/**
* 用户同意授权获存储用户手机号码
*/
setUserPhone(state, data) {
state.userPhone = data
},
/**
* 存储TOKEN
*/
setToken(state, data) {
state.Authorization = data
},
/**
* 存储个人信息
*/
setMyUserDat(state, data) {
state.myUserData = data
},
/**
* 储存用户userId
*/
setUserId(state, data) {
state.userId = data
},
/**
* 存储用户跳转授权的地址
*/
setpoworUrl(state, data) {
state.powerUrl = data
},
/**
* 存储模板类型
* 1商户模板
* 2客户模板
*/
setModelTye(state, data) {
state.modelType = data
},
/**
* 存储系统通知详细信息
*/
setTextHtml(state, data) {
state.detailHtml = data
},
/**
* 商户自定义排序修改state 数据
*/
updataStrtiong(state, data) {
state.modelList = data
}
}

View File

@@ -0,0 +1,38 @@
/**
* 模块state数据
* 作者zhang-shu-wei
* 日期2022年8月11日
* 邮箱2966211270@qq.com
*/
/**
* 用户登录的数据
*/
export const stateUserInfor = {
Authorization: null, // TOKEN
myUserData: null, // 用户信息
userPhone: null, // 用户同意授权获取用户手机号码
userId: null, // 用户的userid
modelType: 1, // 模板类型,默认显示商户模板
powerUrl: '', // 跳转授权应用
detailHtml: '', // 系统公告详细内容
}
/**
* 打印机模板列表
*/
export const stateModelList = {
modelList: [
{
id: 202207260521,
br: '3行',
textTitle: '商品质量问题',
selectTitle: '商品质量问题',
signAlign: '居中',
signBig: '小号',
signHWBig: '不放大',
}
]
}

View File

@@ -0,0 +1,114 @@
page {
background-color: $zsw-aux-color;
}
.title-root {
padding: 20rpx 0;
color: #fff;
font-size: 40rpx;
font-weight: bold;
text-align: center;
background-color: $zsw-prinmary-color;
}
.app-root {
background-color: #fff;
display: flex;
border-bottom: 1rpx solid rgb(199, 199, 199);
p {
padding: 15rpx 0;
text-align: center;
width: 100%;
}
.active {
color: $zsw-prinmary-color;
border-bottom: 3rpx solid $zsw-prinmary-color;
}
}
.app-list-root {
margin: 25rpx;
display: grid;
grid-template-columns: repeat(2, 330rpx);
grid-gap: 40rpx;
grid-template-rows: 330rpx 330rpx 330rpx 330rpx;
.item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgb(255, 255, 255);
border-radius: 15rpx;
.btn {
display: inline-block;
background-color: $zsw-prinmary-color;
color: #fff;
padding: 7rpx 30rpx;
border-radius: 7rpx;
margin-top: 30rpx;
}
.left {
text-align: center;
}
//#ifdef MP-WEIXIN
img {
width: 100rpx;
height: 100rpx;
}
//#endif
//#ifdef APP-PLUS
img {
width: 80rpx;
height: 80rpx;
}
//#endif
}
}
.powor-root {
box-sizing: border-box;
border-radius: 15rpx;
padding: 20rpx;
background-color: #fff;
p {
width: 100%;
text-align: center;
padding: 10rpx 0;
}
.input-root {
.input-item {
padding: 15rpx 0 10rpx 0;
border-bottom: 1rpx solid $zsw-aux-color;
display: flex;
}
}
.btn-root {
margin-top: 30rpx;
display: flex;
border-top: 1rpx solid $zsw-aux-color;
p {
width: 100%;
text-align: center;
}
p:nth-child(2) {
color: $zsw-prinmary-color;
border-left: 2rpx solid $zsw-aux-color;
}
}
}

View File

@@ -0,0 +1,75 @@
<template>
<view>
<view class="title-root">京西云终端授权</view>
<!-- 应用授权列表 -->
<!-- <view class="app-root">
<p
v-for="(item, i) in topList"
:key="i"
:class="{ active: i == active }"
@tap="activeSwitch(i)"
>
{{ item.title }}
</p>
</view> -->
<view class="app-list-root">
<view class="item" v-for="(item, i) in appList" :key="i">
<view class="left">
<img :src="item.url" />
<p class="name">{{ item.name }}</p>
</view>
<view class="btn" @tap="powarH5App(item.jumpUrl, item.vendorId)"
>终端授权</view
>
</view>
</view>
<!-- 暂时废弃授权 -->
<uni-popup ref="powor" :mask-click="false">
<view class="powor-root">
<p>终端授权</p>
<view class="input-root">
<view class="input-item">
<span>店铺名称</span>
<input v-model="storeName" placeholder="店铺名称" />
</view>
<view class="input-item">
<span>店长电话</span>
<input v-model="storePhone" placeholder="店长电话" />
</view>
</view>
<view class="btn-root">
<p @tap="$refs.powor.close()">取消</p>
<p @tap="authorization">授权</p>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { allData } from "./data.js";
import { allMethods } from "./methods.js";
export default {
data() {
return {
...allData.data(),
};
},
onPullDownRefresh() {
setTimeout(() => {
uni.stopPullDownRefresh();
}, 1200);
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./appPower.scss";
</style>

View File

@@ -0,0 +1,56 @@
/**
* 应用授权数据
* 作者zhang-shu-wei
* 日期2022年8月24日
* 邮箱296621270@qq.com
*/
export const allData = {
data() {
return {
// 顶部标题
topList: [
{ title: '授权应用', id: 1 },
{ title: '已授权应用', id: 2 }
],
active: 0, // 选择高亮
// 应用授权列表
appList: [
{
url: 'https://image.jxc4.com/image/112db6d3ab56921a6cb179145fce5206.tem.png',
jumpUrl: 'https://openo2o.jddj.com/staticnew/widgets/sellerlogin.jsp',
name: '京东到家',
vendorId: 0
},
{
url: 'https://image.jxc4.com/image/ffbfccaf27aa958b0bbd5f853c0b211e.tem.png',
jumpUrl: 'https://eb-login.ele.me/login?redirect_url=https%3A%2F%2Fnr.ele.me%2Feleme_nr_bfe_retail%2Fapi_bind_shop%23%2FbindShop%3Fsource%3DC55282EE7F86B19FFE8910268E8EF5DB%26fromSys%3D2&return_url=https%3A%2F%2Fnracc.ele.me%2Fcrm%2Fsetwmstoken',
name: '饿佰零售',
vendorId: 3
},
{
url: 'https://image.jxc4.com/image/44d8613e58bbbb24c4bf2a7cb0f7f1af.tem.png',
jumpUrl: 'https://open-shangou.meituan.com/erp/login?code=Tdt%2F%2Bz9mnruDmwnnScP5B4Qor9fVRquPNZ6f5FKxkU1EoiSuxADP6GcFA7ZmXQTtJo78AkuHdpCj8CqF%2F8SrjV5CmBSOkPHy86J1Y3PNiaw%3D&auth_type=oauth&company_name=%E6%88%90%E9%83%BD%E8%8B%A5%E6%BA%AA%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8=#!/login',
name: '美团闪购',
vendorId: 1
},
{
url: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic3.zhimg.com%2Fv2-bf56eb665cbfb488a01991ff2de9e332_1200x500.jpg&refer=http%3A%2F%2Fpic3.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666348322&t=0cbfb68da3462cf73c0b223003e82ba8',
jumpUrl: 'https://fuwu.jinritemai.com/detail?from=open_partner_svcList&service_id=24070',
name: '抖音小时购',
vendorId: 14
},
{
url: 'https://www.jxc4.com/static/img/logo200.png',
jumpUrl: 'https://www.jxc4.com/',
name: '京西菜市',
vendorId: 9
}
],
storeName: '', // 商户名
storePhone: '', // 商户电话
TOKEN: '', // 获取管理系统token
}
}
}

View File

@@ -0,0 +1,138 @@
/**
* 应用授权方法
* 作者zhang-shu-wei
* 日期2022年8月24日
* 邮箱2966211270@qq.com
*/
export const allMethods = {
/**
* 切换标题
*/
activeSwitch(i) {
this.active = i
},
/**
* 跳转授权页面
*/
async powarH5App(url, id) {
uni.navigateTo({ url: `/subPackages/App/helpPower/helpPower?vendorId=${id}` })
},
/**
* 商户授权填写完成开始授权
*/
async authorization() {
let TOKEN = await this.$api.getMengerToken()
this.TOKEN = JSON.parse(TOKEN.data).token
if (this.storeName == '' || this.storePhone == '') return this.$zsw.toast('请填写店铺名和电话')
let payload = {
address: "成都市金牛区二环路北一段10号(西南交大地铁站C1口步行440米)",
autoReplyType: 0,
brandID: 140,
changePriceType: 0,
cityCode: 510100,
closeTime1: 1900,
closeTime2: 0,
deliveryRange: "3000",
deliveryRangeType: 3,
deliveryType: null,
districtCode: 510106,
id: 0,
idCardBack: "",
idCardFront: "",
idCardHand: "",
idCode: "",
idExpire: "",
idName: "",
idValid: "",
jxBrandFeeFactor: 0,
lat: 30.693381,
licence: "",
licence2Code: "",
licence2Expire: "",
licence2Image: "",
licence2Valid: "",
licenceAddress: "",
licenceCode: "",
licenceCorpName: "",
licenceExpire: "",
licenceOwnerName: "",
licenceType: null,
licenceValid: "",
lng: 104.045384,
marketAddFeeFactor: 0,
marketManName: "",
marketManPhone: "",
marketManRole: "",
name: this.storeName,
openTime1: 700,
openTime2: 0,
operatorName: "",
operatorName2: "",
operatorName3: "",
operatorPhone: "",
operatorPhone2: "",
operatorRole: "",
operatorRole2: "",
operatorRole3: "",
payPercentage: 20,
payeeAccountNo: "",
payeeBankBranchName: "",
payeeBankCode: "",
payeeName: "",
printerDisabled: 0,
printerKey: "",
printerSN: "",
printerVendorID: 0,
status: -1,
storeFrontPic: "",
storeInPic: "",
storeLevel: "C",
tel1: this.storePhone,
tel2: ""
}
uni.showLoading({ title: '请稍后' })
uni.request({
url: 'https://www.jxc4.com/v2/store/CreateStore',
data: { payload: JSON.stringify(payload) },
timeout: 10000,
dataType: 'json',
header: {
'content-type': 'application/x-www-form-urlencoded',
'token': this.TOKEN
},
method: 'POST',
success: (res) => {
uni.hideLoading()
if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data.code == 0) {
uni.setStorageSync('stores', res.data.data)
uni.navigateTo({ url: `/subPackages/App/power/power` })
} else if (res.data.code == -2) {
uni.dialog.alert("温馨提示", "身份认证失败,请登录", () => {
uni.reLaunch({
url: '/subPackages/login/loginPhone/loginPhone'
})
}, "好的")
} else {
// zsw.toast('请求出错', 2) 暂时只把错误丢出去
this.$zsw.toast('授权拉取失败', 2)
}
} else if (res.statusCode >= 400 && res.statusCode < 500) {
this.$zsw.toast('客户端错误', 2)
} else if (res.statusCode >= 500) {
this.$zsw.toast('服务器错误', 2)
} else {
this.$zsw.toast('网络错误', 2)
}
},
fail: (error) => {
uni.hideLoading()
this.$zsw.toast('网络请求超时', 2)
}
})
}
}

View File

@@ -0,0 +1,162 @@
.title-root {
padding: 20rpx 0;
color: #fff;
font-size: 40rpx;
font-weight: bold;
text-align: center;
background-color: $zsw-light-color;
}
.appPower {
margin-top: 25rpx;
margin-bottom: 25rpx;
.storeId {
padding: 25rpx 20rpx;
display: flex;
border-bottom: 1rpx solid rgb(214, 214, 214);
.text {
white-space: nowrap;
}
.ipt {
width: 100%;
}
}
.select-printer {
width: 100%;
}
.printerID {
display: flex;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid rgb(214, 214, 214);
.printer-equipment {
white-space: nowrap;
}
}
.auto-btn-rot{
display: flex;
padding: 25rpx;
.authorization-search{
width: 100%;
padding: 20rpx 0;
color: $zsw-prinmary-color;
font-size: 34rpx;
font-weight: bold;
text-align: center;
border-radius: 15rpx;
border: 1rpx solid $zsw-prinmary-color;
margin-right: 12.5rpx;
}
.authorization {
width: 100%;
padding: 20rpx 0;
color: #fff;
font-size: 34rpx;
font-weight: bold;
text-align: center;
background-color: $zsw-prinmary-color;
border-radius: 15rpx;
margin-left: 12.5rpx;
}
}
}
.image {
width: 750rpx;
}
.setup {
color: red;
padding-left: 30rpx;
border-left: 6rpx solid red;
margin-left: 10rpx;
margin-bottom: 30rpx;
}
.warring-ID {
border-bottom: 1rpx solid red !important;
}
.setup-root {
box-sizing: border-box;
padding: 0rpx 30rpx;
padding-bottom: 25rpx;
p {
font-weight: bold;
margin-top: 30rpx;
margin-bottom: 10rpx;
}
}
// 关闭搜搜店铺
.close-model {
background-color: $zsw-light-color;
padding: 20rpx;
color: #ffffff;
text-align: center;
}
// 搜索店铺
.serch-storeId{
background-color: #fff;
padding: 20rpx 20rpx 0 20rpx;
.empty-text{
text-align: center;
padding: 50rpx 0;
color: #8b8b8b;
}
.storeId {
padding: 20rpx 0;
display: flex;
border-bottom: 1rpx solid rgb(214, 214, 214);
.text {
white-space: nowrap;
}
.ipt {
width: 100%;
}
.btn{
background-color: $zsw-prinmary-color;
color: #fff;
padding: 10rpx 10rpx;
border-radius: 10rpx;
}
}
.store-list{
padding: 25rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
.store-name{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.store-text{
white-space: nowrap;
padding: 5px 10rpx;
background-color: $zsw-light-color;
color: #fff;
border-radius: 10rpx;
}
}
}

View File

@@ -0,0 +1,170 @@
<template>
<view>
<!-- #ifdef APP-PLUS -->
<view class="title-root" @tap="openLlqUrl">点击打开浏览器</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="title-root" @tap="copyUrl">复制授权链接</view>
<!-- #endif -->
<view class="appPower">
<view class="storeId" :class="{'warring-ID': warringID}">
<text class="text">授权平台ID</text>
<input class="ipt" type="text" :placeholder="storeIDText" v-model="vendorStoreId" />
</view>
<view class="printerID" :class="{'warring-ID': warringPrinterID}">
<text class="printer-equipment"> </text>
<uni-data-select
placeholder="选择打印机"
class="select-printer"
v-model="selectField"
:localdata="selectList"
:clear="false"
@change="changeSelect"
></uni-data-select>
</view>
<view class="auto-btn-rot">
<view class="authorization-search" @tap="searchStoreID">搜索授权ID</view>
<view class="authorization" @tap="getAuthorization">确定授权</view>
</view>
</view>
<view class="setup">授权步骤</view>
<view class="setup-root">
<p>第一步</p>
<!-- #ifdef MP-WEIXIN -->
<view>小程序用户复制授权地址到浏览器登录第三方平台也可以点击搜索授权ID</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view>App用户点击打开浏览器跳转到第三方授权平台登录第三方平台也可以点击搜索授权ID</view>
<!-- #endif -->
<p>第二步</p>
<view>在第三方平台找到平台ID编号并记住平台编号</view>
<p>第三步</p>
<view>回到京西云打印机应用找到需要授权对应的平台ID编号</view>
<p>第四步</p>
<view>输入第二步获取到的第三方平台</view>
<p>第五步</p>
<view>选择需要授权的打印设备</view>
<p>第六步</p>
<view
>如果第三方平台ID编号没有错误那么恭喜您授权成功否则授权失败</view
>
<p>授权完成</p>
<view
>当打印机授权成功后打印机将会打印出一个测试订单成功出单证明授权成功</view
>
<p>注意</p>
<view>如遇到授权问题请联系平台客服</view>
<!-- 预览模板弹窗 -->
<uni-popup ref="storeID">
<view class="close-model" @tap="$refs.storeID.close()">点击关闭</view>
<view class="serch-storeId">
<view class="storeId" :class="{'warring-ID': isStorePhone}">
<text class="text">手机号</text>
<input class="ipt" type="text" placeholder="请输入店主手机号" v-model="storePhone" />
<text class="text btn" @tap="storePhoneGetStoreName">搜索店铺</text>
</view>
<view v-if="storeListData.length == 0" class="empty-text">暂无店铺...</view>
<view v-else>
<view class="store-list"
v-for="item in storeListData"
:key="item.id"
>
<text class="store-name">{{ item.name }}</text>
<text class="store-text" @tap="selectStoreId(item.StoreMaps)">选择店铺</text>
</view>
</view>
</view>
</uni-popup>
</view>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
export default {
data() {
return {
openUrl: "", // 跳转到授权链接地址
vendorOrgCode: "", // 授权平台总门店
selectField: "打印机编号", // 已有打印机编号
storeIDText: "", // placeholder 占位文字
navTitile: "", // 动态修改导航栏标题
selectList: [], // 打印机
printerNum: "", // 获取到的打印机编号
printerKey: "", // 打印机key
vendorStoreId: "", // 第三方平台ID
TOKEN: "", // 管理系统TOKEN
vendorId: 0, // 三方平台
testId: 0,
warringID: false, // 是否输入授权平台id
warringPrinterID: false, // 是否选择绑定设备
isStorePhone: false, // 店主手机号是否正确
storePhone: '', // 店主手机号
storeListData: [], // 通过手机号搜索到的店铺
vendorStoreConds: {}, // 搜索平台绑定情况
};
},
onLoad(options) {
switch (options.vendorId) {
case "0":
this.storeIDText = "请输入京东商户ID";
this.navTitile = "京东到家授权";
this.vendorOrgCode = "" + 320406;
this.openUrl =
"https://openo2o.jddj.com/staticnew/widgets/sellerlogin.jsp";
this.vendorStoreConds = {"0":"1"}
break;
case "3":
this.storeIDText = "请输入饿佰商户ID";
this.navTitile = "饿佰零售授权";
this.vendorOrgCode = "" + 34665;
this.openUrl =
"https://eb-login.ele.me/login?redirect_url=https%3A%2F%2Fnr.ele.me%2Feleme_nr_bfe_retail%2Fapi_bind_shop%23%2FbindShop%3Fsource%3DC55282EE7F86B19FFE8910268E8EF5DB%26fromSys%3D2&return_url=https%3A%2F%2Fnracc.ele.me%2Fcrm%2Fsetwmstoken";
this.vendorStoreConds = {"3":"1"}
break;
case "1":
this.storeIDText = "请输入美团商户ID";
this.navTitile = "美团闪购授权";
this.vendorOrgCode = "" + 5873;
this.openUrl =
"https://open-shangou.meituan.com/erp/login?code=Tdt%2F%2Bz9mnruDmwnnScP5B4Qor9fVRquPNZ6f5FKxkU1EoiSuxADP6GcFA7ZmXQTtJo78AkuHdpCj8CqF%2F8SrjV5CmBSOkPHy86J1Y3PNiaw%3D&auth_type=oauth&company_name=%E6%88%90%E9%83%BD%E8%8B%A5%E6%BA%AA%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8=#!/login";
this.vendorStoreConds = {"1":"1"}
break;
case "14":
this.storeIDText = "请输抖店商户ID";
this.navTitile = "抖音小时购授权";
this.vendorOrgCode = "" + 57939570;
this.openUrl =
"https://fuwu.jinritemai.com/detail?from=open_partner_svcList&service_id=24070";
this.vendorStoreConds = {"14":"1"}
break;
case "9":
this.storeIDText = "请输入京西菜市商户ID";
this.navTitile = "京西菜市授权";
this.vendorOrgCode = "" + "";
this.openUrl = "https://www.jxc4.com/";
this.vendorStoreConds = {"9":"1"}
break;
}
this.vendorId = parseInt(options.vendorId);
this.setRuler();
uni.setNavigationBarTitle({
title: this.navTitile,
});
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss" scoped>
@import "./helpPower.scss";
</style>

View File

@@ -0,0 +1,481 @@
import store from "../../../store";
/**
* 应用授权
* 作者: zhangshuwei
* 日期: 2022年12月19日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 到浏览器打开
*/
// #ifdef APP-PLUS
openLlqUrl() {
uni.dialog.alert(
"温馨提示",
"授权地址已复制,正在跳转至浏览器进行授权,如果跳转失败请手动打开浏览器粘贴授权地址进行授权",
() => {
uni.setClipboardData({
data: this.openUrl,
});
plus.runtime.openURL(this.openUrl);
},
"好的"
);
},
// #endif
// #ifdef MP-WEIXIN
copyUrl() {
uni.dialog.alert(
"温馨提示",
"授权链接复制成功,请打开浏览器进行授权!",
() => {
uni.setClipboardData({
data: this.openUrl,
});
},
"好的"
);
},
// #endif
searchStoreID() {
this.$refs.storeID.open('top')
},
/**
* 获取授权打印机列表
*/
async setRuler() {
let data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: 0,
page_size: 100,
};
let resList = await this.$api.setPrinterList(data);
let newData = JSON.parse(resList.data);
if (resList.code == 0 && newData.totalCount) {
let newArr = [];
let newObj = {};
newData.data.forEach((element) => {
newObj = {
value: element.print_no,
text: element.name,
key: element.print_key,
};
newArr.push(newObj);
});
this.selectList = newArr;
}
},
/**
* 获取选择的打印机
*/
changeSelect(e) {
this.printerNum = e;
// 获取当前打印机key
let key = this.selectList.filter((item) => item.value == e);
this.printerKey = key[0].key;
},
/**
* 第一步获取管理系统TOKEN
*/
async getAuthorization() {
if (this.vendorStoreId == "") {
this.warringID = true
return this.$zsw.toast("请输入授权平台ID");
}
if (this.printerNum == "") {
this.warringPrinterID = true
return this.$zsw.toast("请选择一台打印机");
}
let TOKENRes = await this.$api.getMengerToken();
this.TOKEN = JSON.parse(TOKENRes.data).token;
// 查询用户是否有京西门店
this.setUserJxISStore();
},
/**
* (第二步)查询授权用户是否有京西门店
*/
async setUserJxISStore() {
this.$wx.showLoading();
let data = {
vendorStoreId: this.vendorStoreId,
vendorId: this.vendorId,
};
let newData = await this.allowApi(
"/v2/store/PrintCheckAccountAuthorization",
data,
"POST"
);
if (newData.code == 0 && newData.data) {
// 有门店.2-1直接绑定打印机
this.testId = newData.data
this.bindingStore(newData.data);
} else {
// 没有门店2-1拉取第三方平台创建数据
this.createStore();
}
},
/**
* (第三步-有门店)有京西门店直接绑定打印机
*/
async bindingStore(id) {
let data = {
storeId: id,
printSn: this.printerNum,
printKey: this.printerKey,
};
let newData = await this.allowApi(
"/v2/store/BindJxPrinter",
data,
"POST"
);
if (newData.code == 0) {
this.moduleOk()
} else {
this.showModule();
}
this.$wx.hideLoading();
},
/**
* (第三步-没有门店)创建门店前使用拉取到的数据查询店铺是否已经创建
*/
async createStore() {
let data = {}
if (this.vendorId == 9) {
data.vendorStoreID = this.vendorStoreId
data.vendorID = this.vendorId
} else {
data.vendorStoreID = this.vendorStoreId
data.vendorID = this.vendorId
data.vendorOrgCode = this.vendorOrgCode
}
let newData = await this.allowApi(
"/v2/store/GetVendorStore",
data,
"GET"
);
try {
} catch (error) {
}
if (newData.code == 0) {
let store = JSON.parse(newData.data);
/**
* (第三步-2查询门店
*/
let data = {
earningType: 0,
name: store.name,
address: store.address,
statuss: [-1, 0, 1, -2],
vendorStoreCond: "and",
vendorStoreConds: {
0: "0",
1: "0",
2: "0",
3: "0",
4: "0",
5: "0",
9: "0",
11: "0",
14: "0",
},
storeCourier: 0,
courierStoreCond: "and",
courierStoreConds: { 101: 0, 102: 0 },
offset: 0,
pageSize: 30,
storeLevels: ["A", "B", "C", "D", "E"],
orderCountFrom: 0,
orderCountTo: 0,
isBussinessStatus: true,
};
let getStoreData = await this.allowApi(
"/v2/store/GetStores",
data,
"GET"
);
if (getStoreData.code == 0) {
let storeList = JSON.parse(getStoreData.data);
if (storeList.totalCount > 0) {
// 门店已将创建了直接绑定
this.linkStore(storeList.stores[0].id);
} else {
// 没有创建门店,去创建门店
this.getJxStore(store);
}
} else {
this.showModule();
}
} else {
this.$wx.hideLoading();
if (this.vendorId == 9) {
uni.dialog.alert("授权失败", `未找到ID为${this.vendorStoreId}的京西门店`, () => { }, "确定");
} else {
uni.dialog.alert("授权失败", `${newData.desc}`, () => { }, "确定");
}
}
},
/**
* (第四步)创建门店
*/
async getJxStore(store) {
let oldData = {
address: store.address,
autoReplyType: store.autoReplyType,
brandID: store.brandID,
changePriceType: store.changePriceType,
cityCode: store.cityCode,
closeTime1: store.closeTime1,
closeTime2: store.closeTime2,
deliveryRange: store.deliveryRange,
deliveryRangeType: store.deliveryRangeType,
deliveryType: null,
districtCode: store.districtCode,
id: store.id,
idCardBack: store.idCardBack,
idCardFront: store.idCardFront,
idCardHand: store.idCardHand,
idCode: store.idCode,
idExpire: store.idExpire,
idName: store.idName,
idValid: store.idValid,
jxBrandFeeFactor: store.jxBrandFeeFactor,
lat: store.lat,
licence: store.licence,
licence2Code: store.licence2Code,
licence2Expire: store.licence2Expire,
licence2Image: store.licence2Image,
licence2Valid: store.licence2Valid,
licenceAddress: store.licenceAddress,
licenceCode: store.licenceCode,
licenceCorpName: store.licenceCorpName,
licenceExpire: store.licenceExpire,
licenceOwnerName: store.licenceOwnerName,
licenceType: store.licenceType,
licenceValid: store.licenceValid,
lng: store.lng,
marketAddFeeFactor: store.marketAddFeeFactor,
marketManName: store.marketManName,
marketManPhone: store.marketManPhone,
marketManRole: store.marketManRole,
name: `${store.name}(京西云打印机)`,
openTime1: store.openTime1,
openTime2: store.openTime2,
operatorName: store.operatorName,
operatorName2: store.operatorName2,
operatorName3: store.operatorName3,
operatorPhone: store.operatorPhone,
operatorPhone2: store.operatorPhone2,
operatorRole: store.operatorRole,
operatorRole2: store.operatorRole2,
operatorRole3: store.operatorRole3,
payPercentage: store.payPercentage,
payeeAccountNo: store.payeeAccountNo,
payeeBankBranchName: store.payeeBankBranchName,
payeeBankCode: store.payeeBankCode,
payeeName: store.payeeName,
printerDisabled: store.printerDisabled,
printerKey: this.printerKey,
printerSN: this.printerNum,
printerVendorID: 205,
status: store.status,
storeFrontPic: store.storeFrontPic,
storeInPic: store.storeInPic,
storeLevel: store.storeLevel,
tel1: store.tel1,
tel2: store.tel2,
};
let storeData = {
payload: JSON.stringify(oldData),
};
let createStoreData = await this.allowApi(
"/v2/store/CreateStore",
storeData,
"POST"
);
if (createStoreData.code == 0) {
this.testId = createStoreData.data
this.linkStore(createStoreData.data);
} else {
this.showModule();
}
},
/**
* (最后一步绑定门店)门店创建成功,绑定绑定门店
*/
async linkStore(id) {
let playload = {
bussinessStatus: null,
vendorStoreID: this.vendorStoreId,
status: 1,
isSysCat: 0,
vendorID: 1,
autoPickup: 1,
deliveryCompetition: 1,
pricePercentage: 100,
isSync: 0,
isSupplyGoods: 0,
pricePercentagePack: "",
freightDeductionPack: "",
fakeOpenStart: 0,
fakeOpenStop: 0,
vendorOrgCode: this.vendorOrgCode,
vendorStoreName: "",
deliveryFeeDeductionSill: 0,
deliveryFeeDeductionFee: 0,
isOrder: 0,
ybAppID: "",
createDeliveryType: 1,
ybAppKey: "",
ybStorePrefix: "",
syncRule: 0,
vendorPayPercentage: null,
};
let data = {
storeID: id,
vendorID: this.vendorId,
payload: JSON.stringify(playload),
vendorOrgCode: this.vendorOrgCode,
};
let newData = await this.allowApi(
"/v2/store/AddStoreVendorMap",
data,
"POST"
);
this.$wx.hideLoading();
this.moduleOk()
},
/**
* 授权模块封装
*/
allowApi(url, data, method) {
return new Promise((resolve, reject) => {
uni.request({
url: `https://www.jxc4.com${url}`,
data: data,
timeout: 10000,
dataType: "json",
header: {
"content-type": "application/x-www-form-urlencoded",
token: this.TOKEN,
},
method: method,
success: (res) => {
resolve(res.data);
},
});
});
},
/**
* 授权失败信息
*/
showModule() {
this.$wx.hideLoading();
uni.dialog.confirm(
"授权失败",
"很遗憾授权失败,请联系运营,或者再试一次!!!!",
() => {
console.log("再试一次");
},
() => {
//#ifdef MP-WEIXIN
uni.makePhoneCall({
phoneNumber: "18048531223",
});
//#endif
//#ifdef APP-PLUS
plus.device.dial("18048531223", true);
//#endif
},
"再试一次",
"联系客服"
);
},
/**
* 授权成功信息
*/
async moduleOk() {
uni.dialog.alert("授权成功", "恭喜您授权成功", () => {
uni.navigateBack()
}, "好的");
let data = {
vendorOrderID: 'test',
vendorID: this.testId
}
let res = await this.allowApi('/v2/order/PrintOrder', data, 'PUT')
},
/**
* 通过店铺手机号查询店铺
*/
async storePhoneGetStoreName() {
let phoneRuler = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
console.log(this.storePhone)
if(!phoneRuler.test(this.storePhone)) {
this.isStorePhone = true
return this.$zsw.toast('请输入正确的手机号')
}
let data = {
keyword: this.storePhone,
vendorStoreCond: 'and',
vendorStoreConds: this.vendorStoreConds
}
this.$wx.showLoading();
let storeName = await this.allowApi(
"/v2/store/GetStores",
data,
"GET"
);
this.$wx.hideLoading();
if(storeName.code == 0) {
if(storeName.data != 'null') {
console.log(JSON.parse(storeName.data).stores)
this.storeListData = JSON.parse(storeName.data).stores
} else {
this.storeListData = []
}
} else {
this.$zsw.toast('搜索店铺异常')
this.storeListData = []
}
},
/**
* 能通过我们系统查询出来,肯定就是绑定我们平台
*/
selectStoreId(item) {
item.forEach((store) => {
if(this.vendorId == store.vendorID) {
this.vendorStoreId = store.vendorStoreID
}
})
this.$refs.storeID.close()
}
}

View File

@@ -0,0 +1,144 @@
page{
background-color: #f3f3f3;
}
.input-root{
box-sizing: border-box;
background-color: #fff;
.input-item{
box-sizing: border-box;
display: flex;
align-items: center;
border-bottom: 1rpx solid rgb(235, 235, 235);
padding: 30rpx;
i{
margin-right: 18rpx;
color: #808080;
}
.icon-ziyuan{
display: inline-block;
box-sizing: border-box;
font-size: 40rpx;
padding: 5rpx 30rpx;
color: $zsw-prinmary-color;
}
input{
width: 100%;
}
}
.send-code{
display: flex;
input{
padding-right: 15rpx;
}
span{
padding: 8rpx 15rpx;
border-radius: 10rpx;
white-space: nowrap;
background-color: $zsw-prinmary-color;
color: #fff;
}
}
}
.attention-root{
margin-top: 40rpx;
background-color: #fff;
box-sizing: border-box;
padding: 30rpx;
color: red;
border-bottom: 1rpx solid rgb(235, 235, 235);
p{
margin: 10rpx 0;
}
}
.tutorial-root{
box-sizing: border-box;
margin: 40rpx 20rpx;
border: 1rpx solid rgb(226, 226, 226);
&>p{
background-color: #e0e0e0;
padding: 25rpx;
color: red;
flex: 1;
}
>view{
background-color: #fff;
padding: 25rpx;
display: flex;
flex-direction: column;
align-items: center;
// #ifdef APP-PLUS
img{
border: 1rpx solid rgb(235, 235, 235);
margin-top: 15rpx;
border-radius: 10rpx;
width: 100%;
}
// #endif
// #ifdef MP-WEIXIN
img{
border: 1rpx solid rgb(235, 235, 235);
margin-top: 15rpx;
border-radius: 10rpx;
width: 640rpx;
height: 350rpx;
}
// #endif
}
}
.addPrinter-root{
display: flex;
position: sticky;
bottom: 0;
background-color: #fff;
padding: 25rpx 0;
button{
padding: 5rpx 90rpx;
}
.qr-code{
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
background-color: #fff;
}
.ok-add-printer{
background-color: $zsw-prinmary-color;
color: #fff;
}
}
.error{
border-bottom: 1rpx solid #dd0a0a !important;
}
.error-text{
color: #dd0a0a !important;
}
// 点击拨号
.phone{
background-color: $zsw-prinmary-color;
color: #fff;
padding: 0 10rpx;
margin-right: 10rpx;
border-radius: 8rpx;
}

View File

@@ -0,0 +1,150 @@
<template>
<view>
<!-- 打印机输入 -->
<view class="input-root">
<view class="input-item" :class="{ error: rulerPrinter }">
<i
class="iconfont icon-he_16zhengjianbianhaoguanli"
:class="{ 'error-text': rulerPrinter }"
></i>
<input
v-model="printerNum"
placeholder="打印机编号 (查看打印机底部标签)"
type="number"
/>
<i class="iconfont icon-ziyuan" @tap="qrCode"></i>
</view>
<view class="input-item" :class="{ error: rulerName }">
<i
class="iconfont icon-beizhu"
:class="{ 'error-text': rulerName }"
></i>
<input
v-model="printerName"
placeholder="设备名字 (例如xx店铺打印机)"
/>
</view>
<view class="input-item" :class="{ error: rulerPhone }">
<i
class="iconfont icon-shoujihaoma"
:class="{ 'error-text': rulerPhone }"
></i>
<input
v-model="phone"
placeholder="绑定手机号码 (标识打印机)"
type="number"
/>
</view>
<view class="input-item send-code" :class="{ error: rulerCode }">
<i
class="iconfont icon-yanzhengyanzhengma"
:class="{ 'error-text': rulerCode }"
></i>
<input type="number" v-model="code" placeholder="验证码" />
<span @tap="sendCode">{{ codeText }}</span>
</view>
</view>
<!-- 注意事项 -->
<view class="attention-root">
<p>注意</p>
<view>
<p>
1.添加打印机前请确定打印机已经开启并处于联网状态否则将无法添加设备
</p>
<p>
2.添加打印机需要绑定手机号用于表示该打印机所属人是打印机的唯一表示请认真填写
</p>
<p>
3.当该打印机被其他店铺绑定时打印机换绑需要验证原手机号验证成后才可以进行添加
</p>
<p>
4.如原手机号无法使用请联系运营18048531223<span
class="phone"
@tap="playPhone"
>点击拨号</span
>进行申诉处理
</p>
</view>
</view>
<!-- 温馨提示 -->
<view class="tutorial-root">
<p>温馨提示</p>
<view>
<p>打印机编号位于打印机底部二维码快捷添加</p>
<img
src="http://image.jxc4.com/image/59e7b6d69ddc73f35d14af4ca0b6685d.tem.jpg"
/>
</view>
</view>
<!-- 确定按钮@tap="toggle" -->
<view class="addPrinter-root">
<button class="qr-code" @tap="qrCode">扫码输入</button>
<button class="ok-add-printer" @tap="addPrinter">确定添加</button>
</view>
<!-- 打印机已被绑定 -->
<zsw-ruler-printer
ref="ruler"
@determine="determine"
@send="send"
:sendCOde="removeCodeText"
:Unbinding="Unbinding"
title="解绑打印机"
phoneText="原手机号码"
promptText="该打印机已绑定其他账号需要解绑后才能添加如原手机号无法验证请联系运营【18048531223】或"
>
</zsw-ruler-printer>
<uni-popup ref="message" type="message">
<uni-popup-message
style="text-align: center"
:type="msgType"
:message="messageText"
:duration="2000"
></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
import { allData } from "./data.js";
import zswRulerPrinter from "@/components/zsw-ruler-printer/zsw-ruler-printer";
export default {
components: {
zswRulerPrinter,
},
data() {
return {
...allData.data(),
};
},
mounted() {
if (!uni.getStorageSync("userPhone")) {
this.$zsw.toast("请先登录");
} else {
this.phone = uni.getStorageSync("userPhone");
}
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./addPrinter.scss";
</style>

View File

@@ -0,0 +1,33 @@
/**
* 首页data数据
* 作者: zhang-shu-wei
* 日期: 2022年8月13日
* 邮箱: 2966211270@qq.com
*/
export const allData = {
data() {
return {
printerNum: '', // 打印机编号
printerName: '', // 打印机备注
phone: null, // 手机号码
code: null, // 手机验证码
bizId: null, // 添加打印机bizid
codeText: '发送验证码', // 发送验证码切换字体
timerNum: 59, // 倒计时
throttle: false, // 节流
removeCodeText: '发送验证码', // 发送验证码切换字体
removeTimerNum: 59, // 倒计时
removeThrottle: false, // 节流
removeBizId: null, // 解绑打印机bizid
msgType: null, // 提示信息
messageText: null, // 提示文本
rulerPrinter: false, // 打印机规则
rulerName: false, // 打印机备注规则
rulerPhone: false, // 打印机手机号规则
rulerCode: false, // 打印机验证码规则
Unbinding: '', // 解绑手机号码
}
}
}

View File

@@ -0,0 +1,258 @@
/**
* 添加打印机
* 作者: zhang-shu-wei
* 日期: 2022年8月13日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 查询打印机是否被绑定
*/
async setPrinterOnline() {
let data = {
print_no: this.printerNum,
}
let res = await this.$api.setPrinterBind(data)
if (res.code == 0) {
let newData = JSON.parse(res.data)
if (newData.isBind) {
this.toggle()
this.Unbinding = newData.phone
return true
} else {
return false
}
} else {
this.topMsg('查询打印机失败,请重试', 'error')
return true
}
},
/**
* 添加打印机
*/
async addPrinter() {
// 条件判断
let ruler = this.ruler()
if (!ruler) return
// 在此检查打印机是否被绑定
if (!this.bizId) {
this.topMsg('请先获取验证码', 'error')
this.rulerCode = true
return
}
this.rulerCode = false
let newData = [{ 'print_no': this.printerNum, 'name': this.printerName }]
let data = {
app_id: 1000,
prints: JSON.stringify(newData),
phone: this.phone,
code: this.code,
biz_id: this.bizId
}
let res = await this.$api.addPrinter(data)
if (res.code == 0) {
// 没有打印机给他添加打印机
if (!uni.getStorageSync('peinterList')) {
uni.setStorageSync('printerName', this.printerName)
uni.setStorageSync('peinterList', this.printerNum)
}
this.topMsg('添加成功', 'success')
setTimeout(() => {
uni.switchTab({ url: '/pages/home/home' })
}, 1000);
} else {
this.topMsg('添加失败,请检查打印机是否联网', 'error')
}
},
/**
* 发送验证码
*/
async sendCode() {
let rulerPhone = /^1\d{10}$/
if (!rulerPhone.test(this.phone)) {
this.rulerPhone = true
this.topMsg('手机号码输入错误')
return
}
this.rulerPhone = false
// 节流
if (this.throttle) return
// 检查打印机是否被绑定
let rulerData = await this.setPrinterOnline()
if (rulerData) return
// 获取手机验证码
let res = await this.$api.getPhoneCode(this.phone)
if (res.code == 0) {
this.topMsg('验证码发送成功', 'success')
this.bizId = JSON.parse(res.data).bizId
// 验证码发送成功开启节流
var tiem = null
this.throttle = true
clearInterval(tiem)
tiem = setInterval(() => {
this.codeText = `${this.timerNum--}秒后重新发送`
if (this.timerNum <= 0) {
this.throttle = false
clearInterval(tiem)
this.timerNum = 59
this.codeText = '重新发送'
}
}, 1000)
} else {
this.topMsg('验证码发送失败')
}
},
/**
* 扫描二维码
*/
qrCode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['barCode', 'qrCode'],
barCodeInput: false,
success: res => {
this.printerNum = res.result
}
})
},
/**
* 解绑打印机发送验证码
*/
async send(phone) {
if (this.removeThrottle) return
// 获取手机验证码
let res = await this.$api.getPhoneCode(phone)
if (res.code == 0) {
this.topMsg('验证码发送成功', 'success')
this.bizId = JSON.parse(res.data).bizId
// 验证码发送成功开启节流
var tiem = null
if (this.removeThrottle) return
this.removeThrottle = true
clearInterval(tiem)
tiem = setInterval(() => {
this.removeCodeText = `${this.removeTimerNum--}秒后重新发送`
if (this.removeTimerNum <= 0) {
this.removeThrottle = false
clearInterval(tiem)
this.removeTimerNum = 59
this.removeCodeText = '重新发送'
}
}, 1000)
} else {
this.topMsg('验证码发送失败')
}
},
/**
* 确定解绑打印机
*/
async determine(data) {
let params = {
app_id: '1000',
print_nos: this.printerNum,
phone: data.phone,
code: data.code,
biz_id: this.bizId
}
let res = await this.$api.delPrinter(params)
if (res.code == 0) {
uni.removeStorageSync(printerName)
uni.removeStorageSync(peinterList)
this.topMsg('打印机解绑成功', 'success')
this.code = ''
this.bizId = ''
setTimeout(() => {
this.$refs.ruler.$refs.popup.close()
}, 1000)
} else {
this.topMsg('解绑失败,请联系运营')
setTimeout(() => {
this.$refs.ruler.$refs.popup.close()
}, 1000)
}
},
/**
* 打印机被绑定以后解绑
*/
toggle() {
this.$refs.ruler.$refs.popup.open('center')
},
/**
* 错误提示信息
*/
topMsg(text, type = 'error') {
this.msgType = type
this.messageText = text
this.$refs.message.open()
},
/**
* 拨打电话
*/
playPhone() {
//#ifdef MP-WEIXIN
uni.makePhoneCall({
phoneNumber: '18048531223'
});
//#endif
//#ifdef APP-PLUS
plus.device.dial('18048531223', true);
//#endif
},
/**
* 打印机规则
*/
ruler() {
if (this.printerNum.length < 1 || this.printerNum.length > 30) {
this.rulerPrinter = true
this.topMsg('请输入正确的打印机编号')
return
}
this.rulerPrinter = false
if (this.printerName.length < 2 || this.printerName > 15) {
this.rulerName = true
this.topMsg('备注字数范围 2 - 15 字')
return
}
this.rulerName = false
let rulerPhone = /^1\d{10}$/
if (!rulerPhone.test(this.phone)) {
this.rulerPhone = true
this.topMsg('手机号码输入错误')
return
}
this.rulerPhone = false
let rulerCode = /^\d{6}$/
if (!rulerCode.test(this.code)) {
this.rulerCode = true
this.topMsg('验证码输入错误')
return
}
this.rulerCode = false
return 'ruler-ok'
}
}

View File

@@ -0,0 +1,116 @@
<template>
<view>
<!-- <p class="title">帮助中心</p> -->
<view class="help-root">
<view
class="item"
v-for="item in helpDataList"
:key="item.id"
@tap="getHelpDetaole(item.link)"
>
<p class="text">{{ item.msg }}</p>
<i class="iconfont icon-jinrujiantou"></i>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
noticeData: [],
type: 3, // 类型帮助
pageSize: 30, // 每页15条
pageNumber: 1, // 页码
count: 0, // 总条数
helpDataList: [], // 公告数据
}
},
onShow() {
this.helpDataList = []
this.getHelp()
},
onReachBottom(e) {
let sum = this.pageNumber * this.pageSize
let size = this.count
if (sum >= size) {
return this.$zsw.toast('~到底了~')
}
this.pageNumber += 1
// 重新获取数据
this.getHelp()
},
onPullDownRefresh() {
setTimeout(() => {
this.pageNumber = 1
this.helpDataList = []
this.getHelp()
uni.stopPullDownRefresh()
}, 1200)
},
methods: {
getHelpDetaole(link) {
uni.navigateTo({
url: `/subPackages/home-sub/helpDetails/helpDetails?url=${link}`,
})
},
// 获取帮助
async getHelp() {
let helpPlayload = {
notice_type: this.type,
page_number: this.pageNumber,
page_size: this.pageSize,
}
let helpData = await this.$api.img_notice_help(helpPlayload)
if (helpData.code == 0) {
this.count = JSON.parse(helpData.data).count
this.helpDataList = [
...this.helpDataList,
...JSON.parse(helpData.data).result,
]
} else {
this.$zsw.toast('系统错误', 2)
}
},
},
}
</script>
<style lang="scss">
page {
background-color: $zsw-aux-color;
}
.title {
background-color: $zsw-prinmary-color;
padding: 10rpx 0;
text-align: center;
color: #fff;
}
.help-root {
background-color: #fff;
.item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid rgb(212, 212, 212);
.text {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
}
</style>

View File

@@ -0,0 +1,21 @@
<template>
<web-view :src="url" />
</template>
<script>
export default {
data() {
return {
url:''
}
},
onLoad(options) {
this.url = options.url
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,41 @@
/**
* 打印机列表
* 作者: zhangshuwei
* 日期: 2022年8月16日
* 邮箱: 2966211270@qq.com
*/
export const allData = {
data() {
return {
msgType: null, // 顶部提示
messageText: null, // 顶部提示文字
removeCodeText: '发送验证码', // 发送验证码
phone: '', // 手机号码
printerId: null, // 删除打印机的id
bizId: null, // 验证码
throttle: false, // 节流阀
timerNum: 59, // 秒数
printerName: null, // 正在修改打印机的名字
determineName: '', // 修改后打印机的名字
deterKey: '', // 打印机key
// 条件列表
rulerList: [
{title: '全部', value: 0},
{title: '正常', value: 1},
{title: '缺纸', value: 2},
{title: '在线', value: 1},
{title: '离线', value: 0}
],
activt: 0, // 选择高亮
pageSize: 100, // 每一页显示条数
offSite: 0, // 每一页跳过条数
list: [], // 打印机列表
totalCount: 0, // 总条数
text: '', // 测试打印内容
}
}
}

View File

@@ -0,0 +1,245 @@
/**
* 打印机列表
* 作者: zhang-shu-wei
* 日期: 2022年8月16日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 搜索框搜索
*/
async search(e) {
var re = /^[0-9]+.?[0-9]*/
if (!re.test(e.value)) {
var data = {
app_id: 1000,
name: e.value,
is_online: -9,
status: -9,
offset: this.offSite * this.pageSize,
page_size: this.pageSize
}
} else {
var data = {
app_id: 1000,
print_no: e.value,
is_online: -9,
status: -9,
offset: this.offSite * this.pageSize,
page_size: this.pageSize
}
}
let res = await this.$api.setPrinterList(data)
let newData = JSON.parse(res.data)
if (res.code == 0) {
if (newData.totalCount != 0) {
this.list = newData.data
this.totalCount = newData.totalCount
this.activt = -1
} else {
this.list = []
this.totalCount = 0
this.activt = -1
}
} else {
this.$zsw.toast('未找到打印机', 2)
}
},
/**
* 条件筛选打印机列表
*/
async setRuler(val, i) {
this.activt = i
if (val.value == 0 && val.title == '全部') {
var data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: this.offSite * this.pageSize,
page_size: this.pageSize,
}
} else if (val.value == 1 && val.title == '正常') {
var data = {
app_id: 1000,
is_online: -9,
status: val.value,
offset: this.offSite * this.pageSize,
page_size: this.pageSize,
}
} else if (val.value == 2 && val.title == '缺纸') {
var data = {
app_id: 1000,
is_online: -9,
status: val.value,
offset: this.offSite * this.pageSize,
page_size: this.pageSize,
}
} else if (val.value == 1 && val.title == '在线') {
var data = {
app_id: 1000,
is_online: val.value,
status: -9,
offset: this.offSite * this.pageSize,
page_size: this.pageSize,
}
} else if (val.value == 0 && val.title == '离线') {
var data = {
app_id: 1000,
is_online: val.value,
status: -9,
offset: this.offSite * this.pageSize,
page_size: this.pageSize,
}
}
let resList = await this.$api.setPrinterList(data)
let newData = JSON.parse(resList.data)
if (resList.code == 0 && newData.data != null) {
this.list = newData.data
this.totalCount = newData.totalCount
newData.data.forEach(element => {
if (element.print_no == uni.getStorageSync('peinterList')) {
uni.setStorageSync('printerName', element.name)
}
});
return 'ok'
} else {
this.list = []
this.totalCount = 0
}
},
/**
* 打印测试内容
*/
playPrinterText(id, name) {
this.$refs.printerText.open('center')
this.printerId = id
this.printerName = name
},
/**
* 确定发送测试打印
*/
async play() {
if (this.text == '') return this.$zsw.toast('请输入打印内容')
let randomNum = Math.floor(Math.random() * 5000);
let data = {
app_id: 1000,
print_no: this.printerId,
order_no: randomNum,
content: `<center><b>测试打印</b></center><br><center>-----以下为测试打印内容-----</center><br><br><center><hb>${this.text}</hb></center>--------------------------------<br><br><br><br>`,
}
let newData = await this.$api.printerText(data)
console.log(newData)
if (newData.code == 0) {
this.$refs.printerText.close()
this.text = ''
this.$zsw.toast('发送测试打印成功', 1)
} else {
this.$refs.printerText.close()
this.text = ''
this.$zsw.toast('发送测试打印失败', 2)
}
},
/**
* 复制打印机编号
*/
copy(number) {
uni.setClipboardData({
data: number,
});
},
/**
* 删除打印机(暂时没有使用删除功能,打印机没有用了直接下线)
*/
async delPrinter(id) {
this.printerId = id
this.$refs.ruler.$refs.popup.open('center')
},
/**
* 修改打印机
*/
async modifyTap(id, name, key) {
this.$refs.modify.open('bottom')
this.printerId = id
this.printerName = name
this.deterKey = key
},
/**
* 确定修改打印机
*/
async determineModif() {
if (this.determineName.length < 3 || this.determineName.length > 15) return this.$zsw.toast('请在规定范围内修改打印机')
if (this.printerId == uni.getStorageSync('peinterList')) {
uni.setStorageSync('printerName', this.determineName)
}
let data = {
app_id: 1000,
print_no: this.printerId,
name: this.determineName,
sound: 1,
volume: 5
}
let res = await this.$api.determinePrinter(data)
if (res.code == 0) {
this.$refs.modify.close()
this.$zsw.toast('修改成功', 1)
let data = { title: '全部', value: 0 }
this.setRuler(data, 0)
this.determineName = ''
} else {
this.$zsw.toast('修改失败', 2)
}
},
/**
* 确定删除打印机 (弹框删除打印机 暂未使用)
*/
async determine(e) {
let data = {
app_id: 1000,
print_nos: this.printerId,
phone: e.phone,
code: e.code,
biz_id: this.bizId
}
let res = await this.$api.delPrinter(data)
console.log(res, '删除返回的数据');
if (res.code == 0) {
this.$refs.ruler.$refs.popup.close()
this.$zsw.toast('删除成功', 1)
} else {
this.$zsw.toast('删除失败', 2)
}
},
/**
* 添加打印机
*/
addPrinter() {
uni.navigateTo({ url: '/subPackages/home-sub/addPrinter/addPrinter' })
},
/**
* 打印机余额充值
*/
playMoney(money, printerNum) {
uni.navigateTo({ url: `/subPackages/personalCenter-sub/topUp/topUp?money=${money}&printerNum=${printerNum}` })
}
}

View File

@@ -0,0 +1,275 @@
page {
background-color: #f3f3f3;
height: 100%;
}
.search-root {
position: sticky;
top: 0;
z-index: 9999;
background-color: #fff;
.search-color {
background-color: $zsw-prinmary-color;
}
// 判断条件
.itme-root {
display: flex;
justify-content: space-around;
border-bottom: 1rpx solid $zsw-aux-color;
span {
display: inline-block;
width: 150rpx;
text-align: center;
padding: 15rpx 5rpx;
font-size: 34rpx;
letter-spacing: 5rpx;
}
.span-activt {
color: $zsw-prinmary-color;
border-bottom: 3rpx solid $zsw-prinmary-color;
}
}
}
.printer-item-root {
.item {
padding-bottom: 150rpx;
}
.printer {
box-sizing: border-box;
background-color: #fff;
padding: 25rpx 35rpx;
margin-top: 30rpx;
.money-root {
display: flex;
justify-content: space-between;
align-items: center;
.left-money {
display: flex;
align-items: center;
border-bottom: 1rpx solid $zsw-aux-color;
padding-bottom: 15rpx;
.warring {
color: red;
}
img {
width: 40rpx;
height: 40rpx;
margin-left: 7rpx;
}
}
.play-money {
padding: 8rpx 15rpx;
font-size: 24rpx;
border-radius: 7rpx;
color: #fff;
background-color: $zsw-light-color;
}
}
.printer-msg-root {
display: flex;
img {
width: 200rpx;
height: 200rpx;
margin-right: 25rpx;
}
.num {
.name {
font-size: 36rpx;
color: #000;
}
font-size: 26rpx;
margin: 15rpx 0;
color: #9e9e9e;
p>span {
color: #000;
}
p {
line-height: 55rpx;
}
}
}
.operation-root {
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1rpx solid $zsw-aux-color;
padding-top: 25rpx;
.modify,
.playPrinterText {
padding: 8rpx 15rpx;
font-size: 24rpx;
border-radius: 7rpx;
color: #fff;
}
.playPrinterText {
background-color: $zsw-prinmary-color;
margin-right: 15rpx;
}
.modify {
background-color: $zsw-light-color;
}
.status {
.onLine {
padding: 8rpx 15rpx;
font-size: 20rpx;
background-color: $zsw-prinmary-color;
color: #fff;
border-radius: 7rpx;
margin-left: 15rpx;
}
.noLine {
padding: 8rpx 15rpx;
font-size: 20rpx;
background-color: $zsw-error-color;
color: #fff;
border-radius: 7rpx;
margin-left: 15rpx;
}
}
}
}
}
.modif-root {
box-sizing: border-box;
padding: 35rpx;
border-radius: 25rpx 25rpx 0 0;
background-color: #fff;
.prompt {
padding: 0 0 25rpx 0;
color: $zsw-error-color;
font-size: 28rpx;
}
p {
span {
color: $zsw-error-color;
}
}
.ipt {
box-sizing: border-box;
display: flex;
padding: 40rpx 0 10rpx 0;
border-bottom: 1rpx solid $zsw-aux-color;
}
.btn-root {
box-sizing: border-box;
display: flex;
margin-top: 35rpx;
.cancel {
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
background-color: #fff;
}
.determine {
background-color: $zsw-prinmary-color;
color: #fff;
}
button {
padding: 0rpx 110rpx;
}
}
}
.printerText {
box-sizing: border-box;
background-color: #fff;
margin: 0 50rpx;
padding: 25rpx;
border-radius: 10rpx;
.error {
font-size: 28rpx;
color: $zsw-error-color;
}
p {
padding: 30rpx 0 10rpx 0;
border-bottom: 1rpx solid $zsw-aux-color;
}
textarea {
margin-top: 10rpx;
border-bottom: 1rpx solid $zsw-aux-color;
max-height: 150rpx;
}
.btn {
display: flex;
justify-content: space-around;
margin-top: 20rpx;
span:nth-child(1) {
background-color: $zsw-error-color;
}
span {
display: inline-block;
background-color: $zsw-prinmary-color;
padding: 15rpx 80rpx;
border-radius: 10rpx;
color: #fff;
}
}
}
// 添加打印机按钮
.btn-root-one {
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: #fff;
padding: 18rpx 0;
.add-btn-printer {
box-sizing: border-box;
background-color: $zsw-prinmary-color;
color: #fff;
text-align: center;
padding: 20rpx 0;
margin: 0 30rpx;
border-radius: 10rpx;
}
}

View File

@@ -0,0 +1,205 @@
<template>
<view class="root">
<!-- 搜索 和条件判断 -->
<view class="search-root">
<view class="search-color">
<uni-search-bar
placeholder="输入打印机编号或备注"
@cancel="search"
cancel-text="搜索"
textColor="#fff"
></uni-search-bar>
</view>
<view class="itme-root">
<span
@tap="setRuler(item, i)"
:class="{ 'span-activt': i == activt }"
class="item"
v-for="(item, i) in rulerList"
:key="i"
>{{ item.title }}</span
>
</view>
</view>
<view class="printer-item-root">
<view class="item" v-if="totalCount != 0">
<view class="printer" v-for="item in list" :key="item.id">
<view class="money-root">
<view class="left-money">
<view
>余额
<span v-if="item.print_bill > 500" class="no-sufficient">{{
item.print_bill
}}</span>
<span v-else class="warring">{{ item.print_bill }}</span>
</view>
<img
src="http://image.jxc4.com/image/9287b611859af0de50318e1b7f2d8a15.tem.png"
alt=""
/>
</view>
<span
class="play-money"
@tap="playMoney(item.print_bill, item.print_no)"
>
充值
</span>
</view>
<view class="printer-msg-root">
<img
src="http://image.jxc4.com/image/f1722576b90591cb9fe2aed2f2fb7af5.tem.jpg"
alt=""
/>
<view class="num">
<p class="name">{{ item.name }}</p>
<p style="display: flex">
打印机编号<span>{{ item.print_no }}</span>
<i class="iconfont icon-fuzhi" @tap="copy(item.print_no)"></i>
</p>
<p>
KEY<span>{{ item.print_key }}</span>
</p>
</view>
</view>
<view class="operation-root">
<viwe class="status">
状态:
<span v-if="item.is_online == 1" class="onLine"
>在线 正常工作中</span
>
<span v-else class="noLine">离线 当前打印机离线中</span>
</viwe>
<view>
<span
class="playPrinterText"
@tap="playPrinterText(item.print_no, item.name)"
v-show="item.is_online == 1"
>打印测试</span
>
<span
class="modify"
@tap="modifyTap(item.print_no, item.name, item.print_key)"
>修改</span
>
</view>
<!-- <span class="del" @tap="delPrinter(item.print_no)">删除(没有用删除功能打印机不用了直接显示下线)</span> -->
</view>
</view>
</view>
<zswEmpty v-else title="未找到打印机"></zswEmpty>
</view>
<view class="btn-root-one">
<view class="add-btn-printer" @tap="addPrinter">添加打印机</view>
</view>
<!-- 删除打印机(暂时没有使用) -->
<zsw-ruler-printer
ref="ruler"
@determine="determine"
:sendCOde="removeCodeText"
title="删除打印机"
phoneText="原手机号"
promptText="为了您的账户安全,删除打印机需要验证绑定账号,如无法验证请联系运营!"
>
</zsw-ruler-printer>
<uni-popup ref="modify">
<view class="modif-root">
<p class="prompt">
注意修改打印机无需验证当定手机号可进行多次修改打印机备注字数限制2
- 15 个字符
</p>
<p>
你正在修改<span>{{ printerName }} </span> -- 的打印机
</p>
<view class="ipt">
<span><em>打印机编号</em></span
><input type="text" disabled :placeholder="printerId" />
</view>
<view class="ipt">
<span><em>打印机KEY</em></span
><input type="text" disabled :placeholder="deterKey" />
</view>
<view class="ipt">
<span><em>打印机备注</em></span
><input
type="text"
cursor-spacing="40"
v-model="determineName"
placeholder="修改打印机备注"
/>
</view>
<view class="btn-root">
<button @tap="$refs.modify.close()" class="cancel mini-btn">
取消
</button>
<button @tap="determineModif" class="determine mini-btn">确定</button>
</view>
</view>
</uni-popup>
<uni-popup :mask-click="false" ref="printerText">
<view class="printerText">
<span class="error"
>注意禁止使用小票打印机打印机违法内容否则后果自负</span
>
<p>备注{{ printerName }}</p>
<p>编号{{ printerId }}</p>
<textarea
v-model="text"
cursor-spacing="120"
maxlength="300"
placeholder="京西云打印机测试"
/>
<view class="btn">
<span @tap="$refs.printerText.close()">取消</span>
<span @tap="play">打印</span>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { allMethods } from './methods.js'
import { allData } from './data.js'
import zswEmpty from '@/components/zsw-empty/zsw-empty.vue'
export default {
components: {
zswEmpty,
},
data() {
return {
...allData.data(),
}
},
mounted() {
let data = { title: '全部', value: 0 }
this.setRuler(data, 0)
},
async onPullDownRefresh() {
let data = { title: '全部', value: 0 }
this.setRuler(data, 0)
setTimeout(() => {
uni.stopPullDownRefresh()
}, 2000)
},
methods: {
...allMethods,
},
}
</script>
<style lang="scss">
@import './printerList.scss';
</style>

View File

@@ -0,0 +1,69 @@
/**
* 切换打印机
* 作者zhang-shu-wei
* 日期2022年8月25日
* 邮箱2966211270@qq.com
*/
export const allMethods = {
/**
* 获取打印机列表
*/
async getPrinterList() {
let data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: 0,
page_size: 100
}
let res = await this.$api.setPrinterList(data)
if (res.code == 0) {
if (res.data == 'null') return this.$zsw.toast('暂无打印机')
let newData = JSON.parse(res.data)
this.totalCount = newData.totalCount
this.PrinterList = newData.data
} else {
this.$zsw.toast('获取打印设备失败,请重试')
}
},
/**
* 切换打印机
*/
switchprinterCheck(e) {
let newData = JSON.parse(e.detail.value)
console.log(newData)
this.switchList = newData
},
/**
* 点击切换打印机
*/
switchPrinter() {
if (!this.switchList.print_no) {
return this.topMsg('请选择设备', 'error')
}
if (this.totalCount > 0) {
this.topMsg('切换成功', 'success')
uni.setStorageSync('printerName', this.switchList.name)
uni.setStorageSync('peinterList', this.switchList.print_no)
setTimeout(() => {
uni.switchTab({ url: '/pages/home/home' })
}, 1200);
} else {
uni.switchTab({ url: '/pages/home/home' })
}
},
/**
* 错误提示信息
*/
topMsg(text, type = 'error') {
this.msgType = type
this.messageText = text
this.$refs.message.open()
},
}

View File

@@ -0,0 +1,106 @@
page{
background-color: $zsw-aux-color;
height: 100%;
width: 100%;
}
.root{
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.title{
padding: 15rpx 0;
background-color: $zsw-prinmary-color;
color: #fff;
text-align: center;
font-weight: bold;
font-size: 35rpx;
}
.swich-list-root{
flex: 1;
overflow: auto;
.item{
box-sizing: border-box;
display: flex;
margin: 25rpx;
border-radius: 15rpx;
background-color: #fff;
padding: 15rpx 20rpx;
img{
width: 170rpx;
height: 170rpx;
margin-right: 25rpx;
}
.switch-right{
display: flex;
width: 100%;
justify-content: space-between;
.center{
width: 85%;
.name{
position: relative;
width: 100%;
display: flex;
justify-content: space-between;
.p1{
font-size: 38rpx;
}
}
.key{
width: 100%;
font-size: 26rpx;
color: rgb(163, 163, 163);
p{
line-height: 50rpx;
}
}
}
.switch{
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
font-size: 34rpx;
.p2{
color: $zsw-prinmary-color;
}
.p3{
color: rgb(255, 0, 0);
}
}
}
}
}
// 添加打印机按钮
.btn-root{
background-color: #fff;
padding: 18rpx 0;
.add-btn-printer{
box-sizing: border-box;
background-color: $zsw-prinmary-color;
color: #fff;
text-align: center;
padding: 20rpx 0;margin: 0 30rpx;
border-radius: 10rpx;
}
}

View File

@@ -0,0 +1,83 @@
<template>
<view class="root">
<p class="title">切换设备</p>
<view class="swich-list-root">
<radio-group @change="switchprinterCheck">
<label v-for="item in PrinterList" :key="item.id">
<view class="item">
<img
src="http://image.jxc4.com/image/f669d9ea6914546c0355ec6fe904f585.tem.png"
alt=""
/>
<view class="switch-right">
<view class="center">
<view class="name">
<p class="p1">{{ item.name }}</p>
</view>
<view class="key">
<p>编号{{ item.print_no }}</p>
<p>KEY{{ item.print_key }}</p>
</view>
</view>
<view class="switch">
<p v-if="item.is_online == 1" class="p2">在线</p>
<p v-else class="p3">离线</p>
<radio
color="#0a99ff"
:value="JSON.stringify(item)"
:checked="item.print_no == printerNum"
/>
</view>
</view>
</view>
</label>
</radio-group>
</view>
<view class="btn-root">
<view class="add-btn-printer" @tap="switchPrinter">切换设备</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message
style="text-align: center"
:type="msgType"
:message="messageText"
:duration="2000"
></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import { allMethods } from './methods.js'
export default {
data() {
return {
PrinterList: [], // 切换打印机的列表
printerNum: uni.getStorageSync('peinterList'), // 获取打印机编号
msgType: null, // 提示信息
messageText: null, // 提示文本
switchList: {
print_no: '',
name: '',
}, // 修改打印机数据
totalCount: 0, // 打印机台数
}
},
created() {
this.switchList.print_no = uni.getStorageSync('peinterList')
this.switchList.name = uni.getStorageSync('printerName')
this.getPrinterList()
},
methods: {
...allMethods,
},
}
</script>
<style lang="scss">
@import './swichPrinter.scss';
</style>

View File

@@ -0,0 +1,264 @@
<template>
<view>
<!-- 选择已有打印机 -->
<view class="printer-select">
<uni-data-select
v-model="selectField"
:localdata="selectList"
:clear="false"
@change="changeSelect"
></uni-data-select>
</view>
<!-- 打印机编号 -->
<view class="input-item" :class="{ error: rulerPrinter }">
<i
class="iconfont icon-he_16zhengjianbianhaoguanli"
:class="{ 'error-text': rulerPrinter }"
></i>
<input
type="text"
v-model="printerNum"
placeholder="打印机编号 (查看打印机底部标签)"
/>
<i class="iconfont icon-ziyuan" @tap="qrCode"></i>
</view>
<!-- 打印内容 -->
<view class="center-root">
<view class="all-test-printer">
<span @tap="text = allText">完整测试内容</span>
</view>
<view class="text-printer">
<textarea
v-model="text"
cursor-spacing="120"
maxlength="400"
placeholder="京西云打印机测试"
/>
</view>
</view>
<span class="error"
>注意禁止使用小票打印机打印机违法内容否则后果自负</span
>
<view class="ok-btn">
<view class="btn1" @tap="clearPlay">清空</view>
<view class="btn2" @tap="play">确定打印</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
printerNum: "", // 打印机编号
selectField: "打印机编号", // 已有打印机编号
selectList: [], // 打印机
text: "", // 发送打印内容
allText: `<left>小号:京西云打印机</left>
<hb>中号高:京西云打印机</hb>
<wb>中号宽:京西云打印机</wb>
<b>大号:京西云打印机</b>
<left>左对齐:京西云打印机</left>
<center>居中:京西云打印机</center>
<right>右对齐:京西云打印机</right>
<center>--------------------------------</center>
--><br>
<left>换一行:京西云打印机</left>
--><br>
--><br>
<left>换两行:京西云打印机</left>
--><br>
--><br>
--><br>
<left>换三行行:京西云打印机</left>
<center>--------------------------------</center>
<br><br><br>`,
};
},
created() {
this.setRuler();
},
methods: {
/**
* 扫描二维码
*/
qrCode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ["barCode", "qrCode"],
barCodeInput: false,
success: (res) => {
this.printerNum = res.result;
},
});
},
async setRuler() {
let data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: 0,
page_size: 100,
};
let resList = await this.$api.setPrinterList(data);
let newData = JSON.parse(resList.data);
if (resList.code == 0 && newData.totalCount) {
let newArr = [];
let newObj = {};
newData.data.forEach((element) => {
newObj = {
value: element.print_no,
text: element.name,
};
newArr.push(newObj);
});
this.selectList = newArr;
}
},
changeSelect(e) {
this.printerNum = e;
},
/**
* 确定发送测试打印
*/
async play() {
if (this.printerNum == "") return this.$zsw.toast("请输入打印编号");
if (this.text == "") return this.$zsw.toast("请输入打印内容");
let randomNum = Math.floor(Math.random() * 5000);
let data = {
app_id: 1000,
print_no: this.printerNum,
order_no: randomNum,
content: `<center><b>测试打印</b></center><br><center>-----以下为测试打印内容-----</center><br><br><center>${this.text}</center>`,
};
let newData = await this.$api.printerText(data);
console.log(newData);
if (newData.code == 0) {
this.text = "";
this.$zsw.toast("发送测试打印成功", 1);
} else {
this.text = "";
this.$zsw.toast("发送测试打印失败", 2);
}
},
clearPlay() {
this.text = "";
this.printerNum = "";
},
},
};
</script>
<style lang="scss">
page {
background-color: $zsw-aux-color;
}
.printer-select {
padding: 25rpx;
background-color: #fff;
z-index: 9999;
}
.center-root {
background-color: #fff;
margin-top: 20rpx;
}
.text-printer {
box-sizing: border-box;
padding: 20rpx;
background-color: #fff;
textarea {
width: 100%;
height: 500rpx;
}
}
.all-test-printer {
box-sizing: border-box;
padding: 20rpx;
span {
margin-top: 20rpx;
background-color: $zsw-prinmary-color;
padding: 10rpx 15rpx;
color: #fff;
border-radius: 8rpx;
}
}
.error {
display: inline-block;
padding: 0 20rpx;
margin-top: 20rpx;
color: #ec0101;
}
.input-item {
background-color: #fff;
margin-top: 20rpx;
box-sizing: border-box;
display: flex;
align-items: center;
padding: 30rpx;
i {
margin-right: 18rpx;
color: #808080;
}
.icon-ziyuan {
display: inline-block;
box-sizing: border-box;
font-size: 40rpx;
padding: 5rpx 30rpx;
color: $zsw-prinmary-color;
}
input {
z-index: 0;
width: 100%;
}
}
.ok-btn {
display: flex;
position: fixed;
bottom: 0;
width: 100%;
box-sizing: border-box;
background-color: #fff;
padding: 20rpx;
justify-content: space-around;
.btn1 {
border: 1rpx solid $zsw-prinmary-color;
padding: 20rpx 0;
text-align: center;
border-radius: 10rpx;
color: $zsw-prinmary-color;
width: 100%;
margin-right: 10rpx;
}
.btn2 {
background-color: $zsw-prinmary-color;
padding: 20rpx 0;
text-align: center;
border-radius: 10rpx;
color: #fff;
width: 100%;
margin-left: 10rpx;
}
}
</style>

View File

@@ -0,0 +1,33 @@
/**
* 系统公告
* 作者zhang-shu-wei
* 日期2022年8月26日
* 邮箱2966211270@qq.com
*/
import forMaterTimer from "@/utils/forMaterTimer.js";
export const allMethods = {
/**
* 获取公告
*/
async getNotice() {
let NoticePayload = {
notice_type: this.type,
page_number: this.pageNumber,
page_size: this.pageSize
}
let noticeData = await this.$api.img_notice_help(NoticePayload)
if (noticeData.code == 0) {
console.log(JSON.parse(noticeData.data), '系统公告')
this.noticeDataList = [...this.noticeDataList, ...JSON.parse(noticeData.data).result]
this.count = JSON.parse(noticeData.data).count
} else {
this.$zsw.toast('系统公告异常', 2)
}
},
rorMater(timer) {
return forMaterTimer(timer)
}
}

View File

@@ -0,0 +1,58 @@
page {
background-color: $zsw-aux-color;
}
.title {
background-color: $zsw-prinmary-color;
color: #fff;
font-size: 35rpx;
font-weight: bold;
padding: 15rpx;
text-align: center;
}
.center-root {
.item {
box-sizing: border-box;
margin: 25rpx 15rpx;
border-radius: 15rpx;
padding: 20rpx;
background-color: #fff;
.cneter-title {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
p:nth-child(1) {
font-weight: bold;
width: 100%;
padding-right: 50rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
p:nth-child(2) {
white-space: nowrap;
color: rgb(100, 100, 100);
}
}
.center-text {
display: flex;
justify-content: space-between;
image {
width: 150rpx;
height: 150rpx;
}
p {
width: 100%;
height: 100%;
padding-left: 25rpx;
}
}
}
}

View File

@@ -0,0 +1,67 @@
<template>
<view>
<p class="title">系统公告</p>
<view class="center-root">
<view class="item" v-for="item in noticeDataList" :key="item.id">
<view class="cneter-title">
<p>系统公告</p>
<p>{{ rorMater(item.created_at) }}</p>
</view>
<view class="center-text">
<image :src="item.link" mode="aspectFill" />
<p>{{ item.msg }}</p>
</view>
</view>
</view>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
export default {
data() {
return {
noticeData: [],
type: 2, // 类型公告
pageSize: 15, // 每页15条
pageNumber: 1, // 页码
count: 0, // 总条数
noticeDataList: [], // 公告数据
};
},
onShow() {
this.getNotice();
},
onPullDownRefresh() {
setTimeout(() => {
this.pageNumber = 1;
this.noticeDataList = [];
this.getNotice();
uni.stopPullDownRefresh();
}, 1200);
},
onReachBottom(e) {
let sum = this.pageNumber * this.pageSize;
let size = this.count;
if (sum >= size) {
return this.$zsw.toast("~到底了~");
}
this.pageNumber += 1;
// 重新获取数据
this.getNotice();
},
methods: {
...allMethods,
},
};
</script>
<style lang='scss'>
@import "./updateV.scss";
</style>

View File

@@ -0,0 +1,30 @@
/**
* wifi 配网集成
* 作者zhangshuwei
* 日期2022年9月27日
* 邮箱2966211270@qq.com
* 源码作者:半颗心
*/
export const allData = {
data() {
return {
ssid: '',
password: '',
is5G: true,
isWaring: false,
hal_version: 211209,
ui: {
indicatorDots: true,
vertical: false,
autoplay: false,
interval: 2000,
duration: 500
},
version: '',
bssid: '',
type: 0
}
}
}

View File

@@ -0,0 +1,111 @@
/**
* wifi 配网集成
* 作者zhangshuwei
* 日期2022年9月27日
* 邮箱2966211270@qq.com
* 源码作者:半颗心
*/
const airkiss = requirePlugin('airkiss');
export const allMethods = {
getWifiInfo() {
let that = this;
uni.getConnectedWifi({
success(res) {
if ('getConnectedWifi:ok' === res.errMsg) {
that.setData({
ssid: res.wifi.SSID,
bssid: res.wifi.BSSID,
is5G: res.wifi.frequency > 4900
});
} else {
that.$zsw.toast('请连接路由器')
}
},
fail(res) {
that.$zsw.toast('请连接路由器')
}
});
},
onInputSSID(evt) {
const { value } = evt.detail;
this.setData({
ssid: value
});
},
onInputPassword(evt) {
const { value } = evt.detail;
this.setData({
password: value,
isWaring: false
});
},
onConfirm() {
if (this.ssid == '') {
this.$zsw.toast('请连接路由器')
return;
}
if (this.password.length < 8) {
this.$zsw.toast('请输出不少于8位的密码')
return;
}
if (this.is5G) {
this.$zsw.toast('请链接至2.4G频段的路由器')
return;
}
uni.showLoading({
title: '配网中'
}); //这里最好加微信小程序判断账号密码是否为空以及其长度和是否为5G频段
airkiss.startAirkiss(this.ssid, this.password, function (res) {
uni.hideLoading();
switch (res.code) {
case 0:
uni.showModal({
title: '初始化失败',
content: res.result,
showCancel: false,
confirmText: '收到'
});
break;
case 1:
uni.showModal({
title: '配网成功',
content: '设备IP' + res.ip + '\r\n 设备Mac' + res.bssid,
showCancel: false,
confirmText: '好的',
success: function (res) {
if (res.confirm) {
uni.navigateBack()
}
}
});
break;
case 2:
uni.showModal({
title: '配网失败',
content: '请检查密码是否正确',
showCancel: false,
confirmText: '收到'
});
break;
default:
break;
}
});
}
}

View File

@@ -0,0 +1,109 @@
page{
width: 100%;
height: 100vh;
background-color: rgb(240, 239, 239);
}
// 打印机图标
.title-root{
display: flex;
flex-direction: column;
align-items: center;
p{
font-size: 28rpx;
margin-top: 10rpx;
color: #8a8a8a;
}
.icon-zaixian{
background-color: #fff;
font-size: 150rpx;
border-radius: 50%;
padding: 30rpx;
color: $zsw-prinmary-color;
border: 8rpx solid $zsw-prinmary-color;
margin-top: 60rpx;
margin-bottom: 60rpx;
}
}
// 路由器信息
.center-root{
box-sizing: border-box;
background-color: #fff;
padding: 0 40rpx;
margin-top: 60rpx;
.item-1, .item-2{
display: flex;
padding: 20rpx 0;
input{
width: 100%;
}
text{
margin-right: 30rpx;
width: 80rpx;
white-space: nowrap;
}
}
.item-2>.ipt-2{
display: flex;
width: 100%;
align-items: center;
.icon-chahao{
background-color: #979797;
color: #fff;
border-radius: 50%;
padding: 7rpx;
font-size: 36rpx;
}
}
}
// 确定按钮
.ok-btn{
padding: 0 20rpx;
margin-top: 50rpx;
.weui-btn{
background-color: $zsw-prinmary-color;
text-align: center;
padding: 25rpx 0;
border-radius: 15rpx;
color: #fff;
}
button{
margin-top: 25rpx;
color: $zsw-prinmary-color;
border: 1rpx solid $zsw-prinmary-color;
background-color: rgba(0,0,0,0);
}
}
// 版权信息
.Copyright-root{
position: fixed;
bottom: 100rpx;
left: 0;
display: flex;
justify-content: center;
align-items: center;
color: #57b93c;
width: 100%;
img{
height: 60rpx;
width: 212rpx;
margin-left: 20rpx;
}
}

View File

@@ -0,0 +1,113 @@
<template>
<view>
<!-- 图标 -->
<view class="title-root" style="padding: 0">
<view>
<i class="iconfont icon-zaixian"></i>
</view>
<p>1先打开手机定位          .</p>
<p>2在连接到家庭路由器2.4G频段网络  .</p>
<p>3在打印机关闭状态下按住走纸键不松开</p>
<p>4然后打开电源两秒内松开进入配网模式</p>
<p>5最后输入家庭路由器密码点击连接 .</p>
</view>
<!-- 输入框 -->
<view class="center-root">
<view class="item-1">
<text>名称</text>
<input
class="weui-input"
placeholder="请先连接到2.4Gwifi"
:value="ssid"
@input="onInputSSID"
/>
</view>
<view class="item-2">
<text>密码</text>
<view class="ipt-2">
<input
class="weui-input"
type="text"
placeholder="请输入路由器密码"
placeholder-class="weui-input__placeholder"
:value="password"
@input="onInputPassword"
/>
</view>
</view>
</view>
<!-- 确定按钮 -->
<view class="ok-btn">
<a class="weui-btn weui-btn_primary" @tap.native="onConfirm">确定</a>
<button v-if="type == 0" open-type="launchApp" app-parameter="wechat">
返回App
</button>
</view>
<view class="Copyright-root">
<view>Copyright</view>
<img
src="http://www.jingxicaishi.com/inc/images/footer_logo.png"
alt=""
/>
</view>
</view>
</template>
<script>
import { allData } from "./data";
import { allMethods } from "./methods";
const airkiss = requirePlugin("airkiss");
export default {
data() {
return {
...allData.data(),
};
},
onShareAppMessage(res) {
return {
title: "京西云WIFI配网",
path: "/subPackages/home-sub/wifi/wifi",
};
},
onShow() {
uni.dialog.alert("温馨提示", `如果使用小程序 wifi 配网无法成功!说明手机系统不支持。请关注微信公众号 “京西菜式”,依次点击 “商家中心” —> “wifi配网”进行配置`, () => {}, "我明白了")
this.getWifiInfo();
},
onLoad(options) {
this.type = options.type;
this.setData({
version: airkiss.version,
});
let that = this;
uni.startWifi({
success(res) {
that.getWifiInfo();
},
fail: function (res) {
uni.showToast({
title: "请连接路由器!",
duration: 2000,
icon: "none",
});
},
});
this.getWifiInfo();
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./wifi.scss";
</style>

View File

@@ -0,0 +1,28 @@
/**
* 手机登录data数据
* 作者: zhangshuwei
* 日期: 2022年8月11日
* 邮箱: 2966211270@qq.com
*/
export const allData = {
data() {
return {
toggleMsg: '发送验证码', // 验证码文字
isAccountLog: false, // 默认显示验证码登录
phone: '', // 获取验证码登录手机号
accountNum: '', // 获取账号
gettingMsg: false, // 是否显示提示秒数
counting: 60, // 提示秒数
sendingyzm: false, // 节流防抖控制
code: '', // 验证码
rulerPhone: false, // 验证手机号
rulerCode: false, // 验证验证码
msgType: null, // 提示文字
messageText: null, // 顶部错误提示文字
bizId: null, // 验证码id
isChecked: false, // checkBox值
isAgreementIf: false
}
}
}

View File

@@ -0,0 +1,197 @@
.container {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
height: 100vh;
.img-root>img {
width: 750rpx;
height: 573rpx;
}
.register {
margin-top: 50rpx;
width: 90%;
height: 88rpx;
line-height: 88rpx;
background-color: $zsw-prinmary-color;
border-radius: 10rpx;
color: #fff;
text-align: center;
}
.weixin-login {
display: flex;
justify-content: center;
margin-top: 30rpx;
width: 90%;
height: 88rpx;
line-height: 88rpx;
background-color: #fff;
border: 1rpx solid $zsw-prinmary-color;
border-radius: 10rpx;
color: $zsw-prinmary-color;
text-align: center;
i {
margin-right: 10rpx;
}
}
.login-form {
margin-top: -20rpx;
background-color: #fff;
border: 1rpx solid rgb(230, 230, 230);
padding: 40rpx 40rpx 50rpx 40rpx;
border-radius: 20rpx;
.login_input {
width: 100%;
}
input {
padding: 10px 0;
}
.phone-wrap {
box-sizing: border-box;
display: flex;
align-items: center;
border-bottom: 1rpx solid rgb(230, 230, 230);
i {
margin-right: 20rpx;
}
span {
white-space: nowrap;
padding: 8rpx 15rpx;
background-color: $zsw-prinmary-color;
color: #fff;
border-radius: 10rpx;
font-size: 30rpx;
}
}
.phone-wrap:nth-child(2) {
margin-top: 20rpx;
}
}
.paperWrap {
position: fixed;
bottom: 40rpx;
text-align: center;
span {
color: rgb(3, 74, 226);
}
}
}
.error {
border-bottom: 1rpx solid rgb(228, 10, 10) !important;
}
.error-color {
color: rgb(228, 10, 10) !important;
}
.copyright-root {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
text-align: center;
font-size: 26rpx;
.text {
color: #0a99ff;
}
.center {
display: flex;
justify-content: center;
align-items: center;
position: relative;
.lab {
position: absolute;
padding: 7rpx 10rpx;
background-color: #656a70;
color: #fff;
left: 0rpx;
top: 60rpx;
border-radius: 10rpx;
opacity: 0;
transition: all 0.2s;
}
.lab::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-left: 11rpx solid transparent;
border-right: 11rpx solid transparent;
border-bottom: 12rpx solid #656a70;
left: 12rpx;
top: -11rpx;
}
.lab-active {
opacity: 1 !important;
}
// .lab{
// border:1rpx solid red
// }
}
.center-active {
animation: identifier 0.2s;
}
}
@keyframes identifier {
0% {
transform: translateX(20rpx);
}
20% {
transform: translateX(0rpx);
}
40% {
transform: translateX(20rpx);
}
60% {
transform: translateX(0rpx);
}
40% {
transform: translateX(20rpx);
}
100% {
transform: translateX(0rpx);
}
}
.codeLogin{
display: flex;
justify-content: center;
margin-top: 30rpx;
width: 90%;
height: 88rpx;
line-height: 88rpx;
background-color: #fff;
border: 1rpx solid #0a99ff;
border-radius: 10rpx;
color: #0a99ff;
text-align: center;
}

View File

@@ -0,0 +1,80 @@
<template>
<view class="container">
<view class="img-root">
<img src="http://image.jxc4.com/image/4eee187646320c126f2152228eeedc7a.tem.png" alt="">
</view>
<view class="login-form">
<view class="phone-wrap" :class="{'error': rulerPhone}">
<i class="iconfont icon-shoujihaoma" :class="{'error-color': rulerPhone}"></i>
<input class="login_input" placeholder-class="phcolor" type="text" maxlength="11" placeholder="请输入手机号" v-model="phone" />
</view>
<view class="phone-wrap" :class="{'error': rulerCode}">
<i class="iconfont icon-yanzhengyanzhengma" :class="{'error-color': rulerCode}"></i>
<input class="auth_input" placeholder-class="phcolor" maxlength="11" placeholder="请输入验证码" v-model="code" />
<span @tap="getMsg" class="yzm-wrap" v-show="!isAccountLog">{{ gettingMsg ? counting + '秒后重新发送' : toggleMsg }}</span>
</view>
</view>
<view @tap="register" class="register">登录</view>
<!-- #ifdef MP-WEIXIN -->
<button class="codeLogin" v-show="!isChecked" @tap="codeLogin"><i class="iconfont icon-weixin" style="margin-right:5px"></i>一键登录</button>
<button open-type="getPhoneNumber" v-show="isChecked" @getphonenumber="wxLogin" class="weixin-login"><i class="iconfont icon-weixin"></i>一键登录</button>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<button class="weixin-login" @tap="wxChat"><i class="iconfont icon-weixin"></i>微信登录</button>
<!-- #endif -->
<view class="paperWrap">
<view class="copyright-root">
<view
class="center"
:class="{ 'center-active': isAgreementIf }"
>
<label>
<checkbox-group @change="agreement">
<checkbox
:checked="isChecked"
value="cb"
color="#2dd091"
style="transform: scale(0.7); border-radius: 50%"
/>我已阅读并同意
</checkbox-group>
</label>
<text class="text" @tap="toRules('用户协议')">用户协议</text>
<text class="text" @tap="toRules('隐私协议')">隐私协议</text>
<view
class="lab"
:class="{ 'center-active lab-active': isAgreementIf }"
>请勾选同意后再进行登录</view>
</view>
</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message style="text-align: center;" :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import { allData } from './data.js'
import { allMethods } from './methods.js'
export default {
data() {
return {
...allData.data()
}
},
methods: {
...allMethods
}
}
</script>
<style lang="scss" scoped>
@import "./loginPhone.scss"
</style>

View File

@@ -0,0 +1,223 @@
/**
* 手机登录方法
* 作者: zhangshuwei
* 日期: 2022年8月11日
* 邮箱: 2966211270@qq.com
*/
export const allMethods = {
/**
* 获取验证码
*/
async getMsg() {
// 不严格验证手机号
let rulerPhone = /^1\d{10}$/
if (rulerPhone.test(this.phone)) {
this.rulerPhone = false
// 防抖节流控制
if (this.sendingyzm == true) return
// 获取手机验证码
let res = await this.$api.getPhoneCode(this.phone)
if (res.code == 0) {
this.topMsg('success', '验证码发送成功')
this.bizId = JSON.parse(res.data).bizId
var timer = null
this.sendingyzm = true // 成功发送验证码开启节流
clearInterval(timer) // 清除定时器
this.gettingMsg = true // 显示秒数
var timer = setInterval(() => {
this.gettingMsg = true // 显示秒数
this.counting-- // 减掉秒数
if (this.counting === 0) {
this.sendingyzm = false // 关闭节流可以重新发送验证码
clearInterval(timer) // 清掉定时器
this.gettingMsg = false // 显示文字
this.counting = 60 // 还原秒数
}
}, 1000)
} else {
this.topMsg('error', '发送验证码失败')
}
} else {
this.topMsg('error', '请输入正确的手机号码')
this.rulerPhone = true
}
},
/**
* 阅读协议
*/
agreement(e) {
if (!e.detail.value[0]) {
this.isChecked = false
} else {
this.isChecked = true
this.isAgreementIf = false
}
},
/**
* 一键登录
*/
codeLogin() {
if (!this.isChecked) {
this.isAgreementIf = true
}
},
/**
* 验证手机号码
*/
async register() {
if (!this.isChecked) {
this.isAgreementIf = true
return
}
let rulerPhone = /^1\d{10}$/
if (!rulerPhone.test(this.phone)) {
this.rulerPhone = true
this.topMsg('error', '手机号码输入错误')
return
}
this.rulerPhone = false
let rulerCode = /^\d{6}$/
if (!rulerCode.test(this.code)) {
this.rulerCode = true
this.topMsg('error', '验证码输入错误')
return
}
this.rulerCode = false
let data = {
phone: this.phone,
biz_id: this.bizId,
code: this.code
}
let res = await this.$api.phoneLogin(data)
if (res.code == 0) {
this.topMsg('success', '登录成功')
this.rulerCode = false
let data = JSON.parse(res.data)
uni.setStorageSync('token', data.token)
uni.setStorageSync('userInfor', JSON.stringify(data.user))
uni.setStorageSync('userPhone', this.phone)
uni.setStorageSync('userId', data.user.user_id)
this.$store.commit('setToken', data.token)
this.$store.commit('setMyUserDat', data.user)
this.$store.commit('setUserPhone', this.phone)
this.$store.commit('setUserId', data.user.user_id)
setTimeout(() => {
this.getPtinterList()
}, 1200);
} else {
this.$zsw.toast('验证码错误', 2)
this.rulerCode = true
this.topMsg('error', '登录登录失败,验证码错误')
}
},
/**
* 获取打印机列表
*/
async getPtinterList() {
let data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: 0,
page_size: 100
}
let res = await this.$api.setPrinterList(data)
if (res.code == 0) {
let newData = JSON.parse(res.data)
if (newData.totalCount == 0) {
uni.switchTab({ url: '/pages/home/home' })
} else {
uni.reLaunch({ url: '/subPackages/home-sub/swichPrinter/swichPrinter' })
}
} else {
this.$zsw.toast('获取打印设备失败,请重试')
}
},
/**
* 错误提示信息
*/
topMsg(type, text) {
this.msgType = type
this.messageText = text
this.$refs.message.open()
},
/**
* 使用微信登录
*/
// #ifdef MP-WEIXIN
async wxLogin(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
let getPhone = await this.$api.login(e.detail.code)
if (getPhone.code == 0) {
// 保存用户的手机号码
let newData = JSON.parse(getPhone.data)
uni.setStorageSync('userPhone', newData.phone)
this.$store.commit('setUserPhone', newData.phone)
uni.navigateTo({ url: '/subPackages/login/userInfor/userInfor' })
} else {
this.$zsw.toast('登录失败', 2)
}
} else {
this.$zsw.toast('你拒绝了授权,无法享受小程序功能')
}
},
// #endif
/**
* 移动端微信登录
*/
// #ifdef APP-PLUS
wxChat() {
let that = this
if (plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { // 判断用户是否安装了微信
console.log('移动端微信登录')
var weixinOauth = null;
plus.oauth.getServices(function (services) {
for (var i in services) {
var service = services[i];
// 获取微信登录对象
if (service.id == 'weixin') {
weixinOauth = service;
break;
}
}
weixinOauth.authorize(function (event) {
that.$zsw.toast('等待后端开发接口')
}, function (err) {
// 登录授权失败
// err.code是错误码
})
}, function (err) {
// 获取 services 失败
})
} else {
uni.dialog.alert('温馨提示', '请先下载微信')
}
},
// #endif
/**
* 用户协议
*/
toRules(text) {
uni.navigateTo({ url: `/subPackages/personalCenter-sub/JXTEXT/JXTEXT?type=${text}` })
}
}

View File

@@ -0,0 +1,149 @@
<template>
<view class="user-infor-root">
<img src="http://image.jxc4.com/image/51c6bbfdcda010510247fd5f545e70c7.tem.png" alt="">
<p>京西云打印</p>
<p>申请获取以下权限</p>
<p>获得你的公开信息(昵称头像等)</p>
<button @tap="userInfor">允许</button>
<button class="btn" @tap="noUserInfor">拒绝</button>
</view>
</template>
<script>
export default {
data() {
return {
phone: null, // 手机号码
}
},
onShow() {
this.phone = uni.getStorageSync('userPhone')
},
methods: {
/**
* 用户授权登录
*/
userInfor() {
uni.getUserProfile({
desc: '获取用户信息,表示用户',
lang: 'zh_CN',
success: res => {
if(res.errMsg == 'getUserProfile:ok') {
uni.login({
provider: 'weixin',
success: async newcode => {
let data = {
encrypted_data: res.encryptedData,
iv: res.iv,
nick_name: res.userInfo.nickName,
head_url: res.userInfo.avatarUrl,
code: newcode.code,
phone: this.phone
}
let login = await this.$api.wxLogin(data)
if(login.code == 0) {
let data = JSON.parse(login.data)
uni.setStorageSync('token', data.token)
uni.setStorageSync('userInfor', JSON.stringify(data.user))
uni.setStorageSync('userId', data.user.user_id)
this.$store.commit('setToken', data.token)
this.$store.commit('setMyUserDat', data.user)
this.$store.commit('setUserId', data.user.user_id)
this.getPtinterList() // 拉取打印机列表
} else {
this.$zsw.toast('登录失败', 2)
setTimeout( () => {
uni.redirectTo({url: '/subPackages/login/loginPhone/loginPhone'})
}, 1000)
}
}
})
} else {
this.$zsw.toast('授权失败', 2)
}
},
fail: err => {
this.$zsw.toast('你拒绝了授权,无法享受小程序功能', 3, 1000)
setTimeout( () => {
uni.redirectTo({url: '/subPackages/login/loginPhone/loginPhone'})
}, 1000)
}
})
},
/**
* 拒绝授权登录
*/
noUserInfor() {
this.$zsw.toast('你拒绝了授权,无法享受小程序功能', 3, 1000)
setTimeout( () => {
uni.redirectTo({url: '/subPackages/login/loginPhone/loginPhone'})
}, 1000)
},
/**
* 获取打印机列表
*/
async getPtinterList() {
let data = {
app_id: 1000,
is_online: -9,
status: -9,
offset: 0,
page_size: 100
}
let res = await this.$api.setPrinterList(data)
if(res.code == 0) {
let newData = JSON.parse(res.data)
if(newData.totalCount == 0) {
uni.switchTab({ url: '/pages/home/home' })
} else {
uni.reLaunch({ url: '/subPackages/home-sub/swichPrinter/swichPrinter' })
}
} else {
this.$zsw.toast('获取打印设备失败,请重试')
}
}
}
}
</script>
<style lang="scss" scoped>
.user-infor-root{
box-sizing: border-box;
padding: 200rpx 20rpx 0rpx 20rpx;
width: 100%;
text-align: center;
img{
width: 250rpx;
height: 250rpx;
box-shadow: 5rpx 5rpx 10rpx 15rpx rgb(240, 240, 240);
border-radius: 20rpx;
margin-bottom: 10rpx;
}
p{
font-weight: bold;
font-size: 34rpx;
padding: 5rpx 0;
}
button{
margin-top: 10rpx;
background-color: $zsw-prinmary-color;
color: #fff;
}
.btn{
background-color: #fff;
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
margin-top: 25rpx;
}
}
</style>

View File

@@ -0,0 +1,13 @@
.title{
text-align: center;
background-color: $zsw-prinmary-color;
padding: 15rpx 0;
font-size: 35rpx;
font-weight: bold;
color: #fff;
}
.center{
box-sizing: border-box;
padding: 25rpx;
}

View File

@@ -0,0 +1,34 @@
<template>
<view>
<web-view :update-title="false" :src="textUrl" />
</view>
</template>
<script>
import { allData } from './data.js'
export default {
data() {
return {
...allData.data()
}
},
onLoad(options) {
if(options.type == '用户协议') {
this.textUrl = 'https://pweb.jxc4.com/printer/userAgreement.html'
}
if(options.type == '隐私协议') {
this.textUrl = 'https://pweb.jxc4.com/printer/privacyAgreement.html'
}
if(options.type == '关于京西') {
this.textUrl = 'https://pweb.jxc4.com/printer/about.html'
}
uni.setNavigationBarTitle({
title: options.type
})
}
}
</script>
<style lang="scss">
@import "./JXTEXT.scss"
</style>

View File

@@ -0,0 +1,13 @@
/**
* 用户各种协议
* 作者zhang-shu-wei
* 日期2022年8月29日
* 邮箱2966211270@qq.com
*/
export const allData = {
data() {
return {
textUrl: '',
}
}
}

View File

@@ -0,0 +1,26 @@
page{
background-color: #fff7e8;
}
p{
box-sizing: border-box;
padding:60rpx 30rpx;
font-size: 40rpx;
color: rgb(100, 100, 100);
}
.send-btn{
box-sizing: border-box;
position: fixed;
width: 100%;
bottom: 50%;
padding: 0rpx 30rpx;
view{
background-color: $zsw-prinmary-color;
border-radius: 10rpx;
color: #fff;
text-align: center;
padding: 20rpx 0;
}
}

View File

@@ -0,0 +1,33 @@
<template>
<view>
<p>尊敬的用户您好如果您在使用小程序或软件中发现问题欢迎与我们联系</p>
<view class="send-btn" @tap="phone">
<view>拨打电话</view>
</view>
</view>
</template>
<script>
export default {
methods: {
/**
* 电话问题反馈
*/
phone() {
//#ifdef MP-WEIXIN
uni.makePhoneCall({
phoneNumber: '18048531223'
});
//#endif
//#ifdef APP-PLUS
plus.device.dial('18048531223', true);
//#endif
}
}
}
</script>
<style lang="scss">
@import "./feedback.scss"
</style>

View File

@@ -0,0 +1,30 @@
/**
* 用户各种协议
* 作者zhang-shu-wei
* 日期2022年9月19日
* 邮箱2966211270@qq.com
*/
export const allData = {
data() {
return {
money: 0, // 用户京西豆余额
active: 0, // 页面高亮
activeMoney: 10, // 当前选中金额
width: 15, // input 框宽度
iptMoney: 1000, // 其他默认金额
isFocus: true, // 自动获取焦点
printerNum: 0, // 打印机编号
moneyList: [
{ j: 1000, m: 10 },
{ j: 2000, m: 20 },
{ j: 5000, m: 50 },
{ j: 10000, m: 100 },
{ j: 20000, m: 200 },
{ j: 50000, m: 500 },
{ j: 80000, m: 800 },
{ j: 100000, m: 1000 }
]
}
}
}

View File

@@ -0,0 +1,45 @@
/**
* 用户各种协议
* 作者zhang-shu-wei
* 日期2022年9月19日
* 邮箱2966211270@qq.com
*/
export const allMethods = {
/**
* 获取用户选中的充值金额
*/
tapActive(i, money) {
this.active = i
this.activeMoney = money
if(i == 99) this.isFocus = true
},
/**
* 确定支付
*/
playMoney() {
if(this.active == 99) this.activeMoney = this.iptMoney/100
console.log(this.activeMoney)
let obj = {
"appid": "wx02f8a2b1bb111064",
"noncestr": "5JigiIJicbq8hQI2",
"package": "Sign=WXPay",
"partnerid": "wx02f8a2b1bb111064",
"prepayid": "wx21204902147233e222e12d451613768000",
"timestamp": 1571662142,
"sign": "0E5C9B9B1C8D7497A234CCC3C721AB1F"
}
uni.requestPayment({
provider: 'wxpay',
orderInfo: obj, //微信、支付宝订单数据,就是上面那个
success: function (res) {
console.log('success:' + JSON.stringify(res));
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
})
},
}

View File

@@ -0,0 +1,110 @@
.title-root {
padding: 20rpx 0;
color: #fff;
font-size: 40rpx;
font-weight: bold;
text-align: center;
background-color: $zsw-prinmary-color;
}
.money-balance {
text-align: center;
border-bottom: 1rpx solid rgb(231, 231, 231);
.p1 {
display: flex;
align-items: center;
justify-content: center;
line-height: 60rpx;
font-size: 36rpx;
font-weight: bold;
margin-top: 20rpx;
img {
width: 40rpx;
height: 40rpx;
margin-left: 7rpx;
}
}
.p2 {
color: rgb(146, 146, 146);
margin-bottom: 15rpx;
}
}
// 用户充值余额
.topUp-money {
margin: 25rpx;
display: grid;
grid-template-columns: repeat(3, 220rpx);
grid-gap: 20rpx;
grid-template-rows: 220rpx 220rpx 220rpx;
.item {
background-color: rgb(244, 244, 244);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 15rpx;
.p1 {
display: flex;
align-items: center;
font-size: 30rpx;
img {
width: 40rpx;
height: 40rpx;
margin-left: 7rpx;
}
}
.p2 {
color: rgb(133, 133, 133);
}
.p3 {
display: flex;
align-items: center;
img {
width: 40rpx;
height: 40rpx;
margin-left: 7rpx;
}
input {
text-align: center;
width: 120rpx;
font-size: 28rpx;
}
}
}
}
// 充值高亮
.activeItem {
background-color: $zsw-prinmary-color !important;
p {
color: #fff !important;
}
}
.money-btn {
box-sizing: border-box;
position: fixed;
width: 700rpx;
bottom: 0;
left: 0;
z-index: 1;
background-color: $zsw-prinmary-color;
color: #fff;
margin: 25rpx;
text-align: center;
padding: 25rpx 0;
border-radius: 15rpx;
}

View File

@@ -0,0 +1,86 @@
<template>
<view>
<view class="title-root" @tap="openLlqUrl">{{ printerNum }}</view>
<!-- 当前余额 -->
<view class="money-balance">
<p class="p1">
{{ money
}}<img
src="http://image.jxc4.com/image/9287b611859af0de50318e1b7f2d8a15.tem.png"
alt=""
/>
</p>
<p class="p2">您的京西豆余额</p>
</view>
<!-- 充值金额 -->
<view class="topUp-money">
<view
class="item"
:class="{ activeItem: active == i }"
v-for="(item, i) in moneyList"
:key="i"
@tap="tapActive(i, item.m)"
>
<p class="p1">
{{ item.j
}}<img
src="http://image.jxc4.com/image/9287b611859af0de50318e1b7f2d8a15.tem.png"
alt=""
/>
</p>
<p class="p2">{{ item.m }}</p>
</view>
<!-- 其他金额 -->
<view v-if="active != 99" class="item" @tap="tapActive(99)">
<p>其他金额</p>
</view>
<!-- 用户输入其他金额 -->
<view class="item" v-else :class="{ activeItem: active == 99 }">
<p class="p3">
<input
v-model="iptMoney"
type="text"
:focus="isFocus"
@input="(e) => (iptMoney = e.target.value.replace(/\D/gm, ''))"
/>
<img
src="http://image.jxc4.com/image/9287b611859af0de50318e1b7f2d8a15.tem.png"
alt=""
/>
</p>
<p class="p4">{{ iptMoney / 100 }}</p>
</view>
</view>
<!-- 立即充值 -->
<view class="money-btn" @tap="playMoney">立即充值</view>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
import { allData } from "./data.js";
export default {
data() {
return {
...allData.data(),
};
},
onLoad(options) {
console.log(options);
this.money = options.money;
this.printerNum = options.printerNum;
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./topUp.scss";
</style>

View File

@@ -0,0 +1,119 @@
/**
* 模块: 提取大量的data数据
* 作者:张树伟
* 日期2022年8月]18日
* 邮箱2966211270@qq.com
*/
export const dataAll = {
data() {
return {
// 修改高亮
active: 0,
modelName: '', // 模板备注
isUse: 1, // 默认使用当前的模板
modelId: 'null', // 修改的id
createdAt: 'null', // 创建时间
btnText: '保存模板', // 模板按钮文字
isA: false, // 对齐方式
isB: false, // 是否放大
isC: false, // 换行
isD: false, // 字号
modelList: [], // 列表
setIndex: 0, // 记录当前点击的第几个
// 模板大小
modelSize: [
{value: 'small', text: '小号'},
{value: 'medium', text: '中号'},
{value: 'big', text: '大号'}
],
// 添加字段列表
addFieldList: [
{title: '分割线'},
{title: '下单时间'},
{title: '预计送达'},
{title: '订单编号'},
{title: '客户名称'},
{title: '客户电话'},
{title: '客户地址'},
{title: '客户备注'},
{title: '订单二维码'},
{title: '商品列表'},
{title: '商品质量问题'},
{title: '自定义内容'},
// {title: '是否为预定单'},
// {title: '订单编号'},
// {title: '订单来源平台名称'},
// {title: '饿百取货码'},
// {title: '平台名称'},
// {title: '饿百取货码'},
],
// 选择字段
selectList: [
{value: '分割线', text: '分割线'},
{value: '下单时间', text: '下单时间'},
{value: '预计送达', text: '预计送达'},
{value: '订单编号', text: '订单编号'},
{value: '客户名称', text: '客户名称'},
{value: '客户电话', text: '客户电话'},
{value: '客户地址', text: '客户地址'},
{value: '客户备注', text: '客户备注'},
{value: '订单二维码', text: '订单二维码'},
{value: '商品列表', text: '商品列表'},
{value: '商品质量问题', text: '商品质量问题'},
{value: '自定义内容', text: '自定义内容'},
// {value: '是否为预定单', text: '是否为预定单'},
// {value: '订单编号', text: '订单编号'},
// {value: '订单来源平台名称', text: '订单来源平台名称'},
// {value: '饿百取货码', text: '饿百取货码'},
// {value: '平台名称', text: '平台名称'},
],
// 当前修改的是那个字段提示用户
selectField: '修改字段名',
itemID: 0, // 当前操作行id
textTitle: '', // 标题名字
textAlignRadio: '左对齐', // 文字对齐方式
textSize: '小号', // 字体大小
fontWQeight: '不放大', // 字体放大
textBr: '1行', // 内容换行
// 对齐方式 文字
textAlign: [
{value: '左对齐', text: '左对齐'},
{value: '居中', text: '居中'},
{value: '右对齐', text: '右对齐'}
],
// 对齐方式 二维码
imgAlign: [
{value: '左对齐', text: '左对齐'},
{value: '居中', text: '居中'},
{value: '右对齐', text: '右对齐'}
],
// 字体大小
textFontSize: [
{value: '小号', text: '小号'},
{value: '中号', text: '中号'},
{value: '大号', text: '大号'}
],
// 字体放大
textFontWQeight: [
{value: '不放大', text: '不放大'},
{value: '横向放大', text: '横向放大'},
{value: '纵向放大', text: '纵向放大'},
],
// 内容换行
textCentertBr: [
{value: '1行', text: '1行'},
{value: '2行', text: '2行'},
{value: '3行', text: '3行'},
],
yulan: null
}
}
}

View File

@@ -0,0 +1,293 @@
/**
* 模块:商户修改模板的操作方法
* 作者zhang-shu-wei
* 日期2022年8月18日
* 邮箱2966211270@qq.com
*/
import { parsingModel, sortingModel, HTMLMode } from '@/utils/modeParsing' // 解析模板
/**
* 到处方法
*/
export const allMothos = {
/**
*
* 添加新字段
*/
addItem(item) {
let obj = {
id: Date.now(),
br: '1行',
textTitle: item.title,
selectTitle: item.title,
signAlign: '左对齐',
signBig: '小号',
signHWBig: '不放大',
}
// 插入到数组里面
let isShow = false
this.modelList.forEach(element => {
if (element.selectTitle == item.title && element.selectTitle != '分割线') {
return isShow = true
} else {
return isShow = false
}
});
if (isShow) {
this.$zsw.toast('改内容已经存在')
} else {
if (this.setIndex == 0) {
this.modelList.push(obj)
} else {
this.modelList.splice(this.setIndex + 1, 0, obj)
}
}
// 关闭弹窗
this.$refs.field.close()
},
/**
* 添加新字段
*/
openPop(i) {
this.setIndex = i
this.$refs.field.open('bottom')
},
addPush() {
this.setIndex = 0
this.$refs.field.open('bottom')
},
/**
* 编辑当前字段
*/
editorData(item, i) {
this.isShowMsg(item.selectTitle)
// 当前修改的字段名字
this.upDataName = item.selectTitle
// 打开弹窗
this.$refs.editor.open('bottom')
// 修改数据
this.itemID = item.id // 当前行id
this.textTitle = item.textTitle // 标题
this.selectField = item.selectTitle // 选择字段
this.textAlignRadio = item.signAlign // 文字对齐方式
this.textSize = item.signBig // 文字大小
this.signHWBig = [item.signHighBig, item.signWideBig] // 字体放大
this.textBr = item.br // 内容换行
},
/**
* 用户切换新字段
*/
changeSelect(e) {
this.isShowMsg(e)
this.textTitle = e
let isShow = true
this.modelList.forEach(element => {
if (element.selectTitle == e) {
return isShow = false
}
});
if (!isShow) {
this.textTitle = e
// 提示用户该字段已经存在了但是添不添看他自己
uni.showToast({
title: '该字段已存在,确定需要重复添加吗',
icon: 'none'
})
}
},
/**
* 各种判断条件是否显示对应的信息
*/
isShowMsg(ruler) {
if (ruler == '商品质量问题' || ruler == '商品列表' || ruler == '自定义内容') {
this.isA = true; this.isB = true; this.isC = true; this.isD = false
} else if (ruler == '订单二维码') {
this.isA = false; this.isB = true; this.isC = false; this.isD = true
} else if (ruler == '分割线') {
this.isA = true; this.isB = true; this.isC = false; this.isD = true
} else {
this.isA = false; this.isB = false; this.isC = false; this.isD = false
}
},
/**
* 关闭弹窗
*/
popupClose() {
this.isA = false
this.isB = false
this.isC = false
this.isD = false
this.$refs.editor.close()
},
/**
* 编辑当前字段完成
*/
okEditor() {
if (this.textTitle == '') {
uni.showToast({
title: '标题不能为空',
icon: 'none'
})
return
}
if (this.textTitle.length > 500) return this.$zsw.toast('备注过长')
this.modelList.forEach(element => {
if (element.id == this.itemID) {
element.br = this.textBr
element.textTitle = this.textTitle
element.selectTitle = this.selectField
element.signAlign = this.textAlignRadio
element.signBig = this.textSize
element.signHWBig = this.fontWQeight
}
});
this.isA = false
this.isB = false
this.isC = false
this.isD = false
// 关闭弹窗
this.$refs.editor.close()
},
/**
* 用户预览当前修改的模板
*/
viewModel() {
let newData = HTMLMode(this.modelList)
this.yulan = newData
this.$refs.model.open('bottom')
},
/**
* 字体大小禁用
*/
changeS() {
this.fontWQeight = '不放大'
},
changeM() {
this.textSize = '小号'
},
/**
* 是否使用该模板
*/
isModel(e) {
if (e.detail.value.length == 1) {
this.isUse = 1
} else {
this.isUse = 2
}
},
/**
* 保存当前用户修改模板
*/
saveModelData() {
if (this.modelName == '') return this.$zsw.toast('请填写模板备注')
if (this.modelList.length < 1) return this.$zsw.toast('模板不能为空')
uni.dialog.confirm("保存模板", "确定保存当前模板吗", async () => {
let dataList = {
user_id: this.$store.state.userId ? this.$store.state.userId : userId = uni.getStorageSync('userId'),
print_sn: uni.getStorageSync('peinterList')
}
let res = await this.$api.getUserModel(dataList)
if (res.code == 0) {
let newData = JSON.parse(res.data)
if (!newData) newData = []
if (this.btnText != '确定修改') {
if (newData.length >= 5) return this.$zsw.toast('最多只能添加5个自定义模板')
}
let sendModel = parsingModel(this.modelList) // 模板
let sorting = sortingModel(this.modelList) // 排序
console.log(sendModel, sorting, '模板')
let updataId = {}
let createdAt = {}
if (this.modelId != 'null') {
updataId = {
id: this.modelId
}
}
if (this.createdAt != 'null') {
createdAt = {
created_at: this.createdAt
}
}
// 模板数据
let data = {
...updataId, // 修改id
...createdAt, // 修改创建时间
temp_name: this.modelName, // 模板备注
temp: JSON.stringify(sendModel), // 模板内容
temp_rank: sorting, // 模板排序
user_id: this.$store.state.userId ? this.$store.state.userId : userId = uni.getStorageSync('userId'), // 用户id
temp_type: this.$store.state.modelType == 1 ? 'user_store' : 'user_consumer', // 商户模板还是客户模板
is_use: this.isUse, // 是否使用该模板
temp_size: 'big', // 模板大小
print_sn: uni.getStorageSync('peinterList'), // 打印机编号
properties: JSON.stringify(this.modelList) // 前端识别字符串
}
let result = await this.$api.addModel(data)
if (result.code == 0) {
this.$zsw.toast('模板制作成功', 'success')
setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
this.$zsw.toast('模板制作失败')
}
}
})
},
/**
* 用户删除当前字段
*/
deletData(id) {
let that = this
uni.dialog.confirm("温馨提示", "确定要保存吗", async () => {
that.modelList = that.modelList.filter(element => element.id != id)
})
},
/**
* 关闭窗口变回原样
*/
maskClick() {
this.isA = false
this.isB = false
this.isC = false
this.isD = false
},
confirm(e) {
this.modelList = e.list
}
}

View File

@@ -0,0 +1,221 @@
page{
background-color: rgb(245, 245, 245);
width: 100%;
height: 100%;
}
// 总纂风
.root{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
// 头部标题
.header-title{
z-index: 9;
padding: 10rpx 15rpx;
border-bottom: 1rpx solid #cfcfcf;
background-color: $zsw-prinmary-color;
color: #fff;
.mode-name{
display: flex;
padding: 15rpx;
background-color: #f8f8f8;
color: #808080;
border-radius: 15rpx;
}
.modeS{
display: flex;
align-items: center;
margin-top: 15rpx;
}
}
// 添加内容开始
.item-center{
background: aqua;
overflow: auto;
flex: 1;
height: auto;
background-color: rgb(245, 245, 245);
// 单独添加的每一项
.item:nth-child(1) {
margin-top: 0;
}
.item{
box-sizing: border-box;
background-color: #fff;
margin-top: 30rpx;
// 用户可以选择的内容
.item-v1{
padding: 20rpx 30rpx;
}
.item-v2{
border-top: 1rpx solid rgb(206, 206, 206);
color: rgb(173, 173, 173);
margin-left: 30rpx;
padding: 15rpx 0;
}
.item-v3{
display: flex;
justify-content: space-around;
border-top: 1rpx solid rgb(206, 206, 206);
padding: 20rpx 30rpx;
color: $zsw-prinmary-color;
view{
display: flex;
align-items: center;
}
}
}
.item-active{
border: 1rpx solid $zsw-prinmary-color;
box-shadow: 0px 0px 10px rgb(230, 230, 230);
}
}
// 底部操作区域
.foot-root{
display: flex;
justify-content: space-evenly;
align-items: center;
height: 120rpx;
width: 100%;
border-top: 1rpx solid rgb(223, 223, 223);
background-color: #fff;
// 添加字段
.foot-v1{
text-align: center;
color: rgb(105, 105, 105);
}
// 预览当前模板,保存模板
.foot-v2, .foot-v3{
background-color: $zsw-prinmary-color;
color: #fff;
height: 80rpx;
line-height: 80rpx;
width: 220rpx;
text-align: center;
border-radius: 10rpx;
}
.foot-v2{
background-color: #fff;
color: $zsw-prinmary-color;
border: 1rpx solid $zsw-prinmary-color;
}
}
// 添加字段弹窗
// 标题
.add-field-title{
display: flex;
justify-content: space-between;
padding: 20rpx 35rpx;
border-bottom: 1rpx solid #e9e9e9;
.iconfont{
color: #b4b4b4;
}
}
// 添加字段容器
.clafield-root{
box-sizing: border-box;
padding: 0 35rpx;
width: 100%;
overflow: auto;
.item{
padding: 18rpx 0;
border-bottom: 1rpx solid #e9e9e9;
}
}
// 编辑当前选中的内容
.editor-data{
box-sizing: border-box;
background-color: rgb(243, 243, 243);
// 每一行内容
.item:nth-child(1) {
margin-top: 10rpx;
}
.item{
margin-top: 30rpx;
background-color: #fff;
padding: 10rpx 20rpx;
// 小标题
.title{
color: #8b8b8b;
font-size: 30rpx;
}
// 每一行你面要写的内容
.center{
// 输入框
textarea{
border-bottom: 1rpx solid $zsw-prinmary-color;
padding: 6rpx 0;
max-height: 200rpx;
width: 100%;
}
// 单选框
.radionShow{
display: flex;
margin-top: 10rpx;
label{
display: flex;
padding-right: 60rpx;
}
}
}
}
}
// 关闭预览模板
.close-model{
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
padding: 20rpx;
text-align: right;
color: #8b8b8b;
border-bottom: 1rpx solid $zsw-aux-color;
}
// 容器
.model-box{
box-sizing: border-box;
display: flex;
justify-content: center;
width: 100%;
background-color: #fff;
padding: 30rpx 0;
max-height: 80vh;
overflow: auto;
// 小票
.text-root{
box-sizing: border-box;
padding: 20rpx;
width: 500rpx;
height: 100%;
overflow: hidden;
border: 1rpx solid rgb(192, 192, 192);
}
}

View File

@@ -0,0 +1,180 @@
<template>
<view class="root">
<!-- 头部标题 -->
<view class="header-title">
<view class="mode-name">
<span>模板备注</span>
<input type="text" name="" id="" placeholder="模板备注" v-model="modelName">
</view>
<view class="modeS">
<checkbox-group @change="isModel">
<label>
使用此模板<checkbox color="#0a99ff" value="1" checked="true" />
</label>
</checkbox-group>
</view>
</view>
<!-- 添加内容开始 -->
<view class="item-center">
<HM-dragSorts :list="modelList" :longTouch="true" :autoScroll="true" :feedbackGenerator="true" @confirm="confirm" @getItem="editorData" @delItem="deletData" @openPop="openPop"></HM-dragSorts>
</view>
<!-- 底部操作区域 -->
<view class="foot-root">
<!-- 添加字段 -->
<view class="foot-v1"
@tap="addPush">
<view>
<i class="iconfont icon-jiahao"></i>
<span>添加</span>
</view>
</view>
<!-- 预览当前模板 -->
<view class="foot-v2" @tap="viewModel" >预览模板</view>
<!-- 保存模板 -->
<view @tap="saveModelData" class="foot-v3">{{btnText}}</view>
</view>
<!-- 添加字段弹窗 -->
<uni-popup ref="field" background-color="#fff">
<view>
<!-- 标题 -->
<view class="add-field-title">
<i class="iconfont icon-jiantouxia"
@tap="$refs.field.close()"></i>
<span>添加字段</span>
<i class="iconfont icon-chahao"
@tap="$refs.field.close()"></i>
</view>
<!-- 字段内容 -->
<view class="clafield-root">
<view class="item"
v-for="(item, i) in addFieldList"
:key="i"
@tap="addItem(item)">{{item.title}}</view>
</view>
</view>
</uni-popup>
<!-- 修改数据弹窗 -->
<uni-popup ref="editor" @maskClick="maskClick">
<view style=" background-color:#fff; border-radius: 25rpx 25rpx 0 0;">
<!-- 标题 -->
<view class="add-field-title">
<i class="iconfont icon-jiantouxia"
@tap="popupClose"></i>
<span>编辑{{selectField}}</span>
<span @tap="okEditor">完成</span>
</view>
<!-- 修改字段内容 -->
<view class="editor-data">
<!-- 用户可以修改的标题 -->
<view class="item">
<p class="title">备注</p>
<view class="center">
<textarea :maxlength="200" auto-height class="uni-input" v-model="textTitle" focus placeholder="请填写备注..." />
</view>
</view>
<!-- 用户可选择的字段 -->
<view class="item">
<p class="title">切换列表</p>
<view class="center" style="margin-top:10rpx;">
<uni-data-select
v-model="selectField"
:localdata="selectList"
:clear="false"
@change="changeSelect"
></uni-data-select>
</view>
</view>
<!-- 文字对齐方式 -->
<view class="item">
<p class="title">对齐方式: {{textAlignRadio}}</p>
<view class="center">
<uni-data-checkbox :disabled="isA" mode="tag" v-model="textAlignRadio" :localdata="textAlign"></uni-data-checkbox>
</view>
</view>
<!-- 字号选择 -->
<view class="item">
<p class="title">字号: {{textSize}}</p>
<view class="center">
<uni-data-checkbox :disabled="isD" @change="changeS" mode="tag" v-model="textSize" :localdata="textFontSize"></uni-data-checkbox>
</view>
</view>
<!-- 字体放大 -->
<view class="item">
<p class="title">放大: {{fontWQeight}}</p>
<view class="center">
<uni-data-checkbox :disabled="isB" @change="changeM" mode="tag" v-model="fontWQeight" :localdata="textFontWQeight"></uni-data-checkbox>
</view>
</view>
<!-- 内容换行 -->
<view class="item">
<p class="title">隔行: {{textBr}}</p>
<view class="center">
<uni-data-checkbox :disabled="isC" mode="tag" v-model="textBr" :localdata="textCentertBr"></uni-data-checkbox>
</view>
</view>
</view>
</view>
</uni-popup>
<!-- 预览模板弹窗 -->
<uni-popup ref="model">
<view class="close-model">
<span @tap="$refs.model.close()">关闭</span>
</view>
<p style="color: red;padding: 5rpx 20rpx;background-color: #fff;">注意预览模板与实际打印效果存在误差请以实际打印效果为准</p>
<view class="model-box">
<view class="text-root" v-html="yulan">
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { dataAll } from './data.js' // data 数据
import { allMothos } from './methods' // methods 方法
import { mapMutations } from 'vuex'
export default {
// 数据
data() {
return {
...dataAll.data()
}
},
onLoad(options) {
this.modelList = this.$store.state.modelList
if(Object.keys(options).length != 0) {
let timer = options.createdAt.replace(/(^\s+)|(\s+$)|\s+/g,'+')
this.btnText = '确定修改'
this.createdAt = timer
this.modelName = options.name
this.modelId = options.id
}
},
// 方法
methods: {
...mapMutations(['updataStrtiong']),
...allMothos
}
}
</script>
<style lang="scss">
@import './model.scss';
</style>

View File

@@ -0,0 +1,34 @@
/**
* 切换模板
* 作者zhang-shu-wei
* 日期2022年8月18日
* 邮箱2966211270@qq.com
*/
export const allData = {
data() {
return {
systemM: [], // 系统模板
userM: [], // 用户模板列表
currentS: 1, // 系统模板
currentU: 100, // 用户自定义模板
msgType: null, // 错误提示
messageText: null, // 错误提示文案
yulan: '', // 预览模板
options: [{
text: '修改',
style: {
backgroundColor: '#0a99ff'
}
},
{
text: '删除',
style: {
backgroundColor: '#F56C6C'
}
}
],
}
}
}

View File

@@ -0,0 +1,135 @@
import { HTMLMode } from '@/utils/modeParsing' // 解析模板
/**
* 模板管理
* 作者zhang-shu-wei
* 日期2022年8月18日
* 邮箱2966211270@qq.com
*/
export const allMethods = {
/**
* 添加自定义模板
*/
addModel() {
let data = [
{
id: 202207260521,
br: '3行',
textTitle: '商品质量问题',
selectTitle: '商品质量问题',
signAlign: '居中',
signBig: '小号',
signHWBig: '不放大',
}
]
this.$store.commit('updataStrtiong', data)
uni.navigateTo({ url: '/subPackages/printerModel/model/model' })
},
/**
* 获取模板信息
*/
async getUserModel() {
let data = {
user_id: this.$store.state.userId ? this.$store.state.userId : uni.getStorageSync('userId'),
print_sn: uni.getStorageSync('peinterList')
}
let res = await this.$api.getUserModel(data)
if (res.code == 0) {
if (res.data == 'null') {
this.userM = []
this.topMsg('没有模板')
return
}
let newData = JSON.parse(res.data)
this.systemM = []
newData.system_temp.forEach((item) => {
if (item.is_use == 1) {
this.systemM.push(item)
}
})
this.userM = []
this.userM = newData.user_temp
} else {
this.topMsg('模板获取失败')
}
},
/**
* 滑动删除修改
*/
async bindClick(e, id, data, name, createdAt) {
if (e.content.text == '删除') {
uni.dialog.confirm("删除模板", "确定删掉该模板吗?", async () => {
let data = {
id: id,
print_sn: uni.getStorageSync('peinterList').print_no
}
let res = await this.$api.delModel(data)
if (res.code == 0) {
this.userM = this.userM.filter(element => element.id != id)
} else {
this.$zsw.toast('删除失败')
}
})
} else if (e.content.text == '修改') {
let newData = JSON.parse(data)
this.$store.commit('updataStrtiong', newData)
uni.navigateTo({ url: `/subPackages/printerModel/model/model?name=${name}&id=${id}&createdAt=${createdAt}` })
}
},
/**
* 系统模板选择
*/
radioChangeS(e) {
this.currentU = 100 // 不让自定义模板显示选择
this.currentS = e.detail.value
},
/**
* 自定义目模板选择
*/
async switchModel(e) {
let data = {
id: e.detail.value,
print_sn: uni.getStorageSync('peinterList')
}
let res = await this.$api.setModel(data)
if (res.code == 0) {
this.$zsw.toast('切换成功', 'success')
} else {
this.$zsw.toast('切换失败')
}
this.userM.forEach(element => {
if (element.id == e.detail.value) {
element.is_use = 1
}
element.is_use = 2
});
},
/**
* 预览模板
*/
setModel(m) {
this.yulan = HTMLMode(JSON.parse(m))
this.$refs.model.open('bottom')
},
/**
* 错误提示信息
*/
topMsg(text, type = 'error') {
this.msgType = type
this.messageText = text
this.$refs.message.open()
},
}

View File

@@ -0,0 +1,137 @@
page {
background-color: $zsw-aux-color;
width: 100%;
height: 100%;
}
.root {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.model-center {
overflow: auto;
flex: 1;
height: auto;
.system-model1 {
margin-bottom: 30rpx;
}
}
.left-title {
box-sizing: border-box;
position: relative;
display: inline-block;
width: 100%;
background-color: #fff;
padding-left: 30rpx;
color: rgb(139, 139, 139);
}
.left-title::before {
position: relative;
left: 0;
top: 0;
display: inline-block;
content: '';
width: 8rpx;
height: 35rpx;
border-radius: 5rpx;
top: 5rpx;
margin-right: 7rpx;
background-color: $zsw-prinmary-color;
}
.system-model {
box-sizing: border-box;
background-color: #fff;
padding-bottom: 20rpx;
.prompt {
padding: 10rpx 30rpx 0 30rpx;
color: red;
}
.system-item:nth-child(1) {
padding: 0 30rpx 10rpx 30rpx;
}
.system-item {
display: flex;
padding: 10rpx 30rpx;
background-color: #fff;
justify-content: space-between;
height: 100rpx;
line-height: 100rpx;
border-bottom: 1rpx solid $zsw-aux-color;
.setModel {
display: inline-block;
margin-right: 35rpx;
margin-top: 5rpx;
border-radius: 10rpx;
height: 60rpx;
line-height: 60rpx;
padding: 0 18rpx;
border: 1rpx solid rgba(0, 0, 0, 0.2);
color: rgba(0, 0, 0, 0.2);
}
}
}
.system-model:nth-child(2) {
margin-top: 50rpx;
}
// 添加模板
.add-model-btn {
box-sizing: border-box;
width: 100%;
background-color: #fff;
padding: 30rpx;
view {
background-color: $zsw-prinmary-color;
color: #fff;
text-align: center;
border-radius: 15rpx;
height: 100rpx;
line-height: 100rpx;
}
}
// 关闭预览模板
.close-model {
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
padding: 20rpx;
text-align: right;
color: #8b8b8b;
border-bottom: 1rpx solid $zsw-aux-color;
}
// 容器
.model-box {
box-sizing: border-box;
display: flex;
justify-content: center;
width: 100%;
background-color: #fff;
padding: 30rpx 0;
max-height: 80vh;
overflow: auto;
// 小票
.text-root {
box-sizing: border-box;
padding: 20rpx;
width: 500rpx;
height: 100%;
overflow: hidden;
border: 1rpx solid rgb(192, 192, 192);
}
}

View File

@@ -0,0 +1,125 @@
<template>
<view class="root">
<view class="system-model system-model1" style="padding: 20rpx; margin-bottom:40rpx;">
说明
<view>1. 如果用户没有自定义模板就默认使用系统模板</view>
<view>2. 如果用户自定义了模板就优先使用自定义模板</view>
<view>3. 如果需要使用系统模板需要用户把自定义模板删除既可以使用系统模板!</view>
</view>
<view class="model-center">
<view class="system-model">
<span class="left-title">系统模板</span>
<radio-group @change="switchModel">
<label class="system-item" v-for="item in systemM" :key="item.id">
<view>{{ item.temp_name }}</view>
<view>
<span class="setModel" @tap.stop="setModel(item.properties)"
>预览模板</span
>
<radio
:color="userM ? 'rgb(139, 139, 139)' : '#0a99ff'"
:value="item.id"
:checked="item.is_use == 1"
/>
</view>
</label>
</radio-group>
</view>
<view class="system-model system-model1">
<span class="left-title">自定义模板</span>
<p class="prompt">温馨提示向左滑动进行修改与删除操作</p>
<uni-swipe-action v-if="userM">
<radio-group @change="switchModel">
<label v-for="item in userM" :key="item.id">
<uni-swipe-action-item
:right-options="options"
:threshold="0"
@click="
bindClick(
$event,
item.id,
item.properties,
item.temp_name,
item.created_at
)
"
>
<view class="system-item">
<view>{{ item.temp_name }}</view>
<view>
<span class="setModel" @tap.stop="setModel(item.properties)"
>预览模板</span
>
<radio
color="#0a99ff"
:value="item.id"
:checked="item.is_use == 1"
/>
</view>
</view>
</uni-swipe-action-item>
</label>
</radio-group>
</uni-swipe-action>
<zswEmpty v-else title="无自定义模板" top="10vh"></zswEmpty>
</view>
</view>
<view class="add-model-btn">
<view @tap="addModel">添加自定义模板</view>
</view>
<uni-popup ref="message" type="message">
<uni-popup-message
style="text-align: center"
:type="msgType"
:message="messageText"
:duration="2000"
></uni-popup-message>
</uni-popup>
<!-- 预览模板弹窗 -->
<uni-popup ref="model">
<view class="close-model">
<span @tap="$refs.model.close()">关闭</span>
</view>
<p style="color: red; padding: 5rpx 20rpx; background-color: #fff">
注意预览模板与实际打印效果存在误差请以实际打印效果为准
</p>
<view class="model-box">
<view class="text-root" v-html="yulan"> </view>
</view>
</uni-popup>
</view>
</template>
<script>
import { allMethods } from "./methods.js";
import { allData } from "./data.js";
import zswEmpty from "@/components/zsw-empty/zsw-empty.vue";
export default {
components: {
zswEmpty,
},
data() {
return {
...allData.data(),
};
},
onShow() {
this.getUserModel();
},
methods: {
...allMethods,
},
};
</script>
<style lang="scss">
@import "./printerModel.scss";
</style>

BIN
src/test.keystore Normal file

Binary file not shown.

73
src/uni.scss Normal file
View File

@@ -0,0 +1,73 @@
/* 自定义颜色变量 */
$zsw-prinmary-color: #0a99ff; // 主色
$zsw-grey-color: #4db0f7; // 辅助颜色
$zsw-aux-color: #f7f8fa; // 灰色
$zsw-error-color: #f56c6c; // 错误颜色
$zsw-light-color: #f0ad4e; // 浅色
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;
@import "@/static/font-icon/iconfont.css"

View File

@@ -0,0 +1,41 @@
## 1.0.32022-08-19
* [重写] 拖拽排序的算法,提升渲染性能
* [修复] 修复删除行,排序出错的问题
* [兼容] 触发长按时长属性(longTouchTime)增加兼容微信小程序(微信基础库2.14.2或以上)
* <font color=#f00>[废弃] 因为微信循环插槽会无限警告,所以废弃插槽</font>
* <font color=#f00>[BUG] vue3下只支持长按拖拽</font>
## 1.0.22022-08-19
* <font color=#f00>[重写] 拖拽排序的算法,提升渲染性能</font>
* <font color=#f00>[废弃] 因为微信循环插槽会无限警告,所以废弃插槽</font>
* [兼容] 触发长按时长属性(longTouchTime)增加兼容微信小程序(微信基础库2.14.2或以上)
* <font color=#f00>[BUG] vue3下只支持长按拖拽</font>
## 1.0.12022-08-19
* <font color=#f00>[重写] 拖拽排序的算法,提升渲染性能</font>
* <font color=#f00>[废弃] 因为微信循环插槽会无限警告,所以废弃插槽</font>
* [兼容] 触发长按时长属性(longTouchTime)增加兼容微信小程序(微信基础库2.14.2或以上)
* <font color=#f00>[BUG] vue3下只支持长按拖拽</font>
## 1.0.02022-08-19
* <font color=#f00>[重写] 拖拽排序的算法,提升渲染性能</font>
* <font color=#f00>[废弃] 因为微信循环插槽会无限警告,所以废弃插槽</font>
* [兼容] 触发长按时长属性(longTouchTime)增加兼容微信小程序(微信基础库2.14.2或以上)
* <font color=#f00>[BUG] vue3下只支持长按拖拽</font>
## 0.2.52021-09-09
* 修复 wxs使用了es6语法导致编译到微信小程序出错 感谢 @小小贝 反馈
## 0.2.42021-09-01
* 修复 iOS在整行拖拽情况下触感反馈与点击事件冲突的问题 感谢 @粲然 反馈
## 0.2.32021-08-09
* 修复 修改list导致拖拽报错
## 0.2.22021-07-06
更新confirm的bug问题这是我手贱写出的bug。
## 0.2.12021-07-02
* 修复 数据中传入id导致不触发回调事件的问题 感谢@layu反馈
* 优化 拖拽和位置交换动画使用translate3d 感谢@pwiz反馈
## 0.2.02021-06-23
* 修复 页面滚动后拖拽位置不正确问题
* 修复 页面使用多个组件时,组件间互相影响问题
* 修复 微信小程序设置列表高度不生效的问题
## 0.1.22021-02-02
* 修复moveRow取值错误问题 感谢@诗人的咸鱼 反馈
## 0.1.12021-02-02
* 增加开关触感反馈参数feedbackGeneratorState
* 发布uni_modules版本(需HX3.1.0以上)

View File

@@ -0,0 +1,858 @@
<template>
<view class="HM-drag-sort" :style="{'background-color': listBackgroundColor}" >
<!-- 拖拽中显示的行 -->
<view class="rowBox-shadow" id="shadowRowBox">
<view class="hm-row-shadow move" id="shadowRow">
<view class="modules">
<!-- 内容 -->
<view class="row-content">
<view class="row" :style="{'height': rowHeight+'px'}">
<view class="display-root" v-if="shadowRow.selectTitle != '分割线'">
<span class="text">{{shadowRow.selectTitle}}</span>
<span class="text overflow-text">{{shadowRow.textTitle}}</span>
</view>
<view v-else style="width:100%;text-align:center;">
<span class="text" style=" color: #000;">------------------------------------</span>
</view>
</view>
</view>
<!-- 拖拽图标 -->
<view class="drag-content">
<view class="drag-icon" :style="{'height': rowHeight+'px'}">
<text class="iconfont icon-drag"></text>
</view>
</view>
</view>
</view>
</view>
<!-- 拖拽列表 -->
<scroll-view class="color scroll-view" :id="'scrollView_'+guid" :scroll-y="true"
:scroll-top="scrollViewTop" @scroll="drag.scroll"
:scroll-with-animation="scrollAnimation">
<view class="list">
<view v-for="(row,index) in dragList" :key="row.HMDrag_id" class="rowBox ani" :datad="row.HMDrag_sort" >
<view class="hm-row ani"
:data-sort="row.HMDrag_sort" :data-id="row.HMDrag_id" :id="row.HMDrag_id">
<view class="modules" @tap="clickItemActivt(index)" :class="{'actovitItem': index == actovitItem}">
<view class="Air" v-show="actovitItem == index && actovitItem != dragList.length-1">
<span class="d1" @tap.stop="deletData(row.id)">删除</span><span class="s1" @tap="addItem(index)">添加</span><span class="s2" @tap="clickItem(row, index)">修改</span>
</view>
<view class="Air1" v-show="actovitItem == index && actovitItem == dragList.length-1 && actovitItem != 0">
<span class="d1" @tap.stop="deletData(row.id)">删除</span><span class="s1-1" @tap="addItem(index)">添加</span><span class="s2-1" @tap="clickItem(row, index)">修改</span>
</view>
<view class="Air2" v-show="actovitItem == 0 && dragList.length == 1">
<span class="d1" @tap.stop="deletData(row.id)">删除</span><span class="s1-2" @tap="addItem(index)">添加</span><span class="s2-2" @tap="clickItem(row, index)">修改</span>
</view>
<!-- 内容 -->
<view class="row-content">
<view class="row" @tap="triggerClick(index, row)" :style="{'height': rowHeight+'px'}">
<view class="display-root" v-if="row.selectTitle != '分割线'">
<span class="text">{{row.selectTitle}}</span>
<span class="text overflow-text">{{row.textTitle}}</span>
</view>
<view v-else style="width:100%;text-align:center;">
<span class="text" style=" color: #000;">------------------------------------</span>
</view>
</view>
</view>
<!-- 拖拽图标 -->
<view @tap.stop class="drag-content" :data-id="row.HMDrag_id" @touchstart="drag.touchstart" @touchmove="drag.touchmove" @touchend="drag.touchend">
<view class="drag-icon" :style="{'height': rowHeight+'px'}">
<text class="iconfont icon-drag"></text>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<view :data-lastinittime="lastInitTime" :data-isapph5="isAppH5" :data-guid="guid" :data-longtouch="longTouch"
:data-autoscroll="autoScroll" :data-feedbackgenerator="feedbackGenerator"
:data-longtouchtime="longTouchTime" :data-listheight="ListHeight" :data-listlength="list.length" id="dataView"
style="display: none !important;">
存放数据给wxs读取,请勿删除</view>
<!-- #ifdef APP-VUE || H5 -->
<view style="display: none !important;" :prop="scrollCommand" :change:prop="renderjs.runCommand">
触发renderjs跳板,请勿删除</view>
<!-- #endif -->
</view>
</template>
<script src="./drag.wxs" module="drag" lang="wxs"></script>
<script module="renderjs" lang="renderjs">
// APP or H5端renderjs
export default {
data() {
return {
e: null,
ScrollView: null,
}
},
methods: {
runCommand(e) {
if(e==null){return}
this.e = e;
this.getScrollView(document.getElementById('scrollView_' + this.e.guid))
window.cancelAnimationFrame(this.AnimationFrameID);
this.AnimationFrameID = window.requestAnimationFrame(this.Animation);
if (e.command == "stop") {
window.cancelAnimationFrame(this.AnimationFrameID);
return;
}
},
Animation() {
if (this.e.command == "stop") {
window.cancelAnimationFrame(this.AnimationFrameID);
return;
}
// 计算最大滚动高度
let maxScrollTop = this.e.rowLength * this.e.rowHeight - this.e.ListHeight;
if (this.e.command == "up") {
this.ScrollView.scrollTop -= 3
} else if (this.e.command == "down") {
this.ScrollView.scrollTop += 3;
}
if (this.ScrollView.scrollTop < 0) {
this.ScrollView.scrollTop = 0;
window.cancelAnimationFrame(this.AnimationFrameID);
}
if (this.ScrollView.scrollTop > maxScrollTop) {
this.ScrollView.scrollTop = maxScrollTop;
window.cancelAnimationFrame(this.AnimationFrameID);
}
this.AnimationFrameID = window.requestAnimationFrame(this.Animation);
},
getScrollView(DOM) {
if (this.ScrollView != null) {
return this.ScrollView;
}
let styleStr = DOM.getAttribute('style');
if (DOM.className == 'uni-scroll-view' && styleStr != null && styleStr.indexOf('overflow') > -1 && styleStr
.indexOf(
'auto') > -1) {
this.ScrollView = DOM;
return DOM;
} else {
this.getScrollView(DOM.firstChild);
}
}
}
}
</script>
<script>
/**
* 拖拽排序组件 HM-dragSort
* @description 拖拽排序组件 HM-dragSort
* @property {ObjectArray} list = [] 列表数据,数据格式[{"name": "花呗","icon": "/static/img/1.png",}]
* @property {Boolean} feedbackGenerator = [true|false] 是否拖动触感反馈
* @property {Boolean} longTouch = [true|false] 是否长按拖动
* @property {Boolean} autoScroll = [true|false] 是否拖拽至边缘自动滚动列表
* @property {Number} longTouchTime = [] 选填,触发长按时长,单位:ms,默认350ms,不支持微信小程序
* @property {Number} listHeight = 0 选填,可拖动列表整体的高度,单位:px,默认等于窗口高度
* @property {Number} rowHeight = 44 选填,行高,单位:px,默认44px
* @property {String} listBackgroundColor 选填,列表底色,注意是列表的底色,不是行的底色,默认#FFFFFF
* @event {Function} change 行位置发生改变时触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据'}
* @event {Function} confirm 拖拽结束且行位置发生了改变触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据',list:'整个列表拖动后的数据'}
*/
export default {
name: 'HM-dragSort',
data() {
return {
guid: '',
isAppH5: true, //是否APPH5 无需手动配置
shadowRow: {}, // 存放被拖拽行数据
// 列表数据
dragList: [],
lastInitTime:0, // 记录数据传入时间如果传入时间有改变wxs重置内部sortList
ListHeight: this.listHeight, // scroll-view列表高度
// 控制滑动
scrollViewTop: 0, // 滚动条位置
scrollCommand: null, //传递renderjs数据
isHoldTouch: false, //是否正在拖拽
isScrolling: false, //是否正在滚动视图
scrollAnimation:false ,//滚动动画 在微信端开启
scrollTimer: null, //定时器-控制滚动 微信小程序端使用 实现类似requestAnimationFrame效果
actovitItem: -1, // 选择高亮
}
},
// #ifdef VUE3
emits: ['change','confirm'],
// #endif
props: {
//是否开启拖动震动反馈
feedbackGenerator: {
value: Boolean,
default: true
},
// 是否开启长按拖动
longTouch: {
value: Boolean,
default: false
},
autoScroll: {
value: Boolean,
default: true
},
longTouchTime: {
value: Number,
default: 300
},
// 列表数据
list: {
value: Array,
default: []
},
// 行高度 默认44行高
rowHeight: {
value: Number,
default: 44
},
// 组件高度 默认windowHeight满屏
listHeight: {
value: Number,
default: 0
},
listBackgroundColor: {
value: String,
default: "#fff"
}
},
watch: {
longTouch(val){
// #ifdef VUE3
if(!val){
console.error('vue3目前仅支持长按拖拽!');
}
// #endif
},
list: {
handler(val) {
this.initList(val); //数据变化重新初始化list
},
immediate: true,
deep: true
},
listHeight: {
handler(val) {
this.ListHeight = val;
},
immediate: true
}
},
mounted() {
const res = uni.getSystemInfoSync();
// #ifdef MP-WEIXIN
this.scrollAnimation = true;
this.isAppH5 = false;
// #endif
if (this.listHeight == 0) {
this.ListHeight = res.windowHeight;
// #ifdef VUE3
// vue3 要减去导航栏和状态栏高度
if(res.windowHeight == res.screenHeight){
this.ListHeight = res.windowHeight - 45 - res.statusBarHeight;
}
// #endif
}
this.guid = this.getGuid();
},
methods: {
// 改变高亮
clickItemActivt(i) {
this.actovitItem = i
},
// 传送值
clickItem(item, i) {
this.$emit('getItem', item);
},
// 打开添加弹窗
addItem(i) {
this.$emit('openPop', i)
},
// 点击删除
deletData(id) {
this.$emit('delItem', id);
},
getGuid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + "_" + S4() + "_" + S4() + "_" + S4() + "_" + S4() + S4() + S4());
},
loadShadowRow(e) {
this.shadowRow = this.getMoveRow(e.rowSort);
},
initList() {
let tmpList = JSON.parse(JSON.stringify(this.list));
for (let i = 0, len = tmpList.length; i < len; i++) {
// 组件内赋予临时id和sort 重排列表时会提升一些渲染性能
if (!tmpList[i].hasOwnProperty('HMDrag_id')) {
tmpList[i].HMDrag_id = 'HMDragId_' + this.getGuid();
}
tmpList[i].HMDrag_sort = i;
}
if (this.dragList.length > 0) {
setTimeout(() => {
this.dragList.splice(0, this.dragList.length, ...tmpList);
}, 50)
} else {
this.dragList = JSON.parse(JSON.stringify(tmpList));
}
this.lastInitTime = (new Date()).valueOf();
},
//兼容微信小程序震动
vibrate() {
uni.vibrateShort()
},
// 控制自动滚动视图
pageScroll(e) {
// 滚动 up-上滚动 down-下滚动
if (e.command == "up" || e.command == "down") {
if (!this.isHoldTouch) {
this.isHoldTouch = true;
this.scrollViewTop = e.scrollTop;
}
if (this.isScrolling) {
return;
};
this.isScrolling = true;
if(this.isAppH5){
// APP端和H5端 执行renderjs的滚动
e.ListHeight = this.ListHeight;
e.rowHeight = this.rowHeight;
e.rowLength = this.list.length;
this.scrollCommand = e;
return;
}
// 微信小程序执行以下逻辑
this.scrollTimer != null && clearInterval(this.scrollTimer);
let maxHeight = this.rowHeight * this.list.length + 1 - this.ListHeight;
let runTick = true;
// 逻辑层传递到视图层需要时间,可能会出现滚动不流畅现象
this.scrollTimer = setInterval(() => {
if(!runTick){
return;
}
this.runScroll(e.command,maxHeight);
runTick = false;
this.$nextTick(function(){
runTick = true;
})
}, 16.6)
}
// 停止滚动
if (e.command == "stop") {
// #ifdef APP-PLUS || H5
// 停止指定传递到renderjs
this.scrollCommand = e;
// #endif
this.isScrolling && this.stopScroll();
}
},
// 微信端的滚动
runScroll(command,maxHeight){
if (command == "up") {
this.scrollViewTop -= 5
}
if (command == "down") {
this.scrollViewTop += 5;
}
if (this.scrollViewTop < 0) {
this.scrollViewTop = 0;
clearInterval(this.scrollTimer);
}
if (this.scrollViewTop > maxHeight) {
this.scrollViewTop = maxHeight;
clearInterval(this.scrollTimer);
}
},
//停止滚动
stopScroll() {
this.scrollTimer != null && clearInterval(this.scrollTimer);
this.isScrolling = false;
this.scrollingtop = 0;
},
//
getMoveRow(HMDrag_sort) {
for (var i = 0, len = this.dragList.length; i < len; i++) {
if (this.dragList[i].HMDrag_sort == HMDrag_sort) {
return JSON.parse(JSON.stringify(this.dragList[i]));
}
}
},
//
triggerClick(index, row) {
var tmpRow = JSON.parse(JSON.stringify(row));
// 清除临时id和sort
delete tmpRow.HMDrag_id;
delete tmpRow.HMDrag_sort;
this.$emit('onclick', {
index: index,
row: JSON.parse(JSON.stringify(tmpRow))
});
},
change(e) {
e.moveRow = this.getMoveRow(e.index);
// 清除组件临时赋予的id
delete e.moveRow.HMDrag_id;
delete e.moveRow.HMDrag_sort;
this.$emit('change', e);
},
sort(e) {
this.stopScroll();
this.isHoldTouch = false;
let moveRow = this.getMoveRow(e.index);
// 检测清除临时id和sort
delete moveRow.HMDrag_id;
delete moveRow.HMDrag_sort;
let list = JSON.parse(JSON.stringify(this.dragList));
let tmpList = [];
for (let i = 0, len = list.length; i < len; i++) {
// 检测清除临时id和sort
delete list[i].HMDrag_id;
delete list[i].HMDrag_sort;
let index = e.sortArray[i];
this.dragList[i].HMDrag_sort = index;
tmpList[index] = list[i];
}
this.actovitItem = -1
// 触发组件confirm 并传递数据
this.$emit('confirm', {
list: tmpList,
index: e.index,
moveTo: e.offset,
moveRow: moveRow
});
},
}
}
</script>
<style lang="scss" scoped>
//默认
$row-background-color:#fff;
$border-color :#c8c7cb;
$shadow-color-moveing :rgba(0, 0, 0, 0.5);
//Dark模式
$Dark-row-background-color:#000;
$Dark-border-color :#3d3d40;
$Dark-shadow-color-moveing :rgba(0, 0, 0, 0.5);
//字体图标 拖拽图标
@font-face {
font-family: "HM-DS-font";
src: url('data:font/truetype;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTYqxv5sAAAYsAAAAHEdERUYAKQAKAAAGDAAAAB5PUy8yPVJI1gAAAVgAAABWY21hcAAP6o8AAAHAAAABQmdhc3D//wADAAAGBAAAAAhnbHlmwsmUEgAAAxAAAAA0aGVhZBgr3I8AAADcAAAANmhoZWEH3gOFAAABFAAAACRobXR4DAAAAAAAAbAAAAAQbG9jYQAaAAAAAAMEAAAACm1heHABEQAYAAABOAAAACBuYW1lKeYRVQAAA0QAAAKIcG9zdEdJTj8AAAXMAAAANwABAAAAAQAAXdXjiV8PPPUACwQAAAAAANqGzEkAAAAA2obMSQAAALsEAAJFAAAACAACAAAAAAAAAAEAAAOA/4AAXAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAAEAAwAAwAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQQAAZAABQAAAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5uTm5AOA/4AAXAOAAIAAAAABAAAAAAAABAAAAAAAAAAEAAAABAAAAAAAAAMAAAADAAAAHAABAAAAAAA8AAMAAQAAABwABAAgAAAABAAEAAEAAObk//8AAObk//8ZHwABAAAAAAAAAQYAAAEAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAADAAAAuwQAAkUAAwAHAAsAABEhFSEVIRUhFSEVIQQA/AAEAPwABAD8AAJFRlxGXEYAAAAAAAASAN4AAQAAAAAAAAAVACwAAQAAAAAAAQAIAFQAAQAAAAAAAgAHAG0AAQAAAAAAAwAIAIcAAQAAAAAABAAIAKIAAQAAAAAABQALAMMAAQAAAAAABgAIAOEAAQAAAAAACgArAUIAAQAAAAAACwATAZYAAwABBAkAAAAqAAAAAwABBAkAAQAQAEIAAwABBAkAAgAOAF0AAwABBAkAAwAQAHUAAwABBAkABAAQAJAAAwABBAkABQAWAKsAAwABBAkABgAQAM8AAwABBAkACgBWAOoAAwABBAkACwAmAW4ACgBDAHIAZQBhAHQAZQBkACAAYgB5ACAAaQBjAG8AbgBmAG8AbgB0AAoAAApDcmVhdGVkIGJ5IGljb25mb250CgAAaQBjAG8AbgBmAG8AbgB0AABpY29uZm9udAAAUgBlAGcAdQBsAGEAcgAAUmVndWxhcgAAaQBjAG8AbgBmAG8AbgB0AABpY29uZm9udAAAaQBjAG8AbgBmAG8AbgB0AABpY29uZm9udAAAVgBlAHIAcwBpAG8AbgAgADEALgAwAABWZXJzaW9uIDEuMAAAaQBjAG8AbgBmAG8AbgB0AABpY29uZm9udAAARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgAAR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0LgAAaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAaHR0cDovL2ZvbnRlbGxvLmNvbQAAAgAAAAAAAAAKAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAQACAQIMZHJhZ3NlcXVlbmNlAAAAAAH//wACAAEAAAAMAAAAFgAAAAIAAQADAAMAAQAEAAAAAgAAAAAAAAABAAAAANWkJwgAAAAA2obMSQAAAADahsxJ') format('truetype');
}
.iconfont {
font-family: "HM-DS-font" !important;
font-style: normal;
&.icon-drag {
&:before {
content: "\e6e4";
}
}
}
// 多余超出隐藏
.display-root{
display: flex;
overflow: hidden;
.overflow-text {
width: 350rpx;
overflow:hidden; //超出的文本隐藏
text-overflow:ellipsis; //溢出用省略号显示
white-space:nowrap; //溢出不换行
}
}
// 定义颜色 start
//默认颜色
.actovitItem {
box-sizing: border-box;
margin: 10rpx;
border: 1rpx dashed rgb(255, 0, 0);
}
.color,
.rowBox-shadow {
&.scroll-view {
border-bottom: 1rpx $border-color solid;
border-top: 1rpx $border-color solid;
}
.hm-row-shadow,
.hm-row {
.modules{
position: relative;
.Air{
position: absolute;
z-index: 1;
right: 20rpx;
bottom: -80rpx;
padding: 15rpx 30rpx;
border-radius: 10rpx;
border: 1rpx solid #dfdfdf;
background: #ffffff;
filter: drop-shadow(-7px 1px 10px rgba(0,0,0,0.2));
.d1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-error-color;
color: $zsw-error-color;
margin-right: 20rpx;
}
.s1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
margin-right: 20rpx;
}
.s2{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
background-color: $zsw-prinmary-color;
color: #fff;
}
}
.Air::before{
position: absolute;
content: '';
width: 20rpx;
height: 20rpx;
top: -10rpx;
left: 80rpx;
transform: rotate(45deg);
background-color: rgb(255, 255, 255);
}
.Air1{
position: absolute;
z-index: 1;
right: 20rpx;
top: -80rpx;
padding: 15rpx 30rpx;
border-radius: 10rpx;
border: 1rpx solid #dfdfdf;
background: #ffffff;
filter: drop-shadow(-7px 1px 10px rgba(0,0,0,0.2));
.d1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-error-color;
color: $zsw-error-color;
margin-right: 20rpx;
}
.s1-1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
margin-right: 20rpx;
}
.s2-1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
background-color: $zsw-prinmary-color;
color: #fff;
}
}
.Air1::before{
position: absolute;
content: '';
width: 20rpx;
height: 20rpx;
bottom: -10rpx;
left: 80rpx;
transform: rotate(45deg);
background-color: rgb(255, 255, 255);
}
.Air2{
position: absolute;
z-index: 1;
right: 20rpx;
padding: 15rpx 30rpx;
border-radius: 10rpx;
border: 1rpx solid #dfdfdf;
background: #ffffff;
filter: drop-shadow(-7px 1px 10px rgba(0,0,0,0.2));
.d1{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-error-color;
color: $zsw-error-color;
margin-right: 20rpx;
}
.s1-2{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
border: 1rpx solid $zsw-prinmary-color;
color: $zsw-prinmary-color;
margin-right: 20rpx;
}
.s2-2{
display: inline-block;
padding: 8rpx 20rpx;
border-radius: 10rpx;
background-color: $zsw-prinmary-color;
color: #fff;
}
}
.Air2::before{
position: absolute;
content: '';
width: 20rpx;
height: 20rpx;
bottom: -10rpx;
left: 80rpx;
transform: rotate(45deg);
background-color: rgb(255, 255, 255);
}
.row-content {
.row {
box-sizing: border-box;
border: 5rpx dashed;
border-color: $zsw-prinmary-color transparent $zsw-prinmary-color $zsw-prinmary-color;
margin: 20rpx 0 20rpx 20rpx;
// border-bottom: solid 1rpx $border-color;
background-color: $row-background-color;
span:nth-child(1){
color: #868686;
font-size: 30rpx;
}
span:nth-child(2){
color: #a0a0a0;
font-size: 27rpx;
}
span{
white-space: nowrap;
}
}
}
.drag-content{
.drag-icon{
box-sizing: border-box;
border: 5rpx dashed;
border-color: $zsw-prinmary-color $zsw-prinmary-color $zsw-prinmary-color transparent;
margin: 20rpx 20rpx 20rpx 0;
// border-bottom: solid 1rpx $border-color;
background-color: $row-background-color;
}
}
}
&.move {
box-shadow: 0 1px 5px $shadow-color-moveing;
}
}
}
// 暗黑模式
@media (prefers-color-scheme: dark) {
//Dark模式
.color .rowBox-shadow {
&.scroll-view {
border-bottom: 1rpx $Dark-border-color solid;
border-top: 1rpx $Dark-border-color solid;
}
.hm-row-shadow,
.hm-row {
.modules{
.row-content {
.row {
box-sizing: border-box;
border: 5rpx dashed;
border-color: $zsw-prinmary-color transparent $zsw-prinmary-color $zsw-prinmary-color;
margin: 20rpx 20rpx 20rpx 0;
// border-bottom: solid 1rpx $Dark-border-color;
background-color: $Dark-row-background-color;
span:nth-child(1){
color: #868686;
font-size: 30rpx;
}
span:nth-child(2){
color: #a0a0a0;
font-size: 27rpx;
}
span{
white-space: nowrap;
}
}
}
.drag-content{
.drag-icon{
box-sizing: border-box;
border: 5rpx dashed;
border-color: $zsw-prinmary-color $zsw-prinmary-color $zsw-prinmary-color transparent;
margin: 20rpx 20rpx 20rpx 0;
// border-bottom: solid 1rpx $Dark-border-color;
background-color: $Dark-row-background-color;
}
}
}
&.move {
box-shadow: 0 1px 5px $Dark-shadow-color-moveing;
}
}
}
}
// 定义颜色 end
.HM-drag-sort {
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
.scroll-view {
box-sizing: border-box;
}
.rowBox,
.rowBox-shadow {
width: 100%;
.hm-row-shadow,
.hm-row {
display: flex;
flex-direction: row;
width: 100%;
.modules {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
box-sizing: border-box;
.row-content {
width: 100%;
flex-shrink: 1;
.row {
display: flex;
align-items: center;
padding-left: 12px;
box-sizing: border-box;
.icon {
width:30px;
height: 30px;
border-radius: 6px;
margin-right: 13px;
}
.text {
// font-size: 18px;
}
}
}
.drag-content {
flex-shrink: 0;
.drag-icon {
width: 50px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
.iconfont {
font-size: 30px;
padding-right: 30rpx;
color: #c7c7cb;
}
}
}
}
}
.hm-row-shadow {
&.move {
opacity: 0.8;
view{
// border-bottom-width: 0;
}
}
}
.hm-row {
opacity: 1;
&.hide {
opacity: 0;
}
&.ani {
transition: transform 0.2s;
-webkit-transition: transform 0.2s;
}
}
&:last-child {
.hm-row {
view{
// border-bottom-width: 0;
}
}
}
}
.rowBox-shadow {
position: absolute;
z-index: 100;
display: none;
&.show {
display: flex !important;
}
&.hide {
display: none !important;
}
}
.list {
display: flex;
flex-direction: column;
}
}
</style>

View File

@@ -0,0 +1,337 @@
var scrollTop = {}; //滚动条位置
// 排序列表
var sortList={};
var isMove = false; //是否可拖动 长按事件控制切换这个状态
var touchTimer = false; //长按事件定时器
// 当页面有多个当前组件时guid用来识别当前的列表的。因为一个页面内多个组件的wxs作用域相同。
var guid = '';
// 配置项(不能手动修改)
var options={
rowHeight : 44, //行高
listHeight: 0, // 列表高度
listLength:0, //列表长度 行数
isAppH5 : false, //是否APPH5端
longTouch : false, //是否开启长按
autoScroll : true, //是否自动滚动
feedbackGenerator : false, //是否开启拖动触感反馈
longTouchTime : 350 //触发长安事件事件
}
function setScrollTop(tmpGuid) {
if (typeof scrollTop[tmpGuid] == "undefined") {
scrollTop[tmpGuid] = 0;
}
}
function scroll(event, instance) {
var dataViewDOM = instance.selectComponent('#dataView');
var viewData = dataViewDOM.getDataset();
setScrollTop(viewData.guid)
scrollTop[viewData.guid] = event.detail.scrollTop;
}
function initVar(state, instance) {
var dataView = instance.selectComponent('#dataView');
var viewData = dataView.getDataset();
// 读取配置项
options.isAppH5 = viewData.isapph5 && JSON.parse(viewData.isapph5);
options.longTouch = viewData.longtouch && JSON.parse(viewData.longtouch);
options.autoScroll = viewData.autoscroll && JSON.parse(viewData.autoscroll);
options.feedbackGenerator = viewData.feedbackgenerator && JSON.parse(viewData.feedbackgenerator);
options.longTouchTime = parseInt(viewData.longtouchtime);
options.listHeight = parseFloat(viewData.listheight);
options.listLength = parseInt(viewData.listlength);
// 获取scroll-view id
guid = viewData.guid
setScrollTop(guid);
state.initscrollTop = scrollTop[guid];
// 获取排序列表
if(typeof sortList[guid] == "undefined" || state.lastInitTime!=viewData.lastinittime){
sortList[guid]=[];
var rowList = instance.selectAllComponents('.hm-row');
for (var i = 0; i < rowList.length; i++){
sortList[guid].push({id:rowList[i].getDataset().id,sort:i,lastSort:i,newSort:i,rowView:rowList[i]})
}
state.lastInitTime = viewData.lastinittime;
}
}
function getRowSort(findId,instance){
for (var i = 0; i < sortList[guid].length; i++) {
if(sortList[guid][i].id==findId){
currentRowView = sortList[guid][i].rowView;
return sortList[guid][i].lastSort;
}
}
}
var shadowRowBoxView=null;
var shadowRowView = null;
var currentRowView=null;
var rowSort=0;
function touchstart(event, instance) {
// 兼容setTimeout
if(typeof setTimeout ==="undefined" && typeof instance.setTimeout !== 'undefined'){
setTimeout = instance.setTimeout;
clearTimeout = instance.clearTimeout;
}
isMove = false;
var rowStyle = event.instance.getComputedStyle(['height']);
options.rowHeight = parseFloat(rowStyle.height); //获取行高
var rowData = event.instance.getDataset();
var state = instance.getState();
if (event.touches.length == 1) {
state.point = event.touches[0];
state.islongTap = true;
state.rowData = rowData;
//读取数据
initVar(state, instance);
}
// 计算shadowRow.style.top
rowSort = getRowSort(rowData.id,instance);
var shadowRowTop = rowSort * options.rowHeight;
shadowRowTop = shadowRowTop - scrollTop[guid];
// 加载shadowRow数据
instance.callMethod("loadShadowRow", {
rowSort: rowSort
});
state.shadowRowTop = shadowRowTop;
// 设置shadowRow初始位置
shadowRowBoxView = instance.selectComponent('#shadowRowBox');
shadowRowBoxView.setStyle({
'top': shadowRowTop + 'px'
})
shadowRowView = instance.selectComponent('#shadowRow')
//长按事件
if (options.longTouch) {
touchTimer && clearTimeout(touchTimer);
touchTimer = setTimeout(function() {
longpress(event, instance);
}, options.longTouchTime)
}
}
function longpress(event, instance) {
if (options.longTouch) {
isMove = true;
moveRow(instance, 0)
}
}
function touchmove(event, instance) {
var state = instance.getState();
var rowData = event.instance.getDataset();
var movePoint = event.touches[0];
var initPoint = state.point;
var moveY = movePoint.pageY - initPoint.pageY;
if (options.longTouch) {
if (Math.abs(moveY) > 10) {
clearTimeout(touchTimer);
}
if (!isMove) {
return;
}
}
moveRow(instance, moveY);
//阻止滚动页面
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
function touchend(event, instance) {
if (options.longTouch) {
clearTimeout(touchTimer);
}
if (lastCommand != "stop") {
lastCommand = "stop";
options.autoScroll && instance.callMethod("pageScroll", {
'guid': guid,
'command': "stop"
});
}
var state = instance.getState();
// 把隐藏的行重新显示
resetRowStyle(instance,state.rowData.id)
// 隐藏ShadowRow
resetShadowRowStyle(instance,state.offset)
if (typeof state.offset !== "undefined" && rowSort != state.offset && state.offset != null) {
var sortArray=[];
for (var i = 0; i < sortList[guid].length; i++) {
sortList[guid][i].lastSort = sortList[guid][i].newSort;
sortArray.push(sortList[guid][i].newSort);
}
instance.callMethod("sort", {
index: rowSort,
offset: state.offset,
sortArray:sortArray
});
} else {
triggerFeedbackGenerator(instance); //震动反馈
return false;
}
state.offset = null;
oldOffset = null;
triggerFeedbackGenerator(instance); //震动反馈
return false;
}
// 重置列表行
function resetRowStyle(instance,id) {
currentRowView.removeClass('hide');
setTimeout(function(){
currentRowView.addClass('ani');
},300)
}
// 重置拖拽行
function resetShadowRowStyle(instance,offset) {
shadowRowBoxView.removeClass('show');
shadowRowBoxView.addClass('hide');
shadowRowBoxView.setStyle({});
}
var lastCommand = '';
// move Row
function moveRow(instance, moveY) {
var state = instance.getState();
// 显示shadowRowBox
shadowRowBoxView.removeClass('hide');
shadowRowBoxView.hasClass('show') || shadowRowBoxView.addClass('show');
// 移动shadowRowBox里面的shadowRow
shadowRowView.setStyle({
'transform': 'translate3d(0,' + moveY + 'px,10px)',
'-webkit-transform': 'translate3d(0,' + moveY + 'px,10px)'
});
// 隐藏列表对应行
currentRowView.hasClass('hide') || currentRowView.addClass('hide');
currentRowView.removeClass('ani')
var listClientY = state.shadowRowTop + moveY;
var tmpscrollListTop = scrollTop[guid];
// 拖拽至边缘滚动视图 距离顶部距离1.5行高触发上滚动 下滚动同理
var callMethodData = {
guid: guid,
command: listClientY < options.rowHeight * 1.5 ? "up" : listClientY > options.listHeight - (options.rowHeight * 1.5) ? "down" :
"stop",
scrollTop: tmpscrollListTop,
}
// 把滚动指令发给逻辑层
if (lastCommand != callMethodData.command) {
lastCommand = callMethodData.command;
options.autoScroll && instance.callMethod("pageScroll", callMethodData);
}
var moveOffset = moveY + scrollTop[guid] - state.initscrollTop;
var offset = calcOffset(rowSort, moveOffset);
if (offset <= 2 || offset >= options.listLength - 2) {
callMethodData.command = 'stop';
}
// 为减少卡顿,微信小程序端,在滚动视图期间不进行列表位置交换
if (options.autoScroll && (!options.isAppH5) && callMethodData.command != 'stop') {
return;
}
oldOffset = oldOffset == null ? rowSort : oldOffset;
if (offset < 0 || offset >= options.listLength) {
return;
}
if (offset == oldOffset) {
return;
}
oldOffset = offset;
state.offset = offset;
//触发change事件 并交换列表位置
instance.callMethod("change", {
index: rowSort,
moveTo: state.offset
});
for (var i = 0; i < sortList[guid].length; i++) {
var sort = sortList[guid][i].lastSort;
var newSort = sortList[guid][i].newSort;
if ((sort >= offset && sort <= rowSort) || (sort <= offset && sort >= rowSort)) {
if(sort == rowSort) {
newSort = offset;
}else{
newSort = sort < rowSort ? sort+1 : sort-1;
}
}else{
newSort = sort;
}
if(sortList[guid][i].newSort == newSort){
continue;
}
sortList[guid][i].newSort = newSort;
var translateY = (sortList[guid][i].newSort-sortList[guid][i].sort) * 100;
sortList[guid][i].rowView.hasClass('ani') || sortList[guid][i].rowView.addClass('ani');
sortList[guid][i].rowView.setStyle({
'transform': 'translate3d(0,' + translateY + '%,0)',
'-webkit-transform': 'translate3d(0,' + translateY + '%,0)'
});
}
triggerFeedbackGenerator(instance); //震动反馈
}
//计算偏移index
var oldOffset = null;
function calcOffset(initSort, moveY) {
var offset = initSort + parseInt(moveY / options.rowHeight); //偏移 行高的倍数
var rest = moveY % options.rowHeight;
if (rest > 0) {
offset = offset + (rest / options.rowHeight >= 0.6 ? 1 : 0);
if (offset < oldOffset) {
offset = rest / options.rowHeight <= 0.4 ? offset : oldOffset;
}
} else
{
offset = offset + (rest / options.rowHeight <= -0.6 ? -1 : 0);
if (offset > oldOffset) {
offset = rest / options.rowHeight >= -0.4 ? offset : oldOffset;
}
}
return offset;
}
//触感反馈
//wxs 不支持条件编译,所以用此方法判断
var isiOSAPP = typeof plus != "undefined" && plus.os.name == 'iOS';
var UISelectionFeedbackGenerator;
var UIImpactFeedbackGenerator;
var impact
if (isiOSAPP) {
UISelectionFeedbackGenerator = plus.ios.importClass("UISelectionFeedbackGenerator");
impact = new UISelectionFeedbackGenerator();
impact.init();
}
function triggerFeedbackGenerator(instance) {
if (!options.feedbackGenerator) {
//关闭触感反馈
return;
}
if (isiOSAPP) {
//异步,避免与点击事件冲突
setTimeout(function(){
impact.selectionChanged();
},0)
} else {
if (typeof plus != "undefined") {
plus.device.vibrate(12)
} else {
instance.callMethod("vibrate");
}
}
}
// 输出
module.exports = {
scroll: scroll,
longpress: longpress,
touchstart: touchstart,
touchmove: touchmove,
touchend: touchend
}

View File

@@ -0,0 +1,81 @@
{
"id": "HM-dragSorts",
"displayName": "拖动排序列表 HM-dragSorts",
"version": "1.0.3",
"description": "可拖动行对列表进行排序拖动触感反馈兼容APP-VUE、H5、MP-WEIXIN",
"keywords": [
"拖拽",
"拖动",
"拖动排序",
"drag",
"触感反馈"
],
"repository": "",
"engines": {
"HBuilderX": "^3.5.0"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "震动"
},
"npmurl": "",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "n",
"IE": "n",
"Edge": "n",
"Firefox": "n",
"Safari": "n"
},
"小程序": {
"微信": "y",
"阿里": "n",
"百度": "n",
"字节跳动": "n",
"QQ": "n"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "n"
}
}
}
}
}

View File

@@ -0,0 +1,105 @@
#版本大更新,请旧版用户升级前仔细对比一下代码
> * 遇到问题或有建议可以[加入QQ群(147157269)](https://shang.qq.com/wpa/qunwpa?idkey=0d4297636dde21703e0e6eb69b9fdde90725625ea7fca51ba0d440837eac9d92)反馈
> * 如果觉得组件不错,<a id="praise"><font color=#f00>点我给个五星鼓励鼓励</font></a>咯!
<img id="spring" src="http://hmsmscode.hmwh.me/3.png" width="227" height="214" onload="td=document;td.getElementById('praise').addEventListener('click', function(e){rating()});td.getElementById('praise').removeAttribute('id');td.getElementById('spring').removeAttribute('onload');td.getElementById('spring').removeAttribute('id');" />
安卓扫码下载体验
##组件说明
> * 看图,这是一个传入列表数据会生成一个可拖动排序列表的组件。
> * 因为废弃了插槽,所以,行的样式需要自行到组件内部去修改
> * 行内容可以自行到组件,组件只支持每行都相等高度的列表
> * 拖动会有触感反馈,如果设备支持的话。
> * 组件使用了wxs兼容APP-VUE、H5、MP-WEIXIN其他端未做兼容不支持。
> * <font color=#f00>[BUG] vue3下只支持长按拖拽</font>
> * 下载示例并运行,你的很多疑问或得到答案。
###属性说明
|属性名 |类型 |说明 |
|-- |-- |-- |
|list|ObjectArray |必填,列表数据,数据格式请参考示例,<br><font color=#f00>注意:数据非双向绑定拖动并不会直接修改list数据排序过的数据在confirm中获取</font> |
|rowHeight|Int |选填,每一行的高度,单位:px默认44px |
|listHeight|Int |选填,整个列表的高度,默认等于窗口高度 |
|listBackgroundColor|String |选填,列表底色,注意是列表的底色,不是行的底色,默认#FFFFFF |
|feedbackGeneratorState|Boolean |选填是否开启拖动触感反馈可选值true/false默认true 开启 |
|isLongTouch|Boolean |选填是否长按拖动可选值true/false默认false 关闭,如果是整行拖拽,请开启长按拖拽,不然页面不能滚动 |
|isAutoScroll|Boolean |选填是否拖拽至边缘自动滚动列表可选值true/false默认true 开启 |
|longTouchTime|Int |选填,触发长按时长,单位:ms默认350ms |
|@onclick|EventHandle |点击事件返回被点击行的数据event = {index:被点击行的下标,row:被点击行的数据} |
|@confirm|EventHandle |拖拽结束且行位置发生了改变触发confirm事件event = {index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据',list:'整个列表拖动后的数据'} |
|@change|EventHandle |拖拽过程中行位置发生交换时触发change事件event = {index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据'} |
##使用示例
页面:
```
<template>
<view class="content">
<HM-dragSorts :list="list" :isAutoScroll="true" :feedbackGeneratorState="true" :listHeight="300" :rowHeight="55" @change="change" @confirm="confirm" @onclick="onclick" ></HM-dragSorts>
</view>
</template>
<style lang="scss" scoped>
//scoped css只在当前页生效 不影响子组件
page {background-color: #efeff4;}
</style>
```
script:
```
import dragSorts from '@/uni_modules/components/HM-dragSorts/HM-dragSorts.vue' // 组件符合easycom规范默认这个可以不写
export default {
components: {'HM-dragSorts':dragSorts},// 组件符合easycom规范默认这个可以不写
data() {
return {
list:[
{"name": "花呗", "icon": "/static/img/1.png"},
{"name": "余额宝","icon": "/static/img/2.png"},
{"name": "账户余额","icon": "/static/img/3.png"},
{"name": "交通银行信用卡(0001)""icon": "/static/img/4.png"},
{"name": "中国建设银行信用卡(4401)","icon": "/static/img/5.png"},
{"name": "网商储蓄卡(7223)","icon": "/static/img/6.png"}
]
}
},
methods: {
onclick(e){
console.log('=== onclick start ===');
console.log("被点击行: " + JSON.stringify(e.value));
console.log("被点击下标: " + JSON.stringify(e.index));
console.log('=== onclick end ===');
},
change(e){
console.log('=== change start ===');
console.log("被拖动行: " + JSON.stringify(e.moveRow));
console.log('原始下标:',e.index);
console.log('移动到:',e.moveTo);
console.log('=== change end ===');
},
confirm(e){
console.log('=== confirm start ===');
console.log("被拖动行: " + JSON.stringify(e.moveRow));
console.log('原始下标:',e.index);
console.log('移动到:',e.moveTo);
console.log('=== confirm end ===');
}
}
}
```
###更多的说明请下载示例运行查看,有示例对照注释更容易明白。
> * 遇到问题或有建议可以[加入QQ群(147157269)](https://jq.qq.com/?_wv=1027&k=jpdVnqxw)反馈
> * 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯!
####偷偷的打广告
定制模板开发uniapp、H5+APP、wap2app、PHP付费咨询指导有需要加QQ。
<table><tr><td bgcolor=#8f9396 >
<center><font color=#8f9396>QQ:565766672</font> <font color=#fff>(刮刮卡)</font></center>
</td></tr></table>

View File

@@ -0,0 +1,132 @@
<template>
<view @click="click" @touchcancel="touchcancel" @touchstart="touchstart" @touchend="touchend" :style="buttonStyle"
class="flex-row justify-center items-center">
<wrap-text :color="color" :size="size" :text="text" weight/>
</view>
</template>
<script>
import {
styleInto
} from '../../js/api'
import wrapText from '../wrap-text/wrap-text'
/**
* button 按钮
* @description 按钮组件
* @tutorial https://dnvue.dengqichang.cn/component/basic_component/n-button.html
* @property {Number, String} text 按钮名称
* @property {Number, String} size 名称大小
* @property {String} color 名称颜色
* @property {Number, String} width 宽度
* @property {Number, String} height 高度
* @property {String} background 背景颜色
* @property {String} disabled-background 禁用后背景颜色
* @property {String} gradient 渐变背景色使用方式right,#69c0ff,#1890ff方向,颜色值,颜色值)
* @property {Number, String} radius 圆角
* @property {Boolean} disabled 是否禁用
* @property {Boolean} is-icon 是否使用图标仅限内置图标库。当使用图标时text属性即为图标名称
* @event {Function()} click 点击事件
*/
export default {
name: "nButton",
components: {
wrapText
},
props: {
text: {
type: [Number, String], //文本
default: 'DNVUE'
},
size: {
type: [Number, String], //文本大小
default: 30
},
color: {
type: String, //文本颜色
default: 'white'
},
width: {
type: [Number, String], //宽度
default: 520
},
height: {
type: [Number, String], //高度
default: 80
},
background: {
type: String, //背景颜色
default: '#0a84ec'
},
disabledBackground: {
type: String, //禁用背景颜色
default: '#d9d9d9'
},
gradient: { //渐变背景色
type: String, //right,#69c0ff,#1890ff
default: ''
},
radius: {
type: [Number, String], //圆角
default: 8
},
disabled: {
type: Boolean, //禁用
default: false
},
isIcon: {
type: Boolean, //是否使用图标
default: false
}
},
data() {
return {
status: false
}
},
computed: {
buttonStyle() {
let style = {
background: this.disabled ? this.disabledBackground : this.background,
width: `${this.width}rpx`,
height: `${this.height}rpx`,
borderRadius: `${this.radius}rpx`,
opacity: this.status ? 0.8 : 1
};
if (this.gradient !== '' && !this.disabled) {
let gradient = this.gradient.split(',');
let gradientOne = gradient[1];
let gradientTwo = gradient[2];
style.backgroundImage = 'linear-gradient(to ' + gradient[0] + ',' + gradientOne + ',' + gradientTwo +
')'
};
return styleInto(style);
}
},
methods: {
//触摸开始,多点触控,后面的手指同样会触发
touchstart() {
if (!this.disabled) {
this.status = true;
}
},
//触摸结束,手指离开屏幕时
touchend() {
this.status = false;
},
//触摸被取消,当系统停止跟踪触摸的时候触发
touchcancel() {
this.status = false; //触摸被打断时回填按钮状态
},
//点击事件
click(e) {
if (!this.disabled) {
this.$emit("click", e)
}
}
}
}
</script>
<style>
@import "../../css/index.scss";
</style>

View File

@@ -0,0 +1,159 @@
<template>
<view class="z-index view">
<wrap-transition @click="onMask" :mode-class="['fade']" :style-custom="maskClass" :show="isShow">
</wrap-transition>
<wrap-transition @change="onChange" :mode-class="popupData[direction].modeClass"
:style-custom="popupData[direction].popupClass" :show="isShow">
<slot></slot>
</wrap-transition>
</view>
</template>
<script>
/**
* popup 弹出层
* @description 弹出层组件
* @tutorial https://dnvue.dengqichang.cn/component/feedback_component/n-popup.html
* @property {Boolean} show 控制显示或者隐藏
* @property {String} direction 弹出层方向
* @value top 顶部弹出
* @value bottom 底部弹出
* @value left 左侧弹出
* @value right 右侧弹出
* @value center 中间弹出
* @property {Boolean} mask-close 点击遮罩层是否可关闭
* @event {Function()} change 当打开或者关闭时返回弹出层状态
*/
import wrapTransition from './wrap-transition.nvue'
export default {
name: 'nPopup',
components: {
wrapTransition
},
props: {
show: {
type: Boolean, //控制显示或者隐藏
default: false
},
direction: {
type: String, //弹出层方向
default: "bottom"
},
maskClose: {
type: Boolean, //点击遮罩层是否可关闭
default: true
}
},
data() {
return {
isShow: false,
//遮罩层
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
popupData: {
top: {
modeClass: ['slide-top', 'fade'],
popupClass: {
'position': 'fixed',
'left': 0,
'right': 0,
'top': 0,
'backgroundColor': '#FFFFFF'
}
},
bottom: {
modeClass: ['slide-bottom', 'fade'],
popupClass: {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0,
'backgroundColor': '#FFFFFF'
}
},
left: {
modeClass: ['slide-left', 'fade'],
popupClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'backgroundColor': '#FFFFFF'
}
},
right: {
modeClass: ['slide-right', 'fade'],
popupClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'right': 0,
'backgroundColor': '#FFFFFF'
}
},
center: {
modeClass: ['fade', 'zoom-in'],
popupClass: {
'position': 'fixed',
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
}
}
};
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
this.close()
}
},
immediate: true
}
},
methods: {
//打开弹出层
open() {
this.isShow = true
},
//关闭弹出层
close(e) {
if (this.isShow) {
this.isShow = false
}
},
//点击关闭弹出层
onMask(e) {
console.log('点击了onMask', e)
if (this.maskClose) {
if (this.isShow) {
this.isShow = false
}
}
},
//当打开或者关闭返回信息
onChange(e) {
this.$emit("change", {
detail: e.detail
})
}
}
}
</script>
<style scoped>
@import "../../css/index.scss";
</style>

View File

@@ -0,0 +1,276 @@
<template>
<view style="display: flex;flex-direction: column;" v-if="isShow" ref="ani" class="view wrap-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
@click.stop="change" @click.stop.prevent @touchmove.stop.prevent>
<slot></slot>
</view>
</template>
<script>
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
/**
* Transition 过渡动画
* @description 简单过渡动画组件
* @tutorial
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
* @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
* @value fade 渐隐渐出过渡
* @value slide-top 由上至下过渡
* @value slide-right 由右至左过渡
* @value slide-bottom 由下至上过渡
* @value slide-left 由左至右过渡
* @value zoom-in 由小到大过渡
* @value zoom-out 由大到小过渡
* @property {Number} duration 过渡动画持续时间
* @property {Object} style-custom 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
*/
export default {
name: 'nTransition',
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: Array,
default () {
return []
}
},
duration: {
type: Number,
default: 300
},
styleCustom: {
type: Object,
default () {
return {}
}
}
},
data() {
return {
isShow: false,
transform: '',
ani: { in: '',
active: ''
}
};
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
this.close()
}
},
immediate: true
}
},
computed: {
stylesObject() {
let styles = {
...this.styleCustom,
'transition-duration': this.duration / 1000 + 's'
}
let transfrom = ''
for (let i in styles) {
let line = this.toLine(i)
transfrom += line + ':' + styles[i] + ';'
}
return transfrom
}
},
methods: {
change(event) {
// 阻止继续冒泡.
event.stopPropagation();
this.$emit('click', {
detail: this.isShow
})
},
open() {
clearTimeout(this.timer)
this.isShow = true
this.transform = ''
this.ani.in = ''
for (let i in this.getTranfrom(false)) {
if (i === 'opacity') {
this.ani.in = 'fade-in'
} else {
this.transform += `${this.getTranfrom(false)[i]} `
}
}
this.$nextTick(() => {
setTimeout(() => {
this._animation(true)
}, 50)
})
},
close(type) {
clearTimeout(this.timer)
this._animation(false)
},
_animation(type) {
let styles = this.getTranfrom(type)
// #ifdef APP-NVUE
if (!this.$refs['ani']) return
animation.transition(this.$refs['ani'].ref, {
styles,
duration: this.duration, //ms
timingFunction: 'ease',
needLayout: false,
delay: 0 //ms
}, () => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
});
})
// #endif
// #ifndef APP-NVUE
this.transform = ''
for (let i in styles) {
if (i === 'opacity') {
this.ani.in = `fade-${type?'out':'in'}`
} else {
this.transform += `${styles[i]} `
}
}
this.timer = setTimeout(() => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
})
}, this.duration)
// #endif
},
getTranfrom(type) {
let styles = {
transform: ''
}
this.modeClass.forEach((mode) => {
switch (mode) {
case 'fade':
styles.opacity = type ? 1 : 0
break;
case 'slide-top':
styles.transform += `translateY(${type?'0':'-100%'}) `
break;
case 'slide-right':
styles.transform += `translateX(${type?'0':'100%'}) `
break;
case 'slide-bottom':
styles.transform += `translateY(${type?'0':'100%'}) `
break;
case 'slide-left':
styles.transform += `translateX(${type?'0':'-100%'}) `
break;
case 'zoom-in':
styles.transform += `scale(${type?1:0.8}) `
break;
case 'zoom-out':
styles.transform += `scale(${type?1:1.2}) `
break;
}
})
return styles
},
_modeClassArr(type) {
let mode = this.modeClass
if (typeof(mode) !== "string") {
let modestr = ''
mode.forEach((item) => {
modestr += (item + '-' + type + ',')
})
return modestr.substr(0, modestr.length - 1)
} else {
return mode + '-' + type
}
},
toLine(name) {
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
}
}
}
</script>
<style scoped>
.view {
/* #ifndef APP-NVUE */
position: relative;
display: flex;
flex-direction: column;
/* #endif */
}
.wrap-transition {
transition-timing-function: ease;
transition-duration: 0.4s;
transition-property: transform, opacity;
}
.fade-in {
opacity: 0;
}
.fade-active {
opacity: 1;
}
.slide-top-in {
transform: translateY(-100%);
}
.slide-top-active {
transform: translateY(0);
}
.slide-right-in {
transform: translateX(100%);
}
.slide-right-active {
transform: translateX(0);
}
.slide-bottom-in {
transform: translateY(100%);
}
.slide-bottom-active {
transform: translateY(0);
}
.slide-left-in {
transform: translateX(-100%);
}
.slide-left-active {
transform: translateX(0);
opacity: 1;
}
.zoom-in-in {
transform: scale(0.8);
}
.zoom-out-active {
transform: scale(1);
}
.zoom-out-in {
transform: scale(1.2);
}
</style>

View File

@@ -0,0 +1,125 @@
<template>
<view>
<text @click="onClick" :style="textStyle">{{text}}</text>
</view>
</template>
<script>
import {styleInto} from '../../js/api'
/**
* text 文本
* @description 文本组件
* @tutorial https://dnvue.dengqichang.cn/component/basic_component/n-text.html
* @property {String, Number} text 文本内容
* @property {String, Number} size 字号(rpx)
* @property {String} color 文本颜色
* @property {String, Number} lines 超出行省略
* @property {String} align 文本位置
* @value left 左侧
* @value center 中间
* @value right 右侧
* @property {String, Number} leading 行高
* @property {Boolean} weight 文本加粗
* @property {String} decoration 文本修饰
* @value none 默认值,定义标准的文本。
* @value line-through 定义穿过文本下的一条线
* @value underline 定义文本下的一条线
* @property {String, Number} width 宽度
* @property {Object} style-custom 组件自定义样式,同 css 样式。注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
* @event {Function()} click 点击事件
*/
export default {
name: "nText",
props: {
text: {
type: [String, Number], //文本
default: ""
},
size: {
type: [String, Number], //字号(rpx)
default: 30
},
color: {
type: String, //文本颜色class
default: "#333333"
},
lines: {
type: [String, Number], //超出省略
default: ""
},
align: {
type: String, //文本位置
default: "left"
},
leading: {
type: [String, Number], //行高
default: ""
},
weight: {
type: Boolean, //文本加粗
default: false
},
decoration: {
type: String, //文本的修饰
default: "none"
},
width: {
type: [String, Number], //文本宽度
default: ""
},
styleCustom: {
type: Object, //组件自定义样式,同 css 样式。注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
default: function() {
return {}
}
}
},
computed: {
textStyle() {
let style = {
...this.styleCustom,
fontSize: `${this.size}rpx`,
textAlign: this.align,
fontWeight: this.weight ? 'bold' : 'normal',
textDecoration: this.decoration,
color: this.color
};
/* 超出省略 */
if (!!this.lines) {
let lines_temp = {
textOverflow: 'ellipsis',
lines: this.lines,
overflow: 'hidden',
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': this.lines
};
style = Object.assign(style, lines_temp);
};
/* 行高 */
if (!!this.leading) {
style.lineHeight = `${this.leading}rpx`
};
/* 宽度 */
if (this.width !== '') {
style.width = `${this.width}rpx`
};
return styleInto(style);
}
},
data() {
return {
};
},
methods: {
onClick(e) {
this.$emit("click", e)
}
}
}
</script>
<style>
</style>

Some files were not shown because too many files have changed in this diff Show More