diff --git a/components/qrcode-modal/qrcode-modal.js b/components/qrcode-modal/qrcode-modal.js
new file mode 100644
index 0000000..46324fc
--- /dev/null
+++ b/components/qrcode-modal/qrcode-modal.js
@@ -0,0 +1,48 @@
+const drawQrcode = require('../../utils/weapp.qrcode.esm.js').default
+
+Component({
+ properties: {
+ visible: {
+ type: Boolean,
+ value: false
+ },
+ qrcodeId: {
+ type: String,
+ value: ''
+ }
+ },
+
+ data: {
+ loading: true
+ },
+
+ observers: {
+ 'visible'(val) {
+ if (val && this.data.qrcodeId) {
+ this.setData({ loading: true })
+ this.draw()
+ }
+ }
+ },
+
+ methods: {
+ draw() {
+ wx.nextTick(() => {
+ drawQrcode({
+ width: 200,
+ height: 200,
+ canvasId: 'qrcodeCanvas',
+ _this: this,
+ text: this.data.qrcodeId,
+ callback: () => {
+ this.setData({ loading: false })
+ }
+ })
+ })
+ },
+
+ onClose() {
+ this.triggerEvent('close')
+ }
+ }
+})
diff --git a/components/qrcode-modal/qrcode-modal.json b/components/qrcode-modal/qrcode-modal.json
new file mode 100644
index 0000000..a89ef4d
--- /dev/null
+++ b/components/qrcode-modal/qrcode-modal.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
diff --git a/components/qrcode-modal/qrcode-modal.wxml b/components/qrcode-modal/qrcode-modal.wxml
new file mode 100644
index 0000000..e6a9fea
--- /dev/null
+++ b/components/qrcode-modal/qrcode-modal.wxml
@@ -0,0 +1,13 @@
+
+
+ 预约凭证
+
+
+
+
+
+
+ {{qrcodeId}}
+ 请向工作人员出示此二维码
+
+
diff --git a/components/qrcode-modal/qrcode-modal.wxss b/components/qrcode-modal/qrcode-modal.wxss
new file mode 100644
index 0000000..c032e64
--- /dev/null
+++ b/components/qrcode-modal/qrcode-modal.wxss
@@ -0,0 +1,79 @@
+.qrcode-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 100;
+}
+
+.qrcode-container {
+ background: #fff;
+ border-radius: 24rpx;
+ padding: 48rpx 64rpx;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.qrcode-title {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: #1a1a1a;
+ margin-bottom: 32rpx;
+}
+
+.qrcode-canvas-wrap {
+ position: relative;
+ width: 400rpx;
+ height: 400rpx;
+}
+
+.qrcode-canvas {
+ width: 400rpx;
+ height: 400rpx;
+}
+
+.qrcode-loading {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #fff;
+}
+
+.qrcode-spinner {
+ width: 48rpx;
+ height: 48rpx;
+ border: 4rpx solid #e0e0e0;
+ border-top: 4rpx solid #1890ff;
+ border-radius: 50%;
+ animation: qrcode-spin 0.8s linear infinite;
+}
+
+@keyframes qrcode-spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+.qrcode-id {
+ font-size: 24rpx;
+ color: #999;
+ margin-top: 24rpx;
+ word-break: break-all;
+ text-align: center;
+}
+
+.qrcode-tip {
+ font-size: 24rpx;
+ color: #bbb;
+ margin-top: 12rpx;
+}
diff --git a/pages/index/index.js b/pages/index/index.js
index 6a68aa2..53bfd37 100644
--- a/pages/index/index.js
+++ b/pages/index/index.js
@@ -6,7 +6,9 @@ Page({
data: {
isLoggedIn: false,
loginFailed: false,
- latestRecord: null
+ latestRecord: null,
+ qrcodeVisible: false,
+ qrcodeId: ''
},
onLoad() {
@@ -77,5 +79,14 @@ Page({
wx.navigateTo({
url: '/pages/records/records'
})
+ },
+
+ showQrcode(e) {
+ const id = e.currentTarget.dataset.id
+ this.setData({ qrcodeVisible: true, qrcodeId: id })
+ },
+
+ hideQrcode() {
+ this.setData({ qrcodeVisible: false, qrcodeId: '' })
}
})
diff --git a/pages/index/index.json b/pages/index/index.json
index e02c929..fa87f54 100644
--- a/pages/index/index.json
+++ b/pages/index/index.json
@@ -1,4 +1,6 @@
{
- "usingComponents": {},
+ "usingComponents": {
+ "qrcode-modal": "/components/qrcode-modal/qrcode-modal"
+ },
"navigationBarTitleText": "访客预约系统"
}
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index cbdb92e..d969a16 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -45,8 +45,14 @@
@@ -75,4 +81,7 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/index.wxss b/pages/index/index.wxss
index ae325c5..9cebe70 100644
--- a/pages/index/index.wxss
+++ b/pages/index/index.wxss
@@ -177,6 +177,25 @@ page {
border-bottom: 1rpx solid #f0f0f0;
}
+.latest-header-right {
+ display: flex;
+ align-items: center;
+ gap: 12rpx;
+}
+
+.qrcode-btn {
+ font-size: 22rpx;
+ color: #52c41a;
+ background: rgba(82, 196, 26, 0.1);
+ padding: 6rpx 20rpx;
+ border-radius: 20rpx;
+ border: 1rpx solid rgba(82, 196, 26, 0.3);
+}
+
+.qrcode-btn:active {
+ background: rgba(82, 196, 26, 0.2);
+}
+
.latest-title {
font-size: 28rpx;
font-weight: 600;
@@ -188,6 +207,7 @@ page {
padding: 4rpx 16rpx;
border-radius: 16rpx;
font-weight: 500;
+ margin-left: auto;
}
.status-pending {
@@ -251,3 +271,5 @@ page {
font-size: 24rpx;
color: #ccc;
}
+
+
diff --git a/pages/records/records.js b/pages/records/records.js
index a72e451..601c8f1 100644
--- a/pages/records/records.js
+++ b/pages/records/records.js
@@ -7,7 +7,9 @@ Page({
records: [],
filteredRecords: [],
currentTab: 'all',
- loading: true
+ loading: true,
+ qrcodeVisible: false,
+ qrcodeId: ''
},
onLoad() {
@@ -81,5 +83,14 @@ Page({
wx.navigateTo({
url: '/pages/appointment/appointment'
})
+ },
+
+ showQrcode(e) {
+ const id = e.currentTarget.dataset.id
+ this.setData({ qrcodeVisible: true, qrcodeId: id })
+ },
+
+ hideQrcode() {
+ this.setData({ qrcodeVisible: false, qrcodeId: '' })
}
})
diff --git a/pages/records/records.json b/pages/records/records.json
index 7bc86a0..d8828ef 100644
--- a/pages/records/records.json
+++ b/pages/records/records.json
@@ -1,4 +1,6 @@
{
- "usingComponents": {},
+ "usingComponents": {
+ "qrcode-modal": "/components/qrcode-modal/qrcode-modal"
+ },
"navigationBarTitleText": "预约记录"
}
diff --git a/pages/records/records.wxml b/pages/records/records.wxml
index aa4f52f..2252350 100644
--- a/pages/records/records.wxml
+++ b/pages/records/records.wxml
@@ -23,7 +23,9 @@
+
+
+
diff --git a/pages/records/records.wxss b/pages/records/records.wxss
index 3e6afc7..dfb246c 100644
--- a/pages/records/records.wxss
+++ b/pages/records/records.wxss
@@ -72,11 +72,25 @@ page {
color: #999;
}
+.qrcode-btn {
+ font-size: 24rpx;
+ color: #52c41a;
+ background: rgba(82, 196, 26, 0.1);
+ padding: 8rpx 24rpx;
+ border-radius: 24rpx;
+ border: 1rpx solid rgba(82, 196, 26, 0.3);
+}
+
+.qrcode-btn:active {
+ background: rgba(82, 196, 26, 0.2);
+}
+
.status-tag {
font-size: 24rpx;
padding: 6rpx 20rpx;
border-radius: 20rpx;
font-weight: 500;
+ margin-left: auto;
}
.status-pending {
@@ -172,3 +186,5 @@ page {
.empty-btn:active {
background: #096dd9;
}
+
+
diff --git a/utils/config.js b/utils/config.js
index 169fcd7..16954f3 100644
--- a/utils/config.js
+++ b/utils/config.js
@@ -6,7 +6,7 @@ const ENV_CONFIG = {
// release: 'https://xcx.yun.588580.xyz',
trial: 'https://qywx.yun.588580.xyz',
// 开发版 & 体验版
- develop: 'https://qywx.yun.588580.xyz'
+ develop: 'http://172.16.60.235:8080'
}
// 自动判断当前运行环境
diff --git a/utils/weapp.qrcode.esm.js b/utils/weapp.qrcode.esm.js
new file mode 100644
index 0000000..5613f25
--- /dev/null
+++ b/utils/weapp.qrcode.esm.js
@@ -0,0 +1,5 @@
+/**
+ * weapp.qrcode.js v1.0.0 (https://github.com/yingye/weapp-qrcode#readme)
+ */
+
+var hasOwn=Object.prototype.hasOwnProperty,toStr=Object.prototype.toString,defineProperty=Object.defineProperty,gOPD=Object.getOwnPropertyDescriptor,isArray=function(t){return"function"==typeof Array.isArray?Array.isArray(t):"[object Array]"===toStr.call(t)},isPlainObject=function(t){if(!t||"[object Object]"!==toStr.call(t))return!1;var e,r=hasOwn.call(t,"constructor"),o=t.constructor&&t.constructor.prototype&&hasOwn.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!r&&!o)return!1;for(e in t);return void 0===e||hasOwn.call(t,e)},setProperty=function(t,e){defineProperty&&"__proto__"===e.name?defineProperty(t,e.name,{enumerable:!0,configurable:!0,value:e.newValue,writable:!0}):t[e.name]=e.newValue},getProperty=function(t,e){if("__proto__"===e){if(!hasOwn.call(t,e))return;if(gOPD)return gOPD(t,e).value}return t[e]},extend=function t(){var e,r,o,n,i,a,s=arguments[0],u=1,l=arguments.length,h=!1;for("boolean"==typeof s&&(h=s,s=arguments[1]||{},u=2),(null==s||"object"!=typeof s&&"function"!=typeof s)&&(s={});u=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,e)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var o=-1;o<=7;o++)e+o<=-1||this.moduleCount<=e+o||(this.modules[t+r][e+o]=0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=QRUtil.getLostPoint(this);(0==r||t>o)&&(t=o,e=r)}return e},createMovieClip:function(t,e,r){var o=t.createEmptyMovieClip(e,r);this.make();for(var n=0;n>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(r=0;r<18;r++){o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=QRUtil.getBCHTypeInfo(r),n=0;n<15;n++){var i=!t&&1==(o>>n&1);n<6?this.modules[n][8]=i:n<8?this.modules[n+1][8]=i:this.modules[this.moduleCount-15+n][8]=i}for(n=0;n<15;n++){i=!t&&1==(o>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=i:n<9?this.modules[8][15-n-1+1]=i:this.modules[8][15-n-1]=i}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,n=7,i=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var s=0;s<2;s++)if(null==this.modules[o][a-s]){var u=!1;i>>n&1)),QRUtil.getMask(e,o,a-s)&&(u=!u),this.modules[o][a-s]=u,-1==--n&&(i++,n=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},QRCode.PAD0=236,QRCode.PAD1=17,QRCode.createData=function(t,e,r){for(var o=QRRSBlock.getRSBlocks(t,e),n=new QRBitBuffer,i=0;i8*s)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*s+")");for(n.getLengthInBits()+4<=8*s&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*s||(n.put(QRCode.PAD0,8),n.getLengthInBits()>=8*s));)n.put(QRCode.PAD1,8);return QRCode.createBytes(n,o)},QRCode.createBytes=function(t,e){for(var r=0,o=0,n=0,i=new Array(e.length),a=new Array(e.length),s=0;s=0?g.get(c):0}}var d=0;for(h=0;h=0;)e^=QRUtil.G15<=0;)e^=QRUtil.G18<>>=1;return e},getPatternPosition:function(t){return QRUtil.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case QRMaskPattern.PATTERN000:return(e+r)%2==0;case QRMaskPattern.PATTERN001:return e%2==0;case QRMaskPattern.PATTERN010:return r%3==0;case QRMaskPattern.PATTERN011:return(e+r)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case QRMaskPattern.PATTERN101:return e*r%2+e*r%3==0;case QRMaskPattern.PATTERN110:return(e*r%2+e*r%3)%2==0;case QRMaskPattern.PATTERN111:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new QRPolynomial([1],0),r=0;r5&&(r+=3+i-5)}for(o=0;o=256;)t-=255;return QRMath.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},i=0;i<8;i++)QRMath.EXP_TABLE[i]=1<=1&&n<=127?e+=t.charAt(r):n>2047?(e+=String.fromCharCode(224|n>>12&15),e+=String.fromCharCode(128|n>>6&63),e+=String.fromCharCode(128|n>>0&63)):(e+=String.fromCharCode(192|n>>6&31),e+=String.fromCharCode(128|n>>0&63));return e}function drawQrcode(t){t=t||{},(t=extend(!0,{width:256,height:256,x:0,y:0,typeNumber:-1,correctLevel:QRErrorCorrectLevel.H,background:"#ffffff",foreground:"#000000",image:{imageResource:"",dx:0,dy:0,dWidth:100,dHeight:100}},t)).canvasId||t.ctx?function(){var e,r=new QRCode(t.typeNumber,t.correctLevel);r.addData(utf16to8(t.text)),r.make(),e=t.ctx?t.ctx:t._this?wx.createCanvasContext&&wx.createCanvasContext(t.canvasId,t._this):wx.createCanvasContext&&wx.createCanvasContext(t.canvasId);for(var o=t.width/r.getModuleCount(),n=t.height/r.getModuleCount(),i=0;i>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};export default drawQrcode;