From cb3bcb57bc17309c751755d690f33d89fd193bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=A3=E4=BA=9B=E8=8A=B1=E5=84=BF?= <1156921458@qq.com> Date: Fri, 25 Apr 2025 18:15:00 +0800 Subject: [PATCH] .. --- .../controller/ClientActivityController.java | 28 + .../service/ClientActivityService.java | 9 + .../impl/ClientActivityServiceImpl.java | 22 + frontend/index.html | 24 +- frontend/package-lock.json | 7 + frontend/package.json | 1 + frontend/src/components/scanQrCode.vue | 237 +++++++ frontend/src/main.js | 1 + .../src/pages/activity/scan-sign/index.vue | 658 ++++++------------ frontend/src/ssl/localhost+2-key.pem | 28 + frontend/src/ssl/localhost+2.pem | 26 + frontend/src/util/request.ts | 94 --- frontend/src/utils/wechat-sdk.js | 41 ++ frontend/vite.config.js | 9 +- 14 files changed, 624 insertions(+), 561 deletions(-) create mode 100644 frontend/src/components/scanQrCode.vue create mode 100644 frontend/src/ssl/localhost+2-key.pem create mode 100644 frontend/src/ssl/localhost+2.pem delete mode 100644 frontend/src/util/request.ts create mode 100644 frontend/src/utils/wechat-sdk.js diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java index 35b76e1..e062516 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java @@ -6,19 +6,24 @@ import com.budwk.app.base.page.Pagination; import com.budwk.app.base.result.Result; import com.budwk.app.client.module.activity.service.ClientActivityService; import com.budwk.app.client.module.activity.vo.ClientActivitySignVO; +import com.budwk.app.module.activity.models.ActUser; import com.budwk.app.module.activity.models.Activity; import com.budwk.app.web.commons.auth.satoken.StpClientUtil; import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; import org.nutz.mvc.adaptor.JsonAdaptor; import org.nutz.mvc.annotation.AdaptBy; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.GET; import org.nutz.mvc.annotation.Ok; +import java.util.List; + @IocBean @At("/client/activity") @Ok("json:full") @@ -26,6 +31,8 @@ public class ClientActivityController { @Inject private ClientActivityService clientActivityService; + @Inject + private Dao dao; @At @AdaptBy(type = JsonAdaptor.class) @@ -71,4 +78,25 @@ public class ClientActivityController { return Result.success(); } + /** + * 查询我报名的活动 + */ + @At("/list-mine-act") + @SaCheckLogin(type = StpClientUtil.TYPE) + public Result listMineAct() { + List list = clientActivityService.listMineAct(); + return Result.success(list); + } + + /** + * 查询报名签到信息 + */ + @At("/sign-info/?") + @SaCheckLogin(type = StpClientUtil.TYPE) + public Result signInfo(Long activityId) { + ActUser actUser = dao.fetch(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getUserId, "=", StpClientUtil.STP.getLoginIdAsLong())); + return Result.success(actUser); + } + + } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java index cd851a1..4e035fe 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java @@ -2,6 +2,15 @@ package com.budwk.app.client.module.activity.service; import com.budwk.app.base.service.BaseService; import com.budwk.app.module.activity.models.Activity; +import org.nutz.lang.util.NutMap; + +import java.util.List; public interface ClientActivityService extends BaseService { + + /** + * 查询我报名的活动 + */ + List listMineAct(); + } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java index 42df4b2..e52e04e 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java @@ -3,12 +3,34 @@ package com.budwk.app.client.module.activity.service.impl; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.client.module.activity.service.ClientActivityService; import com.budwk.app.module.activity.models.Activity; +import com.budwk.app.web.commons.auth.satoken.StpClientUtil; import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; + +import java.util.List; @IocBean(args = {"refer:dao"}) public class ClientActivityServiceImpl extends BaseServiceImpl implements ClientActivityService { public ClientActivityServiceImpl(Dao dao) { super(dao); } + + @Override + public List listMineAct() { + Sql sql = Sqls.create(""" + SELECT + id, + title, + cover + FROM + activity + WHERE + id IN (SELECT activityId FROM `act_user` WHERE userId = @userId) + """); + sql.setParam("userId", StpClientUtil.STP.getLoginIdAsLong()); + return listMap(sql); + } } diff --git a/frontend/index.html b/frontend/index.html index fb81ddc..5f63efc 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,20 +1,20 @@ - - + + - - -
- - + + +
+ + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 79eed9d..b4af3b2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,6 +24,7 @@ "@dcloudio/uni-mp-weixin": "3.0.0-4050720250324001", "@dcloudio/uni-mp-xhs": "3.0.0-4050720250324001", "@dcloudio/uni-quickapp-webview": "3.0.0-4050720250324001", + "html5-qrcode": "^2.3.8", "moment": "^2.30.1", "tdesign-mobile-vue": "^1.8.3", "vue": "^3.4.21", @@ -6952,6 +6953,12 @@ "license": "MIT", "peer": true }, + "node_modules/html5-qrcode": { + "version": "2.3.8", + "resolved": "https://registry.npmmirror.com/html5-qrcode/-/html5-qrcode-2.3.8.tgz", + "integrity": "sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==", + "license": "Apache-2.0" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 605e005..2f27d2f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -52,6 +52,7 @@ "@dcloudio/uni-mp-weixin": "3.0.0-4050720250324001", "@dcloudio/uni-mp-xhs": "3.0.0-4050720250324001", "@dcloudio/uni-quickapp-webview": "3.0.0-4050720250324001", + "html5-qrcode": "^2.3.8", "moment": "^2.30.1", "tdesign-mobile-vue": "^1.8.3", "vue": "^3.4.21", diff --git a/frontend/src/components/scanQrCode.vue b/frontend/src/components/scanQrCode.vue new file mode 100644 index 0000000..780f9c2 --- /dev/null +++ b/frontend/src/components/scanQrCode.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/frontend/src/main.js b/frontend/src/main.js index 348850e..4353083 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -13,6 +13,7 @@ import moment from 'moment'; import 'moment/dist/locale/zh-cn' moment.locale('zh-cn') + export function createApp() { const app = createSSRApp(App); app.use(TDesign); // 使用TDesign组件库 diff --git a/frontend/src/pages/activity/scan-sign/index.vue b/frontend/src/pages/activity/scan-sign/index.vue index 9395a18..40eb770 100644 --- a/frontend/src/pages/activity/scan-sign/index.vue +++ b/frontend/src/pages/activity/scan-sign/index.vue @@ -1,516 +1,268 @@ \ No newline at end of file + + diff --git a/frontend/src/ssl/localhost+2-key.pem b/frontend/src/ssl/localhost+2-key.pem new file mode 100644 index 0000000..9837698 --- /dev/null +++ b/frontend/src/ssl/localhost+2-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDuEcmyaW2QmhIB +6kTFYgcC9eoWHfZfgadJvl6sqLG4YKNiaBp6fXInvTecVSC4VGpggfXKfjTMlUaW +ZvtMV6i/gx+tP8LTH6lu5ht6sb9LcyO0bjJ+VZuyTeLbOPYiFGq2/Lxgl50wfr/E +BPBg3epQatxyegzbbkrWLS2ouA4sCOKrBhe+aUi8Vkp9Ny4SLAziwgGbkvL04zj3 +w7omQElSCPdcjG/+gDCCee9CdMVGmvPKvOJTob0frlndfpnwQR95he8pKVlDQjkg +sjQZV2vgGQugRBcOBJxx1kENDAEctmrgXvWHE1gUbgN0aMfAdd5ZnbAShzJuWURM +qBLZOQ55AgMBAAECggEBALo206tn57mZqcgxtEUoHg/kxosyOIoP4gg+jdNDyG9N +t767ayqwgOAwkxUHSSalcOe3/8e53BbCFIqEVsAqOOZD7D0ZiIyXUXJbLtdTvSuJ +Dj6Ni5Vh5P0dCvsqnOufSLGFEtwC+4L5QYpTyqoaKrNoQrKQYQoqRQMuJ263OO6b +KmUYd3fGThTeqKc6JGbExd33l6aYNxbX88x3h3oS4hq56owGkfpbouQFkQy1XK6E +DcJoGWv1QHHP51A6QKro6Vlo/BdeVvyv//gUzvOMJ0vMzaLnPSt6/Tdj/83zJAVw +P0JBGU/l2ZnV7EwR/OyCml4yX9zTVgqbX++hq0QZ9jkCgYEA88cJuFVxrR2Hx0u/ +Mv0lwaSzFyYh49ox/UAh8OhZZXfmZcwT70UIBw52RVguKrZLvUcPGBVT7UoJpslR +6ycwYiLbXZ9w+ZQPIvBp7BLl1SSFsgBy8rM93VwV20qNhVoS+qLU80OBvlhigFDc +RLE9ZXfM35jILVn8/JWlo12qcpsCgYEA+gF8XWlHKYroNrdnCwxZZm0BDfb+1DNG +/6r9mu4L+/b//n4jJ/oxZDGaOd6T8XL4pXpKeys5Q8TSbbPA44klF/ooGVd9J1jy +9gby0dYli/It0NyCU7vO3PT3FdY3KPKb53GLWXGB30B/OLL0K+R8Ff9yMtm2xoaL +jNicXVX02nsCgYEAk9TtCRMPx7qzv2EpBsPLZL37ORuPy7xjOj/tFUniBI2Mc8kp +gZ0sPBNCF9Vc0dwQ3Cy+c41jgu+2IKXPfroaNjkLLKBnA4MNFtQSd+4R4IqwZPyu +uI2IA7g3LO/uGKNCBSo/13HluUeiHExs919Aa0sWO7ZMFmyO5aHee85ucecCgYBA +43XWAOc5fxY6bWvPUEs77HrjlwIZLZ316fmc5sAxi7Bx62dQjv2W1dEDyCN5/a9P +s+f1BAj+7+z2EDu2UvhPutwBh9WyCsI03STVFdH0+sytcy5YcVyFuQcQoeL7O8z/ +S1cxxeZBfcoHe1sosUsLopuPWza3XGCIFAixqQe+VQKBgQDfLLRJwirg9DVv5PlY +A545KHWOnzJpvI9ZcUvcvC+QAzPbcdO+Lv3k6XHW3Gv4BWUv/uSsTFN41Ib+ZykB +SUICqRzwF1x8O0lXyBBDooN4nXCQt5YbsX/Y9VbOWTxiJ4Bf2SBn1myWryXz3CM+ +Fi9jIfi+oDYmJbmwGgTyMCCgOQ== +-----END PRIVATE KEY----- diff --git a/frontend/src/ssl/localhost+2.pem b/frontend/src/ssl/localhost+2.pem new file mode 100644 index 0000000..1442bff --- /dev/null +++ b/frontend/src/ssl/localhost+2.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIETzCCAregAwIBAgIQb5YGv6dOgj3XDOtlEmSMFTANBgkqhkiG9w0BAQsFADCB +gzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSwwKgYDVQQLDCNERVNL +VE9QLVNWSEk0MlRcanVnQERFU0tUT1AtU1ZISTQyVDEzMDEGA1UEAwwqbWtjZXJ0 +IERFU0tUT1AtU1ZISTQyVFxqdWdAREVTS1RPUC1TVkhJNDJUMB4XDTI1MDQyNTA3 +NDYzNVoXDTI3MDcyNTA3NDYzNVowVzEnMCUGA1UEChMebWtjZXJ0IGRldmVsb3Bt +ZW50IGNlcnRpZmljYXRlMSwwKgYDVQQLDCNERVNLVE9QLVNWSEk0MlRcanVnQERF +U0tUT1AtU1ZISTQyVDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO4R +ybJpbZCaEgHqRMViBwL16hYd9l+Bp0m+Xqyosbhgo2JoGnp9cie9N5xVILhUamCB +9cp+NMyVRpZm+0xXqL+DH60/wtMfqW7mG3qxv0tzI7RuMn5Vm7JN4ts49iIUarb8 +vGCXnTB+v8QE8GDd6lBq3HJ6DNtuStYtLai4DiwI4qsGF75pSLxWSn03LhIsDOLC +AZuS8vTjOPfDuiZASVII91yMb/6AMIJ570J0xUaa88q84lOhvR+uWd1+mfBBH3mF +7ykpWUNCOSCyNBlXa+AZC6BEFw4EnHHWQQ0MARy2auBe9YcTWBRuA3Rox8B13lmd +sBKHMm5ZREyoEtk5DnkCAwEAAaNqMGgwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFFy6asLfUTtAaZz1nLcl16XDDcjzMCAG +A1UdEQQZMBeCCWxvY2FsaG9zdIcEfwAAAYcEwKgpdjANBgkqhkiG9w0BAQsFAAOC +AYEAHgCaKoqdwjyMqVQKCrRCUo7nw7BcM5QtUs/CtRxG4PWWk15PaMDBlDRISng6 ++hEDI1ZhKnN3mpj/+xWY44Aqrj5QOgcIEkYF0Ny2k6pNFFHqd8Ma9T/9Pfdsdy5Q +29g2Rh4JW3qqna1yfEnhpudiJGmMcuc4+d4c+xQHLCtBMzURXaYYu6COptAvJf7A +JA6eUIf0IULfkyHejPM4NDnOaKd5KqhlofLAYl4bkhDD+d2b91g0rLj0PY5yF+yT +6V454hdiiXcOY334Fc1n7RWawlxhmvZOnNgFpHR+eUlfnDyhHR06YN+n2QUCZrtq +7bnKmttCi+RHNjDziB/w7Eju2PnLAstkY8i+ovS7+SzKvvKI8HvV4EpRxAntsFFt +xje0J0DTfePCZY9WsPJm4KwrV5g8uVsIdY4ayDbrvJJOyzvg+ne4VfdJjABQUgD3 +J+B9W9dMc/hk9WCopAMoLlitEdGS+PXAiPYSm73aytQqhbAMaxnwkuHKc4uPdFPF +CHmn +-----END CERTIFICATE----- diff --git a/frontend/src/util/request.ts b/frontend/src/util/request.ts deleted file mode 100644 index 9ae95c5..0000000 --- a/frontend/src/util/request.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { ref } from 'vue' - -// 基础配置 -// const BASE_URL = "http://192.168.41.118:9090/api" -const BASE_URL = "/api" - -export function useRequest() { - const loading = ref(false) - const error = ref(null) - - // 核心请求方法 - const sendRequest = (options: UniApp.RequestOptions): Promise => { - loading.value = true - error.value = null - - return new Promise((resolve, reject) => { - // 处理URL - const url = options.url.startsWith('http') - ? options.url - : `${BASE_URL}/${options.url.replace(/^\//, '')}` - - // 添加token - const token = uni.getStorageSync('token') - const headers = { - 'Content-Type': 'application/json', - 'X-Requested-With': 'XMLHttpRequest', - ...(token ? { 'Authorization': `Bearer ${token}` } : {}), - ...options.header - } - - uni.request({ - url, - method: options.method || 'GET', - data: options.data, - header: headers, - timeout: options.timeout || 10000, - success: (res) => { - if (res.statusCode >= 200 && res.statusCode < 300) { - if(res.data.code === 0){ - resolve(res.data as T) - }else if(res.data.code === 600098){ - // 未登录 - uni.removeStorageSync('token') - uni.reLaunch({ - url: '/pages/login/index' - }) - }else { - const err = new Error(res.data?.msg || '请求失败') - error.value = err - reject(err) - } - } else { - const err = new Error(res.data?.msg || '请求失败') - error.value = err - reject(err) - } - }, - fail: (err) => { - error.value = err - reject(err) - }, - complete: () => { - loading.value = false - } - }) - }) - } - - // GET请求 - const get = (url: string, params?: any) => { - return sendRequest({ - url, - method: 'GET', - data: params - }) - } - - // POST请求 - const post = (url: string, data?: any) => { - return sendRequest({ - url, - method: 'POST', - data - }) - } - - return { - loading, - error, - request: sendRequest, - get, - post - } -} diff --git a/frontend/src/utils/wechat-sdk.js b/frontend/src/utils/wechat-sdk.js new file mode 100644 index 0000000..ec19ed6 --- /dev/null +++ b/frontend/src/utils/wechat-sdk.js @@ -0,0 +1,41 @@ +export default { + // 初始化微信配置 + initWechatConfig: function(config) { + return new Promise((resolve, reject) => { + jWeixin.config({ + debug: false, // 开启调试模式 + appId: config.appId, + timestamp: config.timestamp, + nonceStr: config.nonceStr, + signature: config.signature, + jsApiList: ['scanQRCode'] // 需要使用的JS接口列表 + }); + + jWeixin.ready(() => { + resolve(); + }); + + jWeixin.error(err => { + reject(err); + }); + }); + }, + + // 调用微信扫一扫 + scanQRCode: function() { + return new Promise((resolve, reject) => { + jWeixin.scanQRCode({ + needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果 + scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有 + success: (res) => { + // 当needResult 为 1 时,扫码返回的结果 + const result = res.resultStr; + resolve(result); + }, + fail: (err) => { + reject(err); + } + }); + }); + } +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 12d1dfc..024962f 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -3,8 +3,9 @@ import uni from '@dcloudio/vite-plugin-uni' import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite'; import { TDesignResolver } from 'unplugin-vue-components/resolvers'; -import path from 'path'; +const path = require('path'); +const fs = require('fs'); // https://vitejs.dev/config/ export default defineConfig({ @@ -27,9 +28,13 @@ export default defineConfig({ } }, server: { + https: { + cert: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2.pem')), + key: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2-key.pem')) + }, proxy: { '/api': { - target: 'http://192.168.0.107:9090', + target: 'http://192.168.41.118:9090', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') }