diff --git a/app.json b/app.json
index 39a8bdd..a808d3c 100644
--- a/app.json
+++ b/app.json
@@ -22,7 +22,8 @@
"pages/order/index",
"pages/order/detail/index",
"pages/company/company",
- "pages/qrcode/index"
+ "pages/qrcode/index",
+ "pages/collection/index"
],
"subpackages": [
{
diff --git a/pages/collection/index.js b/pages/collection/index.js
new file mode 100644
index 0000000..3b8855c
--- /dev/null
+++ b/pages/collection/index.js
@@ -0,0 +1,343 @@
+// pages/collection/index.js
+const API = require('../../utils/api.js');
+
+Page({
+ data: {
+ qrCodes: [], // 二维码数据
+ invitees: [], // 邀请者列表
+ isAdmin: false, // 是否为管理员
+ activeFilter: 'all', // 当前激活的筛选条件
+ sidebarVisible: false, // 侧边栏是否可见
+ expandedIndex: -1, // 当前展开的二维码索引
+ searchKeyword: '' // 搜索关键词
+ },
+
+ onLoad: function (options) {
+ // 页面加载时的初始化逻辑
+ console.log('二维码合集页面加载,options:', options);
+
+ // 检查是否是通过内部按钮进入的
+ if (!options.from || options.from !== 'internal') {
+ console.log('非内部进入,重定向到首页');
+ wx.redirectTo({
+ url: '/pages/index/index'
+ });
+ return;
+ }
+
+ // 加载二维码合集
+ this.loadQrCollection();
+ },
+
+ onShow: function () {
+ // 页面显示时重新加载数据
+ this.loadQrCollection();
+ },
+
+ // 加载用户信息
+ loadUserInfo: function () {
+ return new Promise((resolve, reject) => {
+ // 从本地存储获取用户信息
+ const userInfo = wx.getStorageSync('userInfo') || {};
+ // 获取电话号码信息
+ const phoneNumber = userInfo.phoneNumber || wx.getStorageSync('phoneNumber') || '';
+
+ // 如果有电话号码,查询personnel表获取详细信息
+ if (phoneNumber) {
+ // 根据电话号码查询personnel表
+ API.request('/api/personnel/get', 'POST', { phone: phoneNumber }).then(res => {
+ console.log('查询personnel表结果:', res);
+ if (res && res.success && res.data && res.data.length > 0) {
+ const personnelInfo = res.data[0];
+ // 更新用户信息
+ const updatedUserInfo = {
+ name: personnelInfo.name || userInfo.name || userInfo.userName || '微信用户',
+ phoneNumber: phoneNumber,
+ projectName: personnelInfo.projectName || ''
+ };
+ // 存储到本地存储
+ wx.setStorageSync('userInfo', updatedUserInfo);
+ resolve(updatedUserInfo);
+ } else {
+ // 如果查询失败,使用本地存储的用户信息
+ const fallbackUserInfo = {
+ name: userInfo.name || userInfo.userName || '微信用户',
+ phoneNumber: phoneNumber,
+ projectName: userInfo.projectName || ''
+ };
+ resolve(fallbackUserInfo);
+ }
+ }).catch(err => {
+ console.error('查询personnel表失败:', err);
+ // 如果查询失败,使用本地存储的用户信息
+ const fallbackUserInfo = {
+ name: userInfo.name || userInfo.userName || '微信用户',
+ phoneNumber: phoneNumber,
+ projectName: userInfo.projectName || ''
+ };
+ resolve(fallbackUserInfo);
+ });
+ } else {
+ // 如果没有电话号码,使用本地存储的用户信息
+ const fallbackUserInfo = {
+ name: userInfo.name || userInfo.userName || '微信用户',
+ phoneNumber: phoneNumber,
+ projectName: userInfo.projectName || ''
+ };
+ resolve(fallbackUserInfo);
+ }
+ });
+ },
+
+ // 将UTC时间转换为北京时间
+ convertToBeijingTime: function (utcTime) {
+ if (!utcTime) return '未知';
+
+ // 创建Date对象
+ const date = new Date(utcTime);
+
+ // 转换为北京时间(UTC+8)
+ const beijingTime = new Date(date.getTime() + 8 * 60 * 60 * 1000);
+
+ // 格式化时间
+ const year = beijingTime.getFullYear();
+ const month = String(beijingTime.getMonth() + 1).padStart(2, '0');
+ const day = String(beijingTime.getDate()).padStart(2, '0');
+ const hours = String(beijingTime.getHours()).padStart(2, '0');
+ const minutes = String(beijingTime.getMinutes()).padStart(2, '0');
+ const seconds = String(beijingTime.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+ },
+
+ // 处理二维码数据,转换时间为北京时间
+ processQrCodes: function (qrCodes) {
+ return qrCodes.map(qrCode => {
+ const newQrCode = { ...qrCode };
+ // 转换创建时间
+ if (newQrCode.createdAt) {
+ newQrCode.createdAt = this.convertToBeijingTime(newQrCode.createdAt);
+ }
+ // 转换签发日期
+ if (newQrCode.issueDate) {
+ newQrCode.issueDate = this.convertToBeijingTime(newQrCode.issueDate);
+ }
+ return newQrCode;
+ });
+ },
+
+ // 加载二维码合集
+ loadQrCollection: function () {
+ this.loadUserInfo().then(user => {
+ try {
+ // 构建请求参数
+ let params = {};
+ if (user) {
+ params.userName = user.name;
+ params.phoneNumber = user.phoneNumber;
+ params.projectName = user.projectName;
+ }
+
+ console.log('加载二维码合集,用户信息:', user);
+
+ // 从服务器获取二维码合集
+ API.getQrCollection(params).then(res => {
+ console.log('获取二维码合集结果:', res);
+
+ if (res && res.success) {
+ // 动态生成筛选按钮
+ if (res.isAdmin && res.invitees && res.invitees.length > 0) {
+ this.setData({
+ isAdmin: res.isAdmin,
+ invitees: res.invitees
+ });
+ }
+
+ if (res.qrCodes && res.qrCodes.length > 0) {
+ // 处理二维码数据,转换时间为北京时间
+ const processedQrCodes = this.processQrCodes(res.qrCodes);
+
+ // 渲染二维码合集
+ this.setData({
+ qrCodes: processedQrCodes
+ });
+ } else {
+ // 显示空状态
+ this.setData({
+ qrCodes: []
+ });
+ }
+ } else {
+ // 显示错误状态
+ wx.showToast({
+ title: '加载失败,请稍后重试',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ }).catch(err => {
+ console.error('获取二维码合集失败:', err);
+ wx.showToast({
+ title: '加载失败,请稍后重试',
+ icon: 'none',
+ duration: 2000
+ });
+ });
+ } catch (error) {
+ console.error('获取二维码合集失败:', error);
+ wx.showToast({
+ title: '加载失败,请稍后重试',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+ });
+ },
+
+ // 打开筛选侧边栏
+ openSidebar: function () {
+ this.setData({
+ sidebarVisible: true
+ });
+ },
+
+ // 关闭筛选侧边栏
+ closeSidebar: function () {
+ this.setData({
+ sidebarVisible: false
+ });
+ },
+
+ // 切换展开/收起状态
+ toggleSection: function (e) {
+ const index = e.currentTarget.dataset.index;
+ this.setData({
+ expandedIndex: this.data.expandedIndex === index ? -1 : index
+ });
+ },
+
+ // 切换筛选条件
+ switchFilter: function (e) {
+ const filter = e.currentTarget.dataset.filter;
+ this.setData({
+ activeFilter: filter
+ });
+ this.filterQrCodes(filter, null, this.data.searchKeyword);
+ },
+
+ // 按邀请者筛选
+ filterByInviter: function (e) {
+ const filter = e.currentTarget.dataset.filter;
+ const inviterName = e.currentTarget.dataset.inviter;
+ this.setData({
+ activeFilter: filter
+ });
+ this.filterQrCodes(filter, inviterName, this.data.searchKeyword);
+ this.closeSidebar();
+ },
+
+ // 搜索输入事件
+ onSearchInput: function (e) {
+ const searchKeyword = e.detail.value;
+ this.setData({
+ searchKeyword: searchKeyword
+ });
+ this.filterQrCodes(this.data.activeFilter, null, searchKeyword);
+ },
+
+ // 筛选二维码
+ filterQrCodes: function (filter, inviterName, searchKeyword = '') {
+ this.loadUserInfo().then(user => {
+ // 构建请求参数
+ let params = {};
+ if (user) {
+ params.userName = user.name;
+ params.phoneNumber = user.phoneNumber;
+ params.projectName = user.projectName;
+ }
+
+ console.log('筛选二维码,用户信息:', user);
+
+ // 重新加载并筛选二维码
+ API.getQrCollection(params).then(res => {
+ if (res && res.success && res.qrCodes && res.qrCodes.length > 0) {
+ // 处理二维码数据,转换时间为北京时间
+ let filteredQrCodes = this.processQrCodes(res.qrCodes);
+
+ if (filter === 'me' && user) {
+ // 筛选当前用户自己的二维码
+ filteredQrCodes = filteredQrCodes.filter(qrCode =>
+ qrCode.inviter === user.name
+ );
+ } else if (filter.startsWith('invitee_') && inviterName) {
+ // 筛选特定邀请者的二维码
+ filteredQrCodes = filteredQrCodes.filter(qrCode =>
+ qrCode.inviter === inviterName
+ );
+ }
+
+ // 搜索功能
+ if (searchKeyword) {
+ const keyword = searchKeyword.toLowerCase();
+ filteredQrCodes = filteredQrCodes.filter(qrCode => {
+ return (
+ (qrCode.phoneNumber && qrCode.phoneNumber.toLowerCase().includes(keyword)) ||
+ (qrCode.company && qrCode.company.toLowerCase().includes(keyword))
+ );
+ });
+
+ // 添加高亮效果
+ filteredQrCodes = filteredQrCodes.map(qrCode => {
+ const newQrCode = { ...qrCode };
+ if (newQrCode.company && newQrCode.company.toLowerCase().includes(keyword)) {
+ const regex = new RegExp(`(${keyword})`, 'gi');
+ newQrCode.company = newQrCode.company.replace(regex, '$1');
+ }
+ if (newQrCode.phoneNumber && newQrCode.phoneNumber.toLowerCase().includes(keyword)) {
+ const regex = new RegExp(`(${keyword})`, 'gi');
+ newQrCode.phoneNumber = newQrCode.phoneNumber.replace(regex, '$1');
+ }
+ return newQrCode;
+ });
+ }
+
+ this.setData({
+ qrCodes: filteredQrCodes
+ });
+ }
+ }).catch(error => {
+ console.error('筛选二维码失败:', error);
+ });
+ });
+ },
+
+ // 返回上一页
+ goBack: function () {
+ wx.navigateBack({
+ delta: 1
+ });
+ },
+
+ // 跳转到生成邀请二维码页面
+ goToGenerate: function () {
+ wx.redirectTo({
+ url: '/pages/qrcode/index?from=internal'
+ });
+ },
+
+ // 图片加载成功事件
+ onImageLoad: function () {
+ console.log('二维码图片加载成功');
+ },
+
+ // 图片加载失败事件
+ onImageError: function (e) {
+ console.error('二维码图片加载失败:', e);
+ wx.showToast({
+ title: '二维码图片加载失败',
+ icon: 'none',
+ duration: 2000
+ });
+ }
+
+});
\ No newline at end of file
diff --git a/pages/collection/index.json b/pages/collection/index.json
new file mode 100644
index 0000000..0727ad9
--- /dev/null
+++ b/pages/collection/index.json
@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "二维码合集",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black",
+ "enablePullDownRefresh": true
+}
\ No newline at end of file
diff --git a/pages/collection/index.wxml b/pages/collection/index.wxml
new file mode 100644
index 0000000..34508aa
--- /dev/null
+++ b/pages/collection/index.wxml
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ 全部
+
+
+ 我的
+
+
+
+
+
+
+ 🔍
+ 筛选
+
+
+
+
+
+
+
+
+ 暂无二维码
+ 请先生成邀请二维码
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.inviter || '未知'}}
+
+
+ {{item.inviterProjectName || '无职位'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/collection/index.wxss b/pages/collection/index.wxss
new file mode 100644
index 0000000..c501c07
--- /dev/null
+++ b/pages/collection/index.wxss
@@ -0,0 +1,434 @@
+/* pages/collection/index.wxss */
+
+/* 页面容器 */
+.page-container {
+ width: 100%;
+ background-color: #f5f5f5;
+ min-height: 100vh;
+ box-sizing: border-box;
+}
+
+/* 筛选和搜索栏 */
+.filter-bar {
+ display: flex;
+ align-items: center;
+ padding: 16rpx;
+ background-color: #f0f9f0;
+ border-bottom: 1rpx solid #d4edda;
+ box-sizing: border-box;
+ position: sticky;
+ top: 0;
+ z-index: 900;
+ flex-wrap: wrap;
+ gap: 12rpx;
+ min-height: 100rpx;
+ overflow-x: hidden;
+}
+
+.filter-tabs {
+ display: flex;
+ gap: 8rpx;
+ flex-shrink: 0;
+}
+
+.filter-tab {
+ padding: 6rpx 12rpx;
+ border-radius: 16rpx;
+ background-color: #f0f0f0;
+ font-size: 22rpx;
+ color: #666;
+ transition: all 0.3s;
+ white-space: nowrap;
+}
+
+.filter-tab.active {
+ background-color: #4CAF50;
+ color: white;
+}
+
+.search-container {
+ flex: 1;
+ min-width: 150rpx;
+ position: relative;
+ margin: 0 8rpx;
+ flex-basis: 0;
+ max-width: 400rpx;
+}
+
+.search-input {
+ width: 100%;
+ flex: 1;
+ padding: 16rpx 20rpx;
+ border: 1rpx solid #e0e0e0;
+ border-radius: 12rpx;
+ font-size: 28rpx;
+ box-sizing: border-box;
+ background-color: #f9f9f9;
+ min-height: 70rpx;
+}
+
+.search-input:focus {
+ border-color: #4CAF50;
+ background-color: #ffffff;
+ box-shadow: 0 0 0 2rpx rgba(76, 175, 80, 0.1);
+}
+
+/* 高亮效果 */
+.highlight {
+ background-color: #FFF3CD;
+ color: #856404;
+ padding: 0 4rpx;
+ border-radius: 4rpx;
+ font-weight: 500;
+}
+
+.filter-button {
+ display: flex;
+ align-items: center;
+ gap: 6rpx;
+ padding: 12rpx 16rpx;
+ background-color: #4CAF50;
+ color: white;
+ border-radius: 10rpx;
+ font-size: 24rpx;
+ flex-shrink: 0;
+ min-height: 60rpx;
+ white-space: nowrap;
+}
+
+.filter-icon {
+ font-size: 24rpx;
+}
+
+.filter-text {
+ font-size: 22rpx;
+}
+
+/* 二维码列表 */
+.qr-list {
+ padding: 16rpx;
+ box-sizing: border-box;
+}
+
+/* 空状态 */
+.empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 100rpx 0;
+ color: #999;
+ text-align: center;
+}
+
+.empty-image {
+ width: 120rpx;
+ height: 120rpx;
+ margin-bottom: 24rpx;
+ opacity: 0.5;
+}
+
+.empty-text {
+ font-size: 28rpx;
+ margin-bottom: 8rpx;
+ color: #666;
+}
+
+.empty-subtext {
+ font-size: 24rpx;
+ color: #999;
+}
+
+/* 二维码项 */
+.qr-item {
+ background-color: white;
+ border-radius: 12rpx;
+ margin-bottom: 16rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
+ overflow: hidden;
+}
+
+.qr-item-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 16rpx;
+ cursor: pointer;
+}
+
+.qr-item-info {
+ flex: 1;
+ overflow: hidden;
+}
+
+.qr-item-info rich-text {
+ display: block;
+ font-size: 28rpx;
+ font-weight: 500;
+ color: #333;
+ margin-bottom: 8rpx;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.qr-item-details {
+ display: flex;
+ align-items: center;
+ font-size: 24rpx;
+ color: #666;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.qr-item-details rich-text {
+ display: inline;
+ font-size: 24rpx;
+ color: #666;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.qr-item-details text {
+ margin-left: 8rpx;
+ font-size: 24rpx;
+ color: #666;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.qr-item-arrow {
+ font-size: 24rpx;
+ color: #999;
+ margin-left: 16rpx;
+ flex-shrink: 0;
+}
+
+/* 二维码详情 */
+.qr-item-content {
+ padding: 0 16rpx 16rpx;
+ border-top: 1rpx solid #f0f0f0;
+ animation: slideDown 0.3s ease;
+}
+
+@keyframes slideDown {
+ from {
+ opacity: 0;
+ transform: translateY(-10rpx);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.qr-image {
+ width: 200rpx;
+ height: 200rpx;
+ margin: 16rpx auto;
+ display: block;
+ border-radius: 8rpx;
+}
+
+.qr-info-center {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 16rpx;
+}
+
+.qr-info-item {
+ margin-bottom: 8rpx;
+ font-size: 24rpx;
+ color: #333;
+ text-align: center;
+ width: 100%;
+ max-width: 200rpx;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* 底部按钮 */
+.bottom-section {
+ padding: 20rpx 16rpx;
+ background-color: white;
+ border-top: 1rpx solid #e0e0e0;
+ margin-top: 20rpx;
+}
+
+.generate-button {
+ width: 100%;
+ height: 80rpx;
+ background-color: #4CAF50;
+ color: white;
+ border: none;
+ border-radius: 12rpx;
+ font-size: 28rpx;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.generate-button-text {
+ color: white;
+ font-size: 28rpx;
+}
+
+/* 筛选侧边栏 */
+.sidebar {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2000;
+ display: flex;
+ flex-direction: column;
+}
+
+.sidebar-overlay {
+ flex: 1;
+ background-color: rgba(0, 0, 0, 0.5);
+}
+
+.sidebar-content {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ width: 70%;
+ max-width: 300rpx;
+ background-color: white;
+ box-shadow: -4rpx 0 10rpx rgba(0, 0, 0, 0.1);
+ animation: slideIn 0.3s ease;
+}
+
+@keyframes slideIn {
+ from {
+ transform: translateX(100%);
+ }
+ to {
+ transform: translateX(0);
+ }
+}
+
+.sidebar-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 20rpx;
+ border-bottom: 1rpx solid #e0e0e0;
+}
+
+.sidebar-title {
+ font-size: 28rpx;
+ font-weight: 600;
+ color: #333;
+}
+
+.sidebar-close {
+ font-size: 32rpx;
+ color: #999;
+ cursor: pointer;
+}
+
+.sidebar-body {
+ padding: 20rpx;
+ max-height: calc(100% - 80rpx);
+ overflow-y: auto;
+}
+
+.sidebar-item {
+ padding: 16rpx 0;
+ border-bottom: 1rpx solid #f0f0f0;
+ cursor: pointer;
+}
+
+.sidebar-item:last-child {
+ border-bottom: none;
+}
+
+.sidebar-item-text {
+ font-size: 24rpx;
+ color: #333;
+}
+
+/* 响应式调整 */
+@media (max-width: 375px) {
+ .filter-bar {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .filter-tabs {
+ justify-content: center;
+ }
+
+ .search-container {
+ min-width: 100%;
+ margin: 8rpx 0;
+ }
+
+ .filter-button {
+ align-self: center;
+ }
+}
+
+/* 针对中等屏幕的调整 */
+@media (min-width: 376px) and (max-width: 480px) {
+ .filter-bar {
+ flex-wrap: nowrap;
+ }
+
+ .filter-tabs {
+ flex-shrink: 0;
+ }
+
+ .search-container {
+ flex: 1;
+ min-width: 150rpx;
+ max-width: 300rpx;
+ }
+
+ .filter-button {
+ flex-shrink: 0;
+ }
+}
+
+/* 针对大屏幕的调整 */
+@media (min-width: 481px) {
+ .filter-bar {
+ flex-wrap: nowrap;
+ }
+
+ .search-container {
+ flex: 1;
+ min-width: 200rpx;
+ max-width: 400rpx;
+ }
+}
+
+/* 滚动条样式 */
+::-webkit-scrollbar {
+ width: 4rpx;
+ height: 4rpx;
+}
+
+::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 2rpx;
+}
+
+::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 2rpx;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index c14ba81..d9ffe1e 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -215,8 +215,8 @@
我们
- 📱
- 二维码
+ 📜
+ 合格证
diff --git a/pages/qrcode/index.js b/pages/qrcode/index.js
index 2f7de38..c7f8042 100644
--- a/pages/qrcode/index.js
+++ b/pages/qrcode/index.js
@@ -296,6 +296,13 @@ Page({
});
}
});
+ },
+
+ // 跳转到二维码合集页面
+ goToQrCollection: function () {
+ wx.redirectTo({
+ url: '/pages/collection/index?from=internal'
+ });
}
});
\ No newline at end of file
diff --git a/pages/qrcode/index.wxml b/pages/qrcode/index.wxml
index 92743b3..9ae1bbf 100644
--- a/pages/qrcode/index.wxml
+++ b/pages/qrcode/index.wxml
@@ -52,6 +52,7 @@
+