From af8cab142a6b15c06e131a8474574dd5b00df982 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 04 十二月 2025 22:09:58 +0800
Subject: [PATCH] feat: 改造微信accesstoken存放在系统配置表中
---
sql/wechat_subscribe_message_config_README.md | 167 ++++++++++++++++++
ruoyi-admin/src/main/resources/application.yml | 2
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PaymentSyncServiceImpl.java | 1
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java | 77 ++------
sql/wechat_subscribe_message_config.sql | 18 ++
ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatAccessTokenService.java | 27 +++
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java | 2
app/pagesTask/components/StaffSelector.vue | 17 +
app/pagesTask/edit-emergency.vue | 59 +++++-
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskAttachmentController.java | 12
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatAccessTokenServiceImpl.java | 123 +++++++++++++
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wechat/WechatController.java | 11
app/pagesTask/detail.vue | 8
13 files changed, 440 insertions(+), 84 deletions(-)
diff --git a/app/pagesTask/components/StaffSelector.vue b/app/pagesTask/components/StaffSelector.vue
index 9f750ed..972aae1 100644
--- a/app/pagesTask/components/StaffSelector.vue
+++ b/app/pagesTask/components/StaffSelector.vue
@@ -5,7 +5,7 @@
<view class="staff-list">
<view class="staff-item" v-for="(staff, index) in selectedStaff" :key="staff.userId">
<view class="staff-info">
- <text class="staff-name">{{ staff.nickName }}</text>
+ <text class="staff-name">{{ getStaffDisplayName(staff) }}</text>
</view>
<uni-icons
v-if="canRemove(index)"
@@ -454,6 +454,21 @@
emitChange() {
this.$emit('input', this.selectedStaff)
this.$emit('change', this.selectedStaff)
+ },
+
+ // 鑾峰彇浜哄憳鏄剧ず鍚嶇О锛堜紭鍏堟樉绀哄鍚嶏紝濡傛灉濮撳悕涓虹┖鍒欐樉绀烘墜鏈哄彿锛�
+ getStaffDisplayName(staff) {
+ if (!staff) {
+ return '鏈煡浜哄憳'
+ }
+ // 浼樺厛鏄剧ず nickName锛屽鏋滀负绌哄垯鏄剧ず鎵嬫満鍙凤紝閮戒负绌哄垯鏄剧ず userId
+ if (staff.nickName && staff.nickName.trim()) {
+ return staff.nickName
+ }
+ if (staff.phonenumber && staff.phonenumber.trim()) {
+ return staff.phonenumber
+ }
+ return `鐢ㄦ埛${staff.userId || ''}`
}
}
}
diff --git a/app/pagesTask/detail.vue b/app/pagesTask/detail.vue
index 0e96658..bffcfea 100644
--- a/app/pagesTask/detail.vue
+++ b/app/pagesTask/detail.vue
@@ -804,6 +804,14 @@
// 妫�鏌ヨ溅杈嗙姸鎬佸苟鍑哄彂
checkVehicleAndDepart() {
+ // 妫�鏌ュ嚭鍙戞椂闂存槸鍚︿负绌烘垨1900骞达紙淇锛氶槻姝㈡棤鏁堟椂闂达級
+ if (!this.taskDetail.plannedStartTime || this.taskDetail.plannedStartTime.startsWith('1900')) {
+ this.$modal.confirm('浠诲姟鐨勮浆杩愭椂闂存湭璁剧疆鎴栨棤鏁堬紝闇�瑕佸厛淇敼浠诲姟琛ュ厖杞繍鏃堕棿鍚庢墠鑳藉嚭鍙戙�傛槸鍚︾幇鍦ㄥ幓淇敼锛�').then(() => {
+ this.handleEdit()
+ }).catch(() => {})
+ return
+ }
+
// 鑾峰彇浠诲姟杞﹁締ID
const vehicleId = this.getVehicleId();
if (!vehicleId) {
diff --git a/app/pagesTask/edit-emergency.vue b/app/pagesTask/edit-emergency.vue
index cb0d7dc..eefd5df 100644
--- a/app/pagesTask/edit-emergency.vue
+++ b/app/pagesTask/edit-emergency.vue
@@ -19,7 +19,8 @@
/>
<view class="form-item">
- <OrganizationSelector
+ <OrganizationSelector
+ ref="organizationSelector"
v-model="selectedOrganizationId"
:required="true"
:auto-select-user-dept="false"
@@ -53,6 +54,7 @@
:required="false"
:auto-add-current-user="false"
:current-user-removable="true"
+ :branch-dept-ids="allOrganizationIds"
@change="onStaffChange"
/>
@@ -224,6 +226,7 @@
taskDetail: null,
selectedVehicleId: null,
selectedOrganizationId: null,
+ allOrganizationIds: [], // 鎵�鏈夊彲閫夋満鏋処D鏁扮粍
selectedRegion: '',
mapSelectorType: '',
// 鎵╁睍 addressCoordinates 鏀寔澶氱閿悕
@@ -292,6 +295,11 @@
}, 1500)
}
},
+
+ mounted() {
+ // 椤甸潰鎸傝浇鍚庡姞杞芥墍鏈夋満鏋処D
+ this.loadAllOrganizationIds()
+ },
methods: {
// 鍔犺浇浠诲姟璇︽儏
loadTaskDetail() {
@@ -320,8 +328,9 @@
const info = this.taskDetail.emergencyInfo
console.log('杞繍浠诲姟淇℃伅:', info)
- // 杞繍鏃堕棿
- this.taskForm.transferTime = this.taskDetail.plannedStartTime || ''
+ // 杞繍鏃堕棿锛堜慨澶嶏細1900骞寸殑鏃ユ湡鏄剧ず涓虹┖锛�
+ const transferTime = this.taskDetail.plannedStartTime || ''
+ this.taskForm.transferTime = transferTime && transferTime.startsWith('1900') ? '' : transferTime
// 鎮h�呬俊鎭�
this.taskForm.patient.contact = info.patientContact || ''
@@ -376,7 +385,8 @@
} else {
console.warn('浠诲姟璇︽儏涓病鏈塭mergencyInfo瀛楁锛屽皾璇曚粠涓诲璞¤幏鍙栨暟鎹�')
// 鍏煎澶勭悊锛氬鏋渆mergencyInfo涓嶅瓨鍦紝灏濊瘯浠庝富瀵硅薄鑾峰彇
- this.taskForm.transferTime = this.taskDetail.plannedStartTime || ''
+ const transferTime = this.taskDetail.plannedStartTime || ''
+ this.taskForm.transferTime = transferTime && transferTime.startsWith('1900') ? '' : transferTime
this.taskForm.transferDistance = this.taskDetail.estimatedDistance ? String(this.taskDetail.estimatedDistance) : ''
}
@@ -421,16 +431,24 @@
console.log('璁剧疆鐩爣鍦板潗鏍�:', this.taskDetail.destinationLongitude, this.taskDetail.destinationLatitude)
}
- // 璁剧疆鎵ц浜哄憳锛堜慨澶嶏細纭繚 assignees 涓嶄负 null锛�
+ // 璁剧疆鎵ц浜哄憳锛堜慨澶嶏細纭繚 assignees 涓嶄负 null锛屽苟姝g‘鏄犲皠瀛楁锛�
if (this.taskDetail.assignees && Array.isArray(this.taskDetail.assignees) && this.taskDetail.assignees.length > 0) {
console.log('鍘熷鎵ц浜哄憳鏁版嵁:', this.taskDetail.assignees)
- this.selectedStaff = this.taskDetail.assignees.map(assignee => ({
- userId: assignee.userId,
- nickName: assignee.userName,
- type: assignee.userType || 'driver',
- phonenumber: '',
- deptName: ''
- }))
+ this.selectedStaff = this.taskDetail.assignees.map(assignee => {
+ console.log('澶勭悊鎵ц浜哄憳:', assignee)
+ console.log(' - userName:', assignee.userName)
+ console.log(' - nickName:', assignee.nickName)
+ console.log(' - phonenumber:', assignee.phonenumber)
+ console.log(' - phone:', assignee.phone)
+
+ return {
+ userId: assignee.userId,
+ nickName: assignee.userName || assignee.nickName || '',
+ type: assignee.userType || 'driver',
+ phonenumber: assignee.phonenumber || assignee.phone || '',
+ deptName: assignee.deptName || ''
+ }
+ })
console.log('澶勭悊鍚庣殑鎵ц浜哄憳鍒楄〃:', this.selectedStaff)
} else {
console.warn('浠诲姟娌℃湁鍒嗛厤鎵ц浜哄憳鎴朼ssignees涓虹┖')
@@ -455,6 +473,23 @@
console.log('閫変腑杞﹁締:', vehicle)
},
+ // 鍔犺浇鎵�鏈夋満鏋処D
+ loadAllOrganizationIds() {
+ // 閫氳繃 OrganizationSelector 缁勪欢鑾峰彇鎵�鏈夋満鏋�
+ const orgSelector = this.$refs.organizationSelector
+ if (orgSelector) {
+ orgSelector.reload().then(organizations => {
+ this.allOrganizationIds = organizations.map(org => org.deptId)
+ console.log('鎵�鏈夋満鏋処D:', this.allOrganizationIds)
+ })
+ } else {
+ // 濡傛灉缁勪欢杩樻湭鎸傝浇,绋嶅悗閲嶈瘯
+ setTimeout(() => {
+ this.loadAllOrganizationIds()
+ }, 100)
+ }
+ },
+
// 褰掑睘鏈烘瀯閫夋嫨鍙樺寲
onOrganizationChange(orgData) {
// orgData 鍖呭惈锛歞eptId, deptName, serviceOrderClass, region, departureAddress, departureLongitude, departureLatitude
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskAttachmentController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskAttachmentController.java
index 0480114..d9545fe 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskAttachmentController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskAttachmentController.java
@@ -14,6 +14,7 @@
import com.ruoyi.system.service.ISysTaskEmergencyService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ITaskAttachmentSyncService;
+import com.ruoyi.system.service.IWechatAccessTokenService;
import com.ruoyi.system.task.ITaskAttachmentService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@@ -62,6 +63,9 @@
@Autowired
private ISysUserService userService;
+
+ @Autowired
+ private IWechatAccessTokenService wechatAccessTokenService;
/**
* 鏌ヨ浠诲姟闄勪欢鍒楄〃
*/
@@ -135,6 +139,7 @@
/**
* 浠庡井淇ediaId涓婁紶闄勪欢锛堝井淇″皬绋嬪簭涓撶敤锛�
+ * 浣跨敤搴旂敤绾х紦瀛樼殑AccessToken
*/
@Log(title = "浠诲姟闄勪欢", businessType = BusinessType.INSERT)
@PostMapping("/uploadFromWechat/{taskId}")
@@ -142,11 +147,8 @@
@RequestParam("mediaId") String mediaId,
@RequestParam(value = "category", required = false) String category) {
try {
- // 鑾峰彇寰俊AccessToken
- String accessToken = WechatUtils.getAccessToken(
- wechatConfig.getAppId(),
- wechatConfig.getAppSecret()
- );
+ // 鑾峰彇寰俊AccessToken锛堜娇鐢ㄥ簲鐢ㄧ骇缂撳瓨锛�
+ String accessToken = wechatAccessTokenService.getAppAccessToken();
if (accessToken == null || accessToken.isEmpty()) {
return error("鑾峰彇寰俊AccessToken澶辫触");
}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wechat/WechatController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wechat/WechatController.java
index 82258c3..91796b1 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wechat/WechatController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wechat/WechatController.java
@@ -20,6 +20,7 @@
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.service.IWechatTaskNotifyService;
+import com.ruoyi.system.service.IWechatAccessTokenService;
import java.util.ArrayList;
import java.util.HashMap;
@@ -49,17 +50,17 @@
@Autowired
private IWechatTaskNotifyService wechatTaskNotifyService;
+
+ @Autowired
+ private IWechatAccessTokenService wechatAccessTokenService;
/**
- * 鑾峰彇寰俊AccessToken
+ * 鑾峰彇寰俊AccessToken锛堜娇鐢ㄥ簲鐢ㄧ骇缂撳瓨锛�
*/
@GetMapping("/accessToken")
public AjaxResult getAccessToken() {
try {
- String accessToken = WechatUtils.getAccessToken(
- wechatConfig.getAppId(),
- wechatConfig.getAppSecret()
- );
+ String accessToken = wechatAccessTokenService.getAppAccessToken();
if (accessToken == null || accessToken.isEmpty()) {
return error("鑾峰彇寰俊AccessToken澶辫触");
}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 8ab857f..b039b84 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -58,7 +58,7 @@
basename: i18n/messages
profiles:
# 鐜 dev|test|prod
- active: dev
+ active: prod
# 鏂囦欢涓婁紶
servlet:
multipart:
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatAccessTokenService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatAccessTokenService.java
new file mode 100644
index 0000000..0abe1c4
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatAccessTokenService.java
@@ -0,0 +1,27 @@
+package com.ruoyi.system.service;
+
+/**
+ * 寰俊AccessToken鏈嶅姟鎺ュ彛
+ * 鎻愪緵搴旂敤绾ccessToken鐨勭粺涓�绠$悊锛屼娇鐢╯ys_config琛ㄧ紦瀛�
+ *
+ * @author ruoyi
+ * @date 2025-12-04
+ */
+public interface IWechatAccessTokenService {
+
+ /**
+ * 鑾峰彇搴旂敤绾у井淇ccessToken锛堝甫缂撳瓨锛�
+ * 浼樺厛浠巗ys_config璇诲彇骞跺垽鏂湁鏁堟湡锛涜繃鏈熷垯閲嶆柊鑾峰彇骞跺啓鍥瀞ys_config
+ *
+ * @return Access Token锛屽け璐ヨ繑鍥瀗ull
+ */
+ String getAppAccessToken();
+
+ /**
+ * 寮哄埗鍒锋柊AccessToken
+ * 蹇界暐缂撳瓨锛岀洿鎺ヤ粠寰俊鑾峰彇鏂癟oken骞舵洿鏂扮紦瀛�
+ *
+ * @return 鏂扮殑Access Token锛屽け璐ヨ繑鍥瀗ull
+ */
+ String refreshAppAccessToken();
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
index e764723..c2b98b1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -672,7 +672,7 @@
if (sysUser != null) {
TaskCreateVO.AssigneeInfo assigneeInfo = new TaskCreateVO.AssigneeInfo();
assigneeInfo.setUserId(sysUser.getUserId()); // 浣跨敤绯荤粺鐢ㄦ埛ID
- assigneeInfo.setUserName(sysUser.getUserName());
+ assigneeInfo.setUserName(sysUser.getNickName());
// 鏍规嵁EntourageState纭畾瑙掕壊绫诲瀷
// 1,2 鍙告満锛�3,5 鍖荤敓锛�4,6 鎶ゅ+
if ("1".equals(entourageState) || "2".equals(entourageState)) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PaymentSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PaymentSyncServiceImpl.java
index 2a8e338..ca8b487 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PaymentSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PaymentSyncServiceImpl.java
@@ -73,7 +73,6 @@
* 灏嗘柊绯荤粺鏀粯璁板綍鍚屾鍒版棫绯荤粺PaidMoney琛�
*/
@Override
- @Transactional
public boolean syncPaymentToLegacy(SysTaskPayment payment) {
Long paymentId = payment.getId();
try {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatAccessTokenServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatAccessTokenServiceImpl.java
new file mode 100644
index 0000000..2d43bdb
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatAccessTokenServiceImpl.java
@@ -0,0 +1,123 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.common.config.WechatConfig;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.WechatUtils;
+import com.ruoyi.system.domain.SysConfig;
+import com.ruoyi.system.mapper.SysConfigMapper;
+import com.ruoyi.system.service.ISysConfigService;
+import com.ruoyi.system.service.IWechatAccessTokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 寰俊AccessToken鏈嶅姟瀹炵幇
+ * 鎻愪緵搴旂敤绾ccessToken鐨勭粺涓�绠$悊锛屼娇鐢╯ys_config琛ㄧ紦瀛�
+ *
+ * @author ruoyi
+ * @date 2025-12-04
+ */
+@Service
+public class WechatAccessTokenServiceImpl implements IWechatAccessTokenService {
+
+ private static final Logger log = LoggerFactory.getLogger(WechatAccessTokenServiceImpl.class);
+
+ @Autowired
+ private WechatConfig wechatConfig;
+
+ @Autowired
+ private ISysConfigService configService;
+
+ @Autowired
+ private SysConfigMapper configMapper;
+
+ /**
+ * 鑾峰彇搴旂敤绾у井淇ccessToken锛堝甫缂撳瓨锛�
+ * 浼樺厛浠巗ys_config璇诲彇骞跺垽鏂湁鏁堟湡锛涜繃鏈熷垯閲嶆柊鑾峰彇骞跺啓鍥瀞ys_config
+ */
+ @Override
+ public String getAppAccessToken() {
+ try {
+ String appId = wechatConfig.getAppId();
+ String tokenKey = "weixin.access_token." + appId;
+ String expireKey = "weixin.access_token_expires." + appId;
+
+ String cachedToken = configService.selectConfigByKey(tokenKey);
+ String cachedExpireStr = configService.selectConfigByKey(expireKey);
+ long now = System.currentTimeMillis();
+ long expireTs = 0L;
+ if (StringUtils.isNotEmpty(cachedExpireStr)) {
+ try {
+ expireTs = Long.parseLong(cachedExpireStr);
+ } catch (NumberFormatException e) {
+ expireTs = 0L;
+ }
+ }
+
+ // 缂撳瓨鏈夋晥涓旀湭杩囨湡锛堥鐣�60绉掑畨鍏ㄨ竟鐣岋級
+ if (StringUtils.isNotEmpty(cachedToken) && expireTs > now + 60000L) {
+ log.debug("浣跨敤缂撳瓨鐨凙ccessToken锛屽墿浣欐湁鏁堟湡锛歿}绉�", (expireTs - now) / 1000);
+ return cachedToken;
+ }
+
+ // 閲嶆柊鑾峰彇锛屽苟鍐欏叆sys_config
+ log.info("AccessToken宸茶繃鏈熸垨涓嶅瓨鍦紝閲嶆柊鑾峰彇");
+ return refreshAppAccessToken();
+ } catch (Exception e) {
+ log.error("鑾峰彇搴旂敤绾у井淇ccessToken澶辫触", e);
+ return null;
+ }
+ }
+
+ /**
+ * 寮哄埗鍒锋柊AccessToken
+ * 蹇界暐缂撳瓨锛岀洿鎺ヤ粠寰俊鑾峰彇鏂癟oken骞舵洿鏂扮紦瀛�
+ */
+ @Override
+ public String refreshAppAccessToken() {
+ try {
+ String appId = wechatConfig.getAppId();
+ String appSecret = wechatConfig.getAppSecret();
+ String tokenKey = "weixin.access_token." + appId;
+ String expireKey = "weixin.access_token_expires." + appId;
+
+ String newToken = WechatUtils.getAccessToken(appId, appSecret);
+ if (StringUtils.isEmpty(newToken)) {
+ log.error("浠庡井淇¤幏鍙朅ccessToken澶辫触");
+ return null;
+ }
+
+ long now = System.currentTimeMillis();
+ long newExpireTs = now + 7200L * 1000L; // 7200绉�
+
+ upsertConfig(tokenKey, newToken);
+ upsertConfig(expireKey, String.valueOf(newExpireTs));
+
+ log.info("AccessToken鍒锋柊鎴愬姛锛屾湁鏁堟湡锛�7200绉�");
+ return newToken;
+ } catch (Exception e) {
+ log.error("鍒锋柊搴旂敤绾у井淇ccessToken澶辫触", e);
+ return null;
+ }
+ }
+
+ /**
+ * 鏍规嵁configKey鍐欏叆鎴栨洿鏂皊ys_config
+ */
+ private void upsertConfig(String key, String value) {
+ SysConfig exist = configMapper.checkConfigKeyUnique(key);
+ if (exist != null && exist.getConfigId() != null) {
+ exist.setConfigValue(value);
+ configMapper.updateConfig(exist);
+ } else {
+ SysConfig cfg = new SysConfig();
+ cfg.setConfigKey(key);
+ cfg.setConfigName(key);
+ cfg.setConfigValue(value);
+ cfg.setConfigType("Y"); // 鍐呯疆鍙傛暟
+ configMapper.insertConfig(cfg);
+ }
+ }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java
index 6b91981..5b7273a 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java
@@ -13,9 +13,8 @@
import com.ruoyi.system.domain.SysTaskEmergency;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IWechatTaskNotifyService;
+import com.ruoyi.system.service.IWechatAccessTokenService;
import com.ruoyi.system.service.ISysConfigService;
-import com.ruoyi.system.mapper.SysConfigMapper;
-import com.ruoyi.system.domain.SysConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -50,69 +49,26 @@
private WechatConfig wechatConfig;
@Autowired
- private ISysConfigService configService;
+ private IWechatAccessTokenService wechatAccessTokenService;
@Autowired
- private SysConfigMapper configMapper;
+ private ISysConfigService configService;
+
+
/**
- * 鑾峰彇搴旂敤绾у井淇ccessToken锛堝甫缂撳瓨锛�
- * 浼樺厛浠巗ys_config璇诲彇骞跺垽鏂湁鏁堟湡锛涜繃鏈熷垯閲嶆柊鑾峰彇骞跺啓鍥瀞ys_config
+ * 妫�鏌ユ槸鍚﹀惎鐢ㄨ闃呮秷鎭彂閫�
+ *
+ * @return true=鍚敤锛宖alse=绂佺敤
*/
- private String getAppAccessToken() {
+ private boolean isSubscribeMessageEnabled() {
try {
- String appId = wechatConfig.getAppId();
- String tokenKey = "weixin.access_token." + appId;
- String expireKey = "weixin.access_token_expires." + appId;
-
- String cachedToken = configService.selectConfigByKey(tokenKey);
- String cachedExpireStr = configService.selectConfigByKey(expireKey);
- long now = System.currentTimeMillis();
- long expireTs = 0L;
- if (StringUtils.isNotEmpty(cachedExpireStr)) {
- try {
- expireTs = Long.parseLong(cachedExpireStr);
- } catch (NumberFormatException e) {
- expireTs = 0L;
- }
- }
-
- // 缂撳瓨鏈夋晥涓旀湭杩囨湡锛堥鐣�60绉掑畨鍏ㄨ竟鐣岋級
- if (StringUtils.isNotEmpty(cachedToken) && expireTs > now + 60000L) {
- return cachedToken;
- }
-
- // 閲嶆柊鑾峰彇锛屽苟鍐欏叆sys_config
- String newToken = WechatUtils.getAccessToken(wechatConfig.getAppId(), wechatConfig.getAppSecret());
- if (StringUtils.isEmpty(newToken)) {
- return null;
- }
- long newExpireTs = now + 7200L * 1000L; // 7200绉�
- upsertConfig(tokenKey, newToken);
- upsertConfig(expireKey, String.valueOf(newExpireTs));
- return newToken;
+ String enabled = configService.selectConfigByKey("wechat.subscribe.message.enabled");
+ return "true".equalsIgnoreCase(enabled);
} catch (Exception e) {
- log.error("鑾峰彇搴旂敤绾у井淇ccessToken澶辫触", e);
- return null;
- }
- }
-
- /**
- * 鏍规嵁configKey鍐欏叆鎴栨洿鏂皊ys_config
- */
- private void upsertConfig(String key, String value) {
- SysConfig exist = configMapper.checkConfigKeyUnique(key);
- if (exist != null && exist.getConfigId() != null) {
- exist.setConfigValue(value);
- configMapper.updateConfig(exist);
- } else {
- SysConfig cfg = new SysConfig();
- cfg.setConfigKey(key);
- cfg.setConfigName(key);
- cfg.setConfigValue(value);
- cfg.setConfigType("Y"); // 鍐呯疆鍙傛暟
- configMapper.insertConfig(cfg);
+ log.warn("鑾峰彇璁㈤槄娑堟伅寮�鍏抽厤缃け璐ワ紝榛樿鍚敤", e);
+ return true; // 榛樿鍚敤
}
}
@@ -126,6 +82,11 @@
*/
@Override
public int sendTaskNotifyMessage(Long taskId, List<Long> userIds, Long excludeUserId) {
+ // 妫�鏌ヨ闃呮秷鎭紑鍏�
+ if (!isSubscribeMessageEnabled()) {
+ log.info("璁㈤槄娑堟伅鍙戦�佸凡鍏抽棴锛岃烦杩囧彂閫侊紝taskId={}", taskId);
+ return 0;
+ }
if (taskId == null || userIds == null || userIds.isEmpty()) {
log.warn("鍙戦�佸井淇′换鍔¢�氱煡鍙傛暟涓嶅畬鏁达紝taskId={}, userIds={}", taskId, userIds);
return 0;
@@ -142,7 +103,7 @@
SysTaskEmergency emergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
// 鑾峰彇寰俊AccessToken锛堣蛋搴旂敤绾х紦瀛橈級
- String accessToken = getAppAccessToken();
+ String accessToken = wechatAccessTokenService.getAppAccessToken();
if (StringUtils.isEmpty(accessToken)) {
log.error("鑾峰彇寰俊AccessToken澶辫触锛屾棤娉曞彂閫佷换鍔¢�氱煡");
return 0;
diff --git a/sql/wechat_subscribe_message_config.sql b/sql/wechat_subscribe_message_config.sql
new file mode 100644
index 0000000..0785aaa
--- /dev/null
+++ b/sql/wechat_subscribe_message_config.sql
@@ -0,0 +1,18 @@
+-- 寰俊璁㈤槄娑堟伅鍙戦�佸紑鍏抽厤缃�
+-- 鐢ㄤ簬鎺у埗绯荤粺鏄惁鍚敤寰俊璁㈤槄娑堟伅鎺ㄩ�佸姛鑳�
+
+-- 鎻掑叆璁㈤槄娑堟伅寮�鍏抽厤缃紙榛樿寮�鍚級
+INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark)
+VALUES
+('寰俊璁㈤槄娑堟伅寮�鍏�', 'wechat.subscribe.message.enabled', 'true', 'N', 'admin', NOW(), 'admin', NOW(),
+ '鎺у埗鏄惁鍚敤寰俊璁㈤槄娑堟伅鎺ㄩ�佸姛鑳姐�倀rue=鍚敤锛宖alse=绂佺敤銆傚叧闂悗绯荤粺灏嗕笉鍐嶅彂閫佷换浣曡闃呮秷鎭��');
+
+-- 璇存槑锛�
+-- 1. wechat.subscribe.message.enabled 鎺у埗鍏ㄥ眬璁㈤槄娑堟伅鍙戦�佸紑鍏�
+-- 2. 璁剧疆涓� true 鏃讹紝绯荤粺姝e父鍙戦�佽闃呮秷鎭�
+-- 3. 璁剧疆涓� false 鏃讹紝鎵�鏈夎闃呮秷鎭彂閫佸皢琚烦杩�
+-- 4. 閫傜敤鍦烘櫙锛�
+-- - 鐢熶骇鐜涓存椂鍏抽棴娑堟伅鎺ㄩ��
+-- - 娴嬭瘯鐜閬垮厤璇彂娑堟伅
+-- - 绯荤粺缁存姢鏈熼棿鏆傚仠閫氱煡
+-- 5. 鍙湪绯荤粺绠$悊->鍙傛暟璁剧疆涓姩鎬佷慨鏀癸紝鏃犻渶閲嶅惎鏈嶅姟
diff --git a/sql/wechat_subscribe_message_config_README.md b/sql/wechat_subscribe_message_config_README.md
new file mode 100644
index 0000000..9982a96
--- /dev/null
+++ b/sql/wechat_subscribe_message_config_README.md
@@ -0,0 +1,167 @@
+# 寰俊璁㈤槄娑堟伅寮�鍏充娇鐢ㄨ鏄�
+
+## 涓�銆侀厤缃」璇存槑
+
+### 閰嶇疆閿細`wechat.subscribe.message.enabled`
+
+| 灞炴�� | 鍊� |
+|------|-----|
+| 閰嶇疆鍚嶇О | 寰俊璁㈤槄娑堟伅寮�鍏� |
+| 閰嶇疆閿� | wechat.subscribe.message.enabled |
+| 閰嶇疆绫诲瀷 | N (鏅�氬弬鏁�) |
+| 榛樿鍊� | true |
+| 鍙�夊�� | true / false |
+
+### 閰嶇疆璇存槑
+
+- **true**: 鍚敤寰俊璁㈤槄娑堟伅鎺ㄩ�侊紙榛樿锛�
+- **false**: 绂佺敤寰俊璁㈤槄娑堟伅鎺ㄩ��
+
+## 浜屻�丼QL鑴氭湰
+
+鎵ц浠ヤ笅SQL鑴氭湰娣诲姞閰嶇疆锛�
+
+```sql
+INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, update_by, update_time, remark)
+VALUES
+('寰俊璁㈤槄娑堟伅寮�鍏�', 'wechat.subscribe.message.enabled', 'true', 'N', 'admin', NOW(), 'admin', NOW(),
+ '鎺у埗鏄惁鍚敤寰俊璁㈤槄娑堟伅鎺ㄩ�佸姛鑳姐�倀rue=鍚敤锛宖alse=绂佺敤銆傚叧闂悗绯荤粺灏嗕笉鍐嶅彂閫佷换浣曡闃呮秷鎭��');
+```
+
+## 涓夈�佸姛鑳借鏄�
+
+### 1. 寮�鍏虫帶鍒惰寖鍥�
+
+璇ュ紑鍏虫帶鍒朵互涓嬪満鏅殑璁㈤槄娑堟伅鍙戦�侊細
+
+- 鉁� 鏂颁换鍔″垱寤烘椂閫氱煡鎵ц浜�
+- 鉁� 浠诲姟鏇存柊鏃堕�氱煡鐩稿叧浜哄憳
+- 鉁� 鏃х郴缁熷悓姝ヤ换鍔℃椂鐨勯�氱煡
+- 鉁� 鎵嬪姩瑙﹀彂鐨勪换鍔¢�氱煡
+- 鉁� 鎵�鏈夐�氳繃 `IWechatTaskNotifyService` 鍙戦�佺殑娑堟伅
+
+### 2. 寮�鍏冲叧闂悗鐨勮〃鐜�
+
+褰撳紑鍏宠缃负 `false` 鏃讹細
+- 绯荤粺灏嗚烦杩囨墍鏈夎闃呮秷鎭彂閫�
+- 鏃ュ織璁板綍锛歚璁㈤槄娑堟伅鍙戦�佸凡鍏抽棴锛岃烦杩囧彂閫侊紝taskId=xxx`
+- 涓嶅奖鍝嶅叾浠栦笟鍔¢�昏緫
+- 杩斿洖鍊间负 0锛堝彂閫佹垚鍔熸暟閲忎负0锛�
+
+### 3. 寮傚父澶勭悊
+
+- 濡傛灉閰嶇疆璇诲彇澶辫触锛岄粯璁や负 **鍚敤** 鐘舵��
+- 纭繚绯荤粺姝e父杩愯锛岄伩鍏嶅洜閰嶇疆寮傚父瀵艰嚧鍔熻兘涓柇
+
+## 鍥涖�佷娇鐢ㄥ満鏅�
+
+### 1. 娴嬭瘯鐜
+
+鍦ㄦ祴璇曠幆澧冧腑鍏抽棴娑堟伅鎺ㄩ�侊紝閬垮厤娴嬭瘯鏁版嵁瑙﹀彂鐪熷疄娑堟伅锛�
+
+```sql
+UPDATE sys_config
+SET config_value = 'false'
+WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+### 2. 鐢熶骇缁存姢
+
+鍦ㄧ郴缁熺淮鎶ゆ湡闂翠复鏃跺叧闂秷鎭帹閫侊細
+
+```sql
+-- 鍏抽棴娑堟伅鎺ㄩ��
+UPDATE sys_config
+SET config_value = 'false'
+WHERE config_key = 'wechat.subscribe.message.enabled';
+
+-- 缁存姢瀹屾垚鍚庢仮澶�
+UPDATE sys_config
+SET config_value = 'true'
+WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+### 3. 鏁呴殰鎺掓煡
+
+褰撳井淇℃帴鍙e紓甯告椂锛屼复鏃跺叧闂秷鎭帹閫侊紝閬垮厤澶ч噺閿欒鏃ュ織锛�
+
+```sql
+UPDATE sys_config
+SET config_value = 'false'
+WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+## 浜斻�佺鐞嗙晫闈㈡搷浣�
+
+### 閫氳繃鍚庡彴绠$悊鐣岄潰淇敼
+
+1. 鐧诲綍绯荤粺绠$悊鍚庡彴
+2. 杩涘叆 **绯荤粺绠$悊 > 鍙傛暟璁剧疆**
+3. 鎼滅储 **寰俊璁㈤槄娑堟伅寮�鍏�**
+4. 淇敼鍙傛暟鍊间负 `true` 鎴� `false`
+5. 淇濆瓨鍚� **绔嬪嵆鐢熸晥**锛屾棤闇�閲嶅惎鏈嶅姟
+
+## 鍏�佹妧鏈疄鐜�
+
+### 浠g爜浣嶇疆
+
+- **閰嶇疆SQL**: `/sql/wechat_subscribe_message_config.sql`
+- **鏈嶅姟瀹炵幇**: `/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatTaskNotifyServiceImpl.java`
+
+### 鏍稿績浠g爜
+
+```java
+/**
+ * 妫�鏌ユ槸鍚﹀惎鐢ㄨ闃呮秷鎭彂閫�
+ */
+private boolean isSubscribeMessageEnabled() {
+ try {
+ String enabled = configService.selectConfigByKey("wechat.subscribe.message.enabled");
+ return "true".equalsIgnoreCase(enabled);
+ } catch (Exception e) {
+ log.warn("鑾峰彇璁㈤槄娑堟伅寮�鍏抽厤缃け璐ワ紝榛樿鍚敤", e);
+ return true; // 榛樿鍚敤
+ }
+}
+```
+
+## 涓冦�佹敞鎰忎簨椤�
+
+1. 鈿狅笍 淇敼閰嶇疆鍚庣珛鍗崇敓鏁堬紝鏃犻渶閲嶅惎鏈嶅姟
+2. 鈿狅笍 鍏抽棴寮�鍏充細褰卞搷鎵�鏈夎闃呮秷鎭彂閫�
+3. 鈿狅笍 榛樿鍊间负 `true`锛堝惎鐢級锛岀‘淇濇甯镐笟鍔′笉鍙楀奖鍝�
+4. 鈿狅笍 寤鸿鍦ㄧ敓浜х幆澧冧繚鎸佸紑鍚姸鎬�
+5. 鈿狅笍 娴嬭瘯鐜寤鸿鍏抽棴锛岄伩鍏嶈鍙戞秷鎭粰鐪熷疄鐢ㄦ埛
+
+## 鍏�侀獙璇佹柟娉�
+
+### 1. 楠岃瘉閰嶇疆宸叉坊鍔�
+
+```sql
+SELECT * FROM sys_config WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+### 2. 楠岃瘉寮�鍏崇敓鏁�
+
+**鍏抽棴寮�鍏筹細**
+```sql
+UPDATE sys_config SET config_value = 'false' WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+**鍒涘缓娴嬭瘯浠诲姟锛�**
+- 瑙傚療鏃ュ織鏄惁杈撳嚭锛歚璁㈤槄娑堟伅鍙戦�佸凡鍏抽棴锛岃烦杩囧彂閫乣
+- 纭娌℃湁瀹為檯鍙戦�佸井淇℃秷鎭�
+
+**鎭㈠寮�鍏筹細**
+```sql
+UPDATE sys_config SET config_value = 'true' WHERE config_key = 'wechat.subscribe.message.enabled';
+```
+
+## 涔濄�佺浉鍏抽厤缃�
+
+璇ュ姛鑳介厤鍚堜互涓嬮厤缃娇鐢細
+
+- `weixin.access_token.{appId}` - 寰俊AccessToken缂撳瓨
+- `weixin.access_token_expires.{appId}` - AccessToken杩囨湡鏃堕棿
+- `wechat.task.notify.template.id` - 浠诲姟閫氱煡妯℃澘ID (application.yml)
+- `wechat.task.detail.page` - 浠诲姟璇︽儏椤佃矾寰� (application.yml)
--
Gitblit v1.9.1