app/pages/login.vue
@@ -21,15 +21,22 @@ <image :src="codeUrl" @click="getCode" class="login-code-img" mode="aspectFit"></image> </view> </view> <view class="agreement-checkbox"> <checkbox-group @change="onAgreementChange"> <label class="checkbox-label"> <checkbox :checked="agreedToPolicy" value="agreed" color="#007AFF" style="margin-top: 0;" /> <text class="agreement-text"> <text class="text-grey1">åæ</text> <text @click.stop="handleUserAgrement" class="text-blue agreement-link">ãç¨æ·åè®®ã</text> <text class="text-grey1">å</text> <text @click.stop="handlePrivacy" class="text-blue agreement-link">ãéç§æ¿çã</text> </text> </label> </checkbox-group> </view> <view class="action-btn"> <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">ç»å½</button> </view> <view class="xieyi text-center"> <text class="text-grey1">ç»å½å³ä»£è¡¨åæ</text> <text @click.stop="handleUserAgrement" class="text-blue agreement-link">ãç¨æ·åè®®ã</text> <text class="text-grey1">å</text> <text @click.stop="handlePrivacy" class="text-blue agreement-link">ãéç§åè®®ã</text> </view> </view> </scroll-view> @@ -45,6 +52,8 @@ captchaEnabled: true, // ç¨æ·æ³¨åå¼å ³ register: false, // éç§æ¿çåæç¶æï¼é»è®¤éä¸ï¼ agreedToPolicy: true, globalConfig: getApp().globalData.config, loginForm: { username: "", @@ -70,6 +79,10 @@ handleUserAgrement() { this.$tab.navigateTo('/pages/mine/user-agreement/index') }, // åè®®åæç¶æåæ´ onAgreementChange(e) { this.agreedToPolicy = e.detail.value.length > 0 }, // è·åå¾å½¢éªè¯ç getCode() { getCodeImg().then(res => { @@ -82,6 +95,10 @@ }, // ç»å½æ¹æ³ async handleLogin() { if (!this.agreedToPolicy) { this.$modal.msgError("请å é 读并åæç¨æ·åè®®åéç§æ¿ç") return } if (this.loginForm.username === "") { this.$modal.msgError("请è¾å ¥æ¨çè´¦å·") } else if (this.loginForm.password === "") { @@ -242,24 +259,56 @@ } } .xieyi { .agreement-checkbox { margin: 50rpx 0 30rpx 0; padding: 20rpx 0; line-height: 2; .text-grey1 { color: #888; font-size: 24rpx; padding: 20rpx; display: flex; justify-content: flex-start; align-items: left; checkbox-group { display: flex; align-items: center; } .agreement-link { color: #007AFF; font-size: 24rpx; padding: 10rpx 8rpx; margin: 0 5rpx; display: inline-block; position: relative; z-index: 10; .checkbox-label { display: flex; align-items: center; justify-content: flex-start; checkbox { margin-right: 15rpx; transform: scale(1.2); flex-shrink: 0; vertical-align: middle; } .agreement-text { display: inline-flex; align-items: center; flex-wrap: wrap; line-height: 1.5; font-size: 26rpx; text-align: left; justify-content: flex-start; .text-grey1 { color: #666; font-size: 26rpx; line-height: 1.5; } .text-blue { color: #007AFF; font-size: 26rpx; padding: 8rpx 10rpx; margin: 0 5rpx; display: inline-block; position: relative; z-index: 10; line-height: 1.5; } } } } } app/pages/mine/privacy-policy/index.vue
@@ -9,290 +9,75 @@ <scroll-view class="content" scroll-y="true"> <view class="privacy-content"> <view class="update-time">æ´æ°æ¥æï¼2025å¹´1æ25æ¥</view> <view class="effect-time">çææ¥æï¼2025å¹´10æ25æ¥</view> <view class="main-title">å¹¿ä¸æ°èªå»ç快线è°åº¦ç³»ç»å°ç¨åºéç§ä¿æ¤æå¼</view> <view class="update-time">æ´æ°æ¥æï¼2025-10-26</view> <view class="intro-text"> æ¬æå¼æ¯å¹¿ä¸æ°èªå»ç快线è°åº¦ç³»ç»å°ç¨åºå¼åè <text class="bold">å¹¿ä¸æ°èªå»ç快线æéå ¬å¸</text>ï¼ä»¥ä¸ç®ç§°"å¼åè "ï¼ä¸ºå¤çä½ ç个人信æ¯èå¶å®ã </view> <view class="section"> <text class="section-title">å¼è¨</text> <text class="section-title">å¼åè å¤ççä¿¡æ¯</text> <text class="section-text"> æ¥æè½¬è¿è°åº¦ç³»ç»ï¼ä»¥ä¸ç®ç§°"æä»¬"ï¼æ·±ç¥ä¸ªäººä¿¡æ¯å¯¹æ¨çéè¦æ§ï¼æä»¬å°æç §æ³å¾æ³è§çè¦æ±ï¼éåç¸åºçå®å ¨ä¿æ¤æªæ½ï¼å°½åä¿æ¤æ¨ç个人信æ¯å®å ¨å¯æ§ã </text> <text class="section-text"> æ¬ãéç§æ¿çãéç¨äºæä»¬åæ¨æä¾çæææå¡ãæä»¬å¸æéè¿æ¬æ¿çåæ¨è¯´ææä»¬å¦ä½æ¶éã使ç¨ãåå¨åå享æ¨ç个人信æ¯ï¼ä»¥åæ¨äº«æçç¸å ³æå©ã æ ¹æ®æ³å¾è§å®ï¼å¼åè ä» å¤çå®ç°å°ç¨åºåè½æå¿ è¦çä¿¡æ¯ã </text> <text class="section-text highlight"> 请æ¨å¨ä½¿ç¨æä»¬ç产å/æå¡åï¼ä»ç»é 读并å åçè§£æ¬æ¿çï¼ç¹å«æ¯ä»¥ç²ä½/ä¸å线æ è¯çæ¡æ¬¾ï¼æ¨åºéç¹é 读ã妿¨å¯¹æ¬æ¿çæä»»ä½çé®ï¼å¯éè¿æ¬æ¿çææ«æä¾çèç³»æ¹å¼ä¸æä»¬èç³»ã å¼åè å°å¨è·åä½ çæç¤ºåæåï¼æ¶éä½ çä½ç½®ä¿¡æ¯ï¼ç¨éæ¯ãè·åå½å叿ºæå¨ä½ç½®ï¼ä»¥å¤æä»»å¡åå°åªéäºã </text> </view> <view class="section"> <text class="section-title">ä¸ãæä»¬å¦ä½æ¶éåä½¿ç¨æ¨ç个人信æ¯</text> <text class="section-title">ä½ çæç</text> <text class="section-text"> ä¸ªäººä¿¡æ¯æ¯æä»¥çµåæè å ¶ä»æ¹å¼è®°å½çè½å¤åç¬æè ä¸å ¶ä»ä¿¡æ¯ç»åè¯å«ç¹å®èªç¶äººèº«ä»½æè åæ ç¹å®èªç¶äººæ´»å¨æ åµçåç§ä¿¡æ¯ã å ³äºä½ ç个人信æ¯ï¼ä½ å¯ä»¥éè¿ä»¥ä¸æ¹å¼ä¸å¼åè èç³»ï¼è¡ä½¿æ¥é ãå¤å¶ãæ´æ£ãå é¤çæ³å®æå©ã </text> <text class="section-text"> æä»¬ä» ä¼åºäºä»¥ä¸ç®çï¼æ¶éåä½¿ç¨æ¨ç个人信æ¯ï¼ è¥ä½ å¨å°ç¨åºä¸æ³¨åäºè´¦å·ï¼ä½ å¯ä»¥éè¿ä»¥ä¸æ¹å¼ä¸å¼åè èç³»ï¼ç³è¯·æ³¨éä½ å¨å°ç¨åºä¸ä½¿ç¨çè´¦å·ãå¨åçä½ çç³è¯·åï¼å¼åè æ¿è¯ºå¨åäºä¸ªå·¥ä½æ¥å å®ææ ¸æ¥åå¤çï¼å¹¶æç §æ³å¾æ³è§è¦æ±å¤çä½ çç¸å ³ä¿¡æ¯ã </text> <text class="subsection-title">1.1 è´¦å·æ³¨åä¸ç»å½</text> <text class="contact-info"> çµè¯:13602220409 </text> </view> <view class="section"> <text class="section-title">å¼åè 对信æ¯çåå¨</text> <text class="section-text"> 彿¨æ³¨ååä½¿ç¨æ¬ç³»ç»æ¶ï¼æä»¬éè¦æ¶éï¼ å¼åè æ¿è¯ºï¼é¤æ³å¾æ³è§å¦æè§å®å¤ï¼å¼åè å¯¹ä½ çä¿¡æ¯çä¿åæéåºå½ä¸ºå®ç°å¤çç®çæå¿ è¦çæçæ¶é´ã </text> <text class="section-text indent"> · ææºå·ç ï¼ç¨äºè´¦å·æ³¨åãç»å½éªè¯åå®å ¨ä¿é </text> <text class="section-text indent"> · å§åï¼ç¨äºèº«ä»½è¯å«åä»»å¡åé </text> <text class="section-text indent"> · æå±é¨é¨/æºæï¼ç¨äºæé管çåä»»å¡åä½ </text> <text class="section-text indent"> · èä½/è§è²ï¼ç¨äºç¡®å®ç³»ç»ä½¿ç¨æé </text> <text class="subsection-title">1.2 ä»»å¡è°åº¦æå¡</text> </view> <view class="section"> <text class="section-title">ä¿¡æ¯ç使ç¨è§å</text> <text class="section-text"> 为äºåæ¨æä¾ä»»å¡è°åº¦æå¡ï¼æä»¬éè¦æ¶éï¼ </text> <text class="section-text indent"> · ä½ç½®ä¿¡æ¯ï¼è·åæ¨ç宿¶ä½ç½®ï¼ç¨äºä»»å¡åé ã车è¾è°åº¦åè·¯å¾è§å </text> <text class="section-text indent"> · ä»»å¡ç¸å ³ä¿¡æ¯ï¼å æ¬æ£è ä¿¡æ¯ï¼å§åãå¹´é¾ãæ§å«ãç æ æè¿°ï¼ãå°åä¿¡æ¯ãå»é¢ä¿¡æ¯ç </text> <text class="section-text indent"> · 车è¾ä¿¡æ¯ï¼è½¦çå·ã车è¾ç±»åã设å¤ç¼å·ç å¼åè å°ä¼å¨æ¬æå¼ææç¤ºçç¨éå ä½¿ç¨æ¶éçä¿¡æ¯ã </text> <text class="section-text highlight"> ä½ç½®ä¿¡æ¯å±äºææä¸ªäººä¿¡æ¯ï¼æä»¬ä» 卿¨ä¸»å¨å¼å¯å®ä½æé并使ç¨ç¸å ³åè½æ¶æ¶éï¼æ¨å¯ä»¥éæ¶å¨ç³»ç»è®¾ç½®ä¸å ³éå®ä½æéãæç»æä¾ä½ç½®ä¿¡æ¯å¯è½å¯¼è´é¨ååè½æ æ³ä½¿ç¨ï¼ä½ä¸å½±åå ¶ä»åè½çæ£å¸¸ä½¿ç¨ã </text> <text class="subsection-title">1.3 æ¶æ¯æ¨éæå¡</text> <text class="section-text"> 为äºåæ¶åæ¨æ¨éä»»å¡éç¥ãç³»ç»æ¶æ¯çä¿¡æ¯ï¼æä»¬éè¦æ¶éï¼ </text> <text class="section-text indent"> · 设å¤ä¿¡æ¯ï¼è®¾å¤åå·ãæä½ç³»ç»çæ¬ãè®¾å¤æ è¯ç¬¦ </text> <text class="section-text indent"> · æ¨étokenï¼ç¨äºæ¶æ¯æ¨é </text> <text class="subsection-title">1.4 ç³»ç»å®å ¨ä¸ä¼å</text> <text class="section-text"> 为äºä¿éç³»ç»å®å ¨ç¨³å®è¿è¡å¹¶æåç¨æ·ä½éªï¼æä»¬ä¼æ¶éï¼ </text> <text class="section-text indent"> · æ¥å¿ä¿¡æ¯ï¼æä½æ¥å¿ãé误æ¥å¿ãæ§è½æ°æ® </text> <text class="section-text indent"> · ç½ç»ä¿¡æ¯ï¼IPå°åãç½ç»ç±»å </text> <text class="section-text indent"> · åºç¨ä½¿ç¨æ åµï¼é¡µé¢è®¿é®è®°å½ãåè½ä½¿ç¨é¢ç å¦å¼åè 使ç¨ä½ çä¿¡æ¯è¶ åºæ¬æå¼ç®çæåçèå´ï¼å¼åè å¿ é¡»å¨åæ´ä½¿ç¨ç®çæèå´åï¼åæ¬¡ä»¥ææºçä¿¡æ¹å¼åç¥å¹¶å¾å¾ä½ çæç¤ºåæã </text> </view> <view class="section"> <text class="section-title">äºãæä»¬å¦ä½ä½¿ç¨Cookieååç±»ææ¯</text> <text class="section-title">ä¿¡æ¯å¯¹å¤æä¾</text> <text class="section-text"> Cookieæ¯ä¸ç§ç½ç»æå¡å¨åå¨å¨è®¡ç®æºæç§»å¨è®¾å¤ä¸ççº¯ææ¬æä»¶ãæä»¬ä½¿ç¨Cookieååç±»ææ¯ä¸»è¦ä¸ºäºå®ç°ä»¥ä¸åè½ï¼ </text> <text class="section-text indent"> · è®°ä½æ¨çç»å½ç¶æï¼é¿å éå¤ç»å½ </text> <text class="section-text indent"> · åææ¨ä½¿ç¨æä»¬æå¡çæ åµï¼ä»¥ä¾¿ä¼åæå¡ä½éª </text> <text class="section-text indent"> · ä¿éç³»ç»å®å ¨ï¼é²èå®å ¨é£é© å¼åè æ¿è¯ºï¼ä¸ä¼ä¸»å¨å ±äº«æè½¬è®©ä½ çä¿¡æ¯è³ä»»ä½ç¬¬ä¸æ¹ï¼å¦åå¨ç¡®éå ±äº«æè½¬è®©æ¶ï¼å¼åè åºå½ç´æ¥å¾å¾æç¡®è®¤ç¬¬ä¸æ¹å¾å¾ä½ çåç¬åæã </text> <text class="section-text"> æ¨å¯ä»¥éè¿æµè§å¨æè®¾å¤è®¾ç½®æç»æç®¡çCookieï¼ä½è¿å¯è½å½±åæ¨ä½¿ç¨æä»¬æå¡çé¨ååè½ã å¼åè æ¿è¯ºï¼ä¸ä¼å¯¹å¤å ¬å¼æ«é²ä½ çä¿¡æ¯ï¼å¦å¿ é¡»å ¬å¼æ«é²æ¶ï¼å¼åè åºå½åä½ åç¥å ¬å¼æ«é²çç®çãæ«é²ä¿¡æ¯çç±»ååå¯è½æ¶åçä¿¡æ¯ï¼å¹¶å¾å¾ä½ çåç¬åæã </text> </view> <view class="section"> <text class="section-title">ä¸ãæä»¬å¦ä½å ±äº«ã转让ãå ¬å¼æ«é²æ¨ç个人信æ¯</text> <text class="subsection-title">3.1 å ±äº«</text> <text class="section-title">æè¯ä¸èç³»</text> <text class="section-text"> æä»¬ä¸ä¼åç¬¬ä¸æ¹å ±äº«æ¨ç个人信æ¯ï¼é¤éï¼ ä½ è®¤ä¸ºå¼åè æªéµå®ä¸è¿°çº¦å®ï¼ææå ¶ä»çæè¯å»ºè®®ãææªæå¹´äººä¸ªäººä¿¡æ¯ä¿æ¤ç¸å ³é®é¢ï¼å¯éè¿ä»¥ä¸æ¹å¼ä¸å¼åè èç³»ï¼æè å微信è¿è¡æè¯ã </text> <text class="section-text indent"> · äºå è·å¾æ¨çæç¡®åæ </text> <text class="section-text indent"> · ä¸å ³èæºæå ±äº«ï¼å¨ä¸å¡éè¦ä¸ç¬¦åæ³å¾è§å®çæ åµä¸ï¼æä»¬å¯è½ä¸æ¨æå±å»çæºæãæ¥æä¸å¿å ±äº«å¿ è¦ä¿¡æ¯ </text> <text class="section-text indent"> · æ³å¾æ³è§è§å®çå ¶ä»æ å½¢ </text> <text class="subsection-title">3.2 转让</text> <text class="section-text"> æä»¬ä¸ä¼å°æ¨ç个人信æ¯è½¬è®©ç»ä»»ä½å ¬å¸ãç»ç»å个人ï¼ä½ä»¥ä¸æ åµé¤å¤ï¼ </text> <text class="section-text indent"> · äºå è·å¾æ¨çæç¡®åæ </text> <text class="section-text indent"> · æ ¹æ®æ³å¾æ³è§æå¼ºå¶æ§çè¡æ¿æå¸æ³è¦æ± </text> <text class="subsection-title">3.3 å ¬å¼æ«é²</text> <text class="section-text"> æä»¬ä» ä¼å¨ä»¥ä¸æ åµä¸å ¬å¼æ«é²æ¨ç个人信æ¯ï¼ </text> <text class="section-text indent"> · è·å¾æ¨çæç¡®åæ </text> <text class="section-text indent"> · åºäºæ³å¾æ³è§ãæ³å¾ç¨åºãè¯è®¼ææ¿åºä¸»ç®¡é¨é¨å¼ºå¶æ§è¦æ± </text> </view> <view class="section"> <text class="section-title">åãæä»¬å¦ä½ä¿æ¤æ¨ç个人信æ¯</text> <text class="section-text"> 4.1 æä»¬é常éè§ä¸ªäººä¿¡æ¯å®å ¨ï¼å¹¶éåä¸ååçå¯è¡çæªæ½ä¿æ¤æ¨ç个人信æ¯ï¼ </text> <text class="section-text indent"> · æ°æ®å å¯ï¼éç¨SSL/TLSå å¯ä¼ è¾ï¼å¯¹æææ°æ®è¿è¡å å¯åå¨ </text> <text class="section-text indent"> · è®¿é®æ§å¶ï¼å»ºç«ä¸¥æ ¼çæ°æ®è®¿é®æéæ§å¶åå®¡æ¹æºå¶ </text> <text class="section-text indent"> · å®å ¨å®¡è®¡ï¼å®æè¿è¡å®å ¨å®¡è®¡åé£é©è¯ä¼° </text> <text class="section-text indent"> · 人å管çï¼å¯¹å¤ç个人信æ¯çåå·¥è¿è¡èº«ä»½è®¤è¯åæé管ç </text> <text class="section-text indent"> · åºæ¥ååºï¼å¶å®ä¸ªäººä¿¡æ¯å®å ¨äºä»¶åºæ¥é¢æ¡ </text> <text class="section-text"> 4.2 æä»¬ä¼éååçå¯è¡çæªæ½ï¼å°½åé¿å æ¶éæ å ³ç个人信æ¯ã </text> <text class="section-text highlight"> 4.3 äºèç½å¹¶éç»å¯¹å®å ¨çç¯å¢ï¼æä»¬å¼ºç建议æ¨éåç§¯ææªæ½ä¿æ¤ä¸ªäººä¿¡æ¯çå®å ¨ï¼å æ¬ä½ä¸éäºä½¿ç¨å¤æå¯ç ãå®æä¿®æ¹å¯ç ãä¸å°èªå·±çè´¦å·å¯ç ç个人信æ¯éé²ç»ä»äººã </text> <text class="section-text highlight"> 4.4 妿åç个人信æ¯å®å ¨äºä»¶ï¼æä»¬å°æç §æ³å¾æ³è§çè¦æ±ï¼åæ¶åæ¨åç¥ï¼å®å ¨äºä»¶çåºæ¬æ åµåå¯è½çå½±åãæä»¬å·²éåæå°è¦éåçå¤ç½®æªæ½ãæ¨å¯èªä¸»é²èåéä½é£é©ç建议çã </text> </view> <view class="section"> <text class="section-title">äºãæ¨å¦ä½ç®¡ç个人信æ¯</text> <text class="section-text"> æç §ä¸å½ç¸å ³çæ³å¾æ³è§ï¼æä»¬ä¿éæ¨å¯¹èªå·±ç个人信æ¯è¡ä½¿ä»¥ä¸æå©ï¼ </text> <text class="subsection-title">5.1 访é®åæ´æ£æ¨ç个人信æ¯</text> <text class="section-text"> æ¨å¯ä»¥éè¿ä»¥ä¸æ¹å¼è®¿é®åæ´æ£æ¨ç个人信æ¯ï¼ </text> <text class="section-text indent"> · éè¿"æç-个人信æ¯"页颿¥çåä¿®æ¹åºæ¬ä¿¡æ¯ </text> <text class="section-text indent"> · è系系ç»ç®¡çååå©ä¿®æ¹ </text> <text class="subsection-title">5.2 å 餿¨ç个人信æ¯</text> <text class="section-text"> å¨ä»¥ä¸æ å½¢ä¸ï¼æ¨å¯ä»¥åæä»¬æåºå é¤ä¸ªäººä¿¡æ¯ç请æ±ï¼ </text> <text class="section-text indent"> · æä»¬å¤ç个人信æ¯çè¡ä¸ºè¿åæ³å¾æ³è§ </text> <text class="section-text indent"> · æä»¬æ¶éãä½¿ç¨æ¨ç个人信æ¯ï¼å´æªå¾å¾æ¨çåæ </text> <text class="section-text indent"> · æä»¬å¤ç个人信æ¯çè¡ä¸ºè¿åäºä¸æ¨ççº¦å® </text> <text class="section-text indent"> · æ¨æ³¨éäºè´¦å· </text> <text class="subsection-title">5.3 注éè´¦å·</text> <text class="section-text"> æ¨å¯ä»¥éè¿è系系ç»ç®¡çåç³è¯·æ³¨éè´¦å·ãè´¦å·æ³¨éåï¼æä»¬å°åæ¢ä¸ºæ¨æä¾æå¡ï¼å¹¶æ ¹æ®æ³å¾æ³è§è¦æ±å 餿¨ç个人信æ¯ã </text> <text class="subsection-title">5.4 æ¤ååæ</text> <text class="section-text"> æ¨å¯ä»¥éè¿è®¾å¤æé设置æ¤å对ä½ç½®ä¿¡æ¯ãæå头ãç¸åçæææéçææã </text> <text class="section-text"> 请æ¨çè§£ï¼ç¹å®çä¸å¡åè½éè¦æ¨çä¿¡æ¯æè½å¾ä»¥å®æï¼å½æ¨æ¤ååæåï¼æä»¬æ æ³ç»§ç»ä¸ºæ¨æä¾æ¤å忿坹åºçæå¡ã </text> </view> <view class="section"> <text class="section-title">å ãæä»¬å¦ä½å¤çæªæå¹´äººç个人信æ¯</text> <text class="section-text"> 6.1 æ¬ç³»ç»ä¸»è¦é¢åå»çæ¥æä»ä¸äººåï¼ååä¸ä¸åæªæå¹´äººæä¾æå¡ã </text> <text class="section-text"> 6.2 妿æä»¬åç°å¨æªäºå è·å¾å¯è¯å®çç¶æ¯ææ³å®çæ¤äººåæçæ åµä¸æ¶éäºæªæå¹´äººç个人信æ¯ï¼æä»¬ä¼è®¾æ³å°½å¿«å é¤ç¸å ³æ°æ®ã </text> </view> <view class="section"> <text class="section-title">ä¸ãæ¨ç个人信æ¯å¦ä½å¨å ¨çèå´å 转移</text> <text class="section-text"> æä»¬å¨ä¸å人æ°å ±åå½å¢å æ¶éå产çç个人信æ¯å°åå¨å¨ä¸å人æ°å ±åå½å¢å ã </text> </view> <view class="section"> <text class="section-title">å «ãæ¬æ¿çå¦ä½æ´æ°</text> <text class="section-text"> 8.1 æä»¬å¯è½éæ¶ä¿®è®¢æ¬æ¿çå 容ãå¦è¯¥çåæ´ä¼å¯¼è´æ¨å¨æ¬æ¿ç项䏿å©çå®è´¨åæï¼æä»¬å°å¨åæ´çæåï¼éè¿å¨é¡µé¢æ¾èä½ç½®æç¤ºã忍åéæ¶æ¯çæ¹å¼éç¥æ¨ã </text> <text class="section-text highlight"> 8.2 å¨è¯¥ç§æ åµä¸ï¼è¥æ¨ç»§ç»ä½¿ç¨æä»¬çæå¡ï¼å³è¡¨ç¤ºåæåç»ä¿®è®¢çæ¬æ¿çç约æã </text> </view> <view class="section"> <text class="section-title">ä¹ãå¦ä½èç³»æä»¬</text> <text class="section-text"> 9.1 妿¨å¯¹æ¬éç§æ¿çææ¨ä¸ªäººä¿¡æ¯çç¸å ³äºå®æä»»ä½é®é¢ãæè§æå»ºè®®ï¼è¯·éè¿ä»¥ä¸æ¹å¼ä¸æä»¬èç³»ï¼ </text> <text class="section-text"> çµåé®ç®±ï¼wanglizhong@966120.com.cn </text> <text class="section-text"> 客æçµè¯ï¼020-966120 </text> <text class="section-text"> 工使¶é´ï¼å¨ä¸è³å¨æ¥ 24å°æ¶ </text> <text class="section-text"> 9.2 ä¸è¬æ åµä¸ï¼æä»¬å°å¨15ä¸ªå·¥ä½æ¥å å夿¨ç请æ±ã </text> </view> <view class="section"> <text class="section-title">åãå®ä¹</text> <text class="section-text"> 个人信æ¯ï¼æä»¥çµåæè å ¶ä»æ¹å¼è®°å½çè½å¤åç¬æè ä¸å ¶ä»ä¿¡æ¯ç»åè¯å«ç¹å®èªç¶äººèº«ä»½æè åæ ç¹å®èªç¶äººæ´»å¨æ åµçåç§ä¿¡æ¯ã </text> <text class="section-text"> ææä¸ªäººä¿¡æ¯ï¼æä¸æ¦æ³é²æè éæ³ä½¿ç¨ï¼å®¹æå¯¼è´èªç¶äººçäººæ ¼å°ä¸¥åå°ä¾µå®³æè 人身ã财产å®å ¨åå°å±å®³ç个人信æ¯ï¼å æ¬çç©è¯å«ãå®æä¿¡ä»°ãç¹å®èº«ä»½ãå»çå¥åº·ãéèè´¦æ·ãè¡è¸ªè½¨è¿¹çä¿¡æ¯ã </text> <text class="section-text"> 个人信æ¯å é¤ï¼æå¨å®ç°æ¥å¸¸ä¸å¡åè½ææ¶åçç³»ç»ä¸å»é¤ä¸ªäººä¿¡æ¯çè¡ä¸ºï¼ä½¿å ¶ä¿æä¸å¯è¢«æ£ç´¢ã访é®çç¶æã <text class="contact-info"> çµè¯:13602220409 </text> </view> <view class="footer"> <text class="footer-text">æè°¢æ¨ä¿¡ä»»å¹¶ä½¿ç¨æ¥æè½¬è¿è°åº¦ç³»ç»ï¼</text> <text class="footer-text">æ´æ°æ¥æï¼2025-10-26</text> </view> </view> </scroll-view> @@ -354,11 +139,41 @@ border-radius: 15rpx; padding: 40rpx 30rpx; .update-time, .effect-time { .main-title { font-size: 36rpx; font-weight: bold; color: #333; text-align: center; margin-bottom: 20rpx; line-height: 1.5; } .update-time { font-size: 24rpx; color: #999; margin-bottom: 10rpx; text-align: center; margin-bottom: 30rpx; } .intro-text { font-size: 28rpx; color: #666; line-height: 1.8; margin-bottom: 30rpx; text-align: justify; .bold { font-weight: bold; color: #333; } } .contact-info { display: block; font-size: 28rpx; color: #007AFF; margin: 20rpx 0; font-weight: bold; } .section { @@ -374,15 +189,6 @@ font-weight: bold; color: #333; margin-bottom: 20rpx; line-height: 1.5; } .subsection-title { display: block; font-size: 30rpx; font-weight: bold; color: #666; margin: 25rpx 0 15rpx; line-height: 1.5; } @@ -402,22 +208,6 @@ margin: 20rpx 0; font-weight: bold; color: #333; } &.indent { padding-left: 40rpx; position: relative; &::before { content: ''; position: absolute; left: 20rpx; top: 18rpx; width: 8rpx; height: 8rpx; background-color: #666; border-radius: 50%; } } } } app/pages/register.vue
@@ -30,7 +30,7 @@ <view class="agreement-section"> <checkbox-group @change="handleAgreementChange"> <label class="agreement-label"> <checkbox value="agreed" :checked="agreedToTerms" color="#007AFF" /> <checkbox value="agreed" :checked="agreedToTerms" color="#007AFF" style="margin-top: 0;" /> <text class="agreement-text"> æå·²é è¯»å¹¶åæ <text class="agreement-link" @click.stop="handleUserAgreement">ãç¨æ·æå¡åè®®ã</text> @@ -59,7 +59,7 @@ return { codeUrl: "", captchaEnabled: true, agreedToTerms: false, agreedToTerms: true, // é»è®¤éä¸ globalConfig: getApp().globalData.config, registerForm: { username: "", @@ -211,32 +211,49 @@ } .agreement-section { margin: 30rpx 0; margin: 50rpx 0 30rpx 0; padding: 20rpx; display: flex; justify-content: flex-end; align-items: center; checkbox-group { display: flex; align-items: center; } .agreement-label { display: flex; align-items: flex-start; align-items: center; justify-content: flex-start; checkbox { margin-right: 15rpx; transform: scale(0.9); transform: scale(1.2); flex-shrink: 0; vertical-align: middle; } .agreement-text { flex: 1; display: inline-flex; align-items: center; flex-wrap: wrap; font-size: 26rpx; color: #666; line-height: 2; text-align: left; line-height: 1.5; text-align: right; justify-content: flex-end; .agreement-link { color: #007AFF; text-decoration: underline; padding: 8rpx 5rpx; text-decoration: none; padding: 8rpx 10rpx; margin: 0 5rpx; display: inline-block; position: relative; z-index: 10; border-bottom: 1px solid #007AFF; line-height: 1.5; } } } app/pages/task/create-emergency.vue
@@ -785,25 +785,67 @@ this.taskForm.hospitalIn.departmentId = selected.id // ä¿åç§å®¤ID }, // å è½½é»è®¤åºé¢å表ï¼å100æ¡ï¼ // å è½½é»è®¤å»é¢å表ï¼å100æ¡ï¼ loadDefaultHospitals() { // ä¼ å ¥ç©ºå符串æç¹æ®æ è¯è·åå100æ¡ï¼åæ¶ä¼ å ¥å°åè¿æ»¤ // 转åºå»é¢ï¼åªå è½½å½ååºåçå»é¢ï¼å¸¦å°åè¿æ»¤ï¼ searchHospitals('', this.selectedRegion).then(response => { this.defaultHospitals = response.data || [] // åæ¶åå§å两个æç´¢ç»æä¸ºé»è®¤æ°æ® this.hospitalOutResults = [...this.defaultHospitals] this.hospitalInResults = [...this.defaultHospitals] this.hospitalOutResults = response.data || [] console.log('å 载转åºå»é¢ï¼å½ååºåï¼:', this.selectedRegion, 'æ°é:', this.hospitalOutResults.length) }).catch(error => { console.error('å è½½é»è®¤åºé¢å表失败:', error) this.defaultHospitals = [] console.error('å 载转åºå»é¢å表失败:', error) this.hospitalOutResults = [] }) // è½¬å ¥å»é¢ï¼å è½½ææå»é¢ï¼ä¸å¸¦å°åè¿æ»¤ï¼åç»ä¼æå°åæåºï¼ searchHospitals('', this.selectedRegion).then(response => { const allHospitals = response.data || [] // å°å»é¢æå°åæåºï¼æ¬å°åºåä¼å this.hospitalInResults = this.sortHospitalsByRegion(allHospitals) console.log('å è½½è½¬å ¥å»é¢ï¼å ¨é¨åºåï¼:', 'æ°é:', this.hospitalInResults.length) }).catch(error => { console.error('å è½½è½¬å ¥å»é¢å表失败:', error) this.hospitalInResults = [] }) }, // æå°åæåºå»é¢ï¼æ¬å°åºåä¼å sortHospitalsByRegion(hospitals) { if (!this.selectedRegion || !hospitals || hospitals.length === 0) { return hospitals } const region = this.selectedRegion const localHospitals = [] const otherHospitals = [] hospitals.forEach(hospital => { // 夿å»é¢æ¯å¦å¨æ¬å°åºåï¼çãå¸ãåºä»»ä¸å å«å°åå ³é®è¯ï¼ const isLocal = (hospital.hopsProvince && hospital.hopsProvince.includes(region)) || (hospital.hopsCity && hospital.hopsCity.includes(region)) || (hospital.hopsArea && hospital.hopsArea.includes(region)) if (isLocal) { localHospitals.push(hospital) } else { otherHospitals.push(hospital) } }) // æ¬å°å»é¢å¨åï¼å ¶ä»å»é¢å¨å return [...localHospitals, ...otherHospitals] }, // 转åºå»é¢è¾å ¥æ¡è·å¾ç¦ç¹ onHospitalOutFocus() { // å¦ææ²¡ææç´¢å ³é®è¯ï¼æ¾ç¤ºé»è®¤ç100æ¡æ°æ® // å¦ææ²¡ææç´¢å ³é®è¯ï¼åªæ¾ç¤ºå½ååºåçå»é¢ if (!this.hospitalOutSearchKeyword || this.hospitalOutSearchKeyword.trim() === '') { this.hospitalOutResults = [...this.defaultHospitals] searchHospitals('', this.selectedRegion).then(response => { this.hospitalOutResults = response.data || [] }).catch(error => { console.error('å 载转åºå»é¢å¤±è´¥:', error) this.hospitalOutResults = [] }) } this.showHospitalOutResults = true }, @@ -818,27 +860,33 @@ clearTimeout(this.searchTimer) } // å¦æå ³é®è¯ä¸ºç©ºï¼æ¾ç¤ºé»è®¤100æ¡ // å¦æå ³é®è¯ä¸ºç©ºï¼åªæ¾ç¤ºå½ååºåçå»é¢ if (!keyword || keyword.trim() === '') { this.hospitalOutResults = [...this.defaultHospitals] searchHospitals('', this.selectedRegion).then(response => { this.hospitalOutResults = response.data || [] }).catch(error => { console.error('å 载转åºå»é¢å¤±è´¥:', error) this.hospitalOutResults = [] }) this.showHospitalOutResults = true return } // æå ³é®è¯æ¶ï¼å»æå¡ç«¯æç´¢ // æå ³é®è¯æ¶ï¼å»æå¡ç«¯æç´¢ï¼ä» éå½ååºåï¼ this.searchTimer = setTimeout(() => { this.searchHospitalOut(keyword) }, 300) }, // æç´¢è½¬åºå»é¢ // æç´¢è½¬åºå»é¢ï¼ä» éå½ååºåï¼ searchHospitalOut(keyword) { // ä¼ å ¥å ³é®è¯åå°åè¿æ»¤ // ä¼ å ¥å ³é®è¯åå°åè¿æ»¤ï¼åªæç´¢å½ååºåçå»é¢ searchHospitals(keyword, this.selectedRegion).then(response => { this.hospitalOutResults = response.data || [] this.showHospitalOutResults = true console.log('æç´¢è½¬åºå»é¢:', keyword, 'åºå:', this.selectedRegion, 'ç»ææ°:', this.hospitalOutResults.length) }).catch(error => { console.error('æç´¢å»é¢å¤±è´¥:', error) console.error('æç´¢è½¬åºå»é¢å¤±è´¥:', error) this.hospitalOutResults = [] }) }, @@ -868,9 +916,16 @@ // è½¬å ¥å»é¢è¾å ¥æ¡è·å¾ç¦ç¹ onHospitalInFocus() { // å¦ææ²¡ææç´¢å ³é®è¯ï¼æ¾ç¤ºé»è®¤ç100æ¡æ°æ® // å¦ææ²¡ææç´¢å ³é®è¯ï¼æ¾ç¤ºææå»é¢ï¼æ¬å°åºåä¼å ï¼ if (!this.hospitalInSearchKeyword || this.hospitalInSearchKeyword.trim() === '') { this.hospitalInResults = [...this.defaultHospitals] searchHospitals('', '').then(response => { const allHospitals = response.data || [] // æå°åæåºï¼æ¬å°åºåä¼å this.hospitalInResults = this.sortHospitalsByRegion(allHospitals) }).catch(error => { console.error('å è½½è½¬å ¥å»é¢å¤±è´¥:', error) this.hospitalInResults = [] }) } this.showHospitalInResults = true }, @@ -885,27 +940,37 @@ clearTimeout(this.searchTimer) } // å¦æå ³é®è¯ä¸ºç©ºï¼æ¾ç¤ºé»è®¤100æ¡ // å¦æå ³é®è¯ä¸ºç©ºï¼æ¾ç¤ºææå»é¢ï¼æ¬å°åºåä¼å ï¼ if (!keyword || keyword.trim() === '') { this.hospitalInResults = [...this.defaultHospitals] searchHospitals('', '').then(response => { const allHospitals = response.data || [] // æå°åæåºï¼æ¬å°åºåä¼å this.hospitalInResults = this.sortHospitalsByRegion(allHospitals) }).catch(error => { console.error('å è½½è½¬å ¥å»é¢å¤±è´¥:', error) this.hospitalInResults = [] }) this.showHospitalInResults = true return } // æå ³é®è¯æ¶ï¼å»æå¡ç«¯æç´¢ // æå ³é®è¯æ¶ï¼å»æå¡ç«¯æç´¢ï¼ä¸éåºåï¼ä½ç»ææå°åæåºï¼ this.searchTimer = setTimeout(() => { this.searchHospitalIn(keyword) }, 300) }, // æç´¢è½¬å ¥å»é¢ // æç´¢è½¬å ¥å»é¢ï¼ä¸éåºåï¼ä½æ¬å°åºåä¼å ï¼ searchHospitalIn(keyword) { // ä¼ å ¥å ³é®è¯åå°åè¿æ»¤ searchHospitals(keyword, this.selectedRegion).then(response => { this.hospitalInResults = response.data || [] // ä¼ å ¥å ³é®è¯ï¼ä¸ä¼ å°åè¿æ»¤ï¼æç´¢ææåºåï¼ searchHospitals(keyword, '').then(response => { const allHospitals = response.data || [] // æå°åæåºï¼æ¬å°åºåä¼å this.hospitalInResults = this.sortHospitalsByRegion(allHospitals) this.showHospitalInResults = true console.log('æç´¢è½¬å ¥å»é¢:', keyword, 'ç»ææ°:', this.hospitalInResults.length) }).catch(error => { console.error('æç´¢å»é¢å¤±è´¥:', error) console.error('æç´¢è½¬å ¥å»é¢å¤±è´¥:', error) this.hospitalInResults = [] }) }, app/µÇ¼ע²áÐÒéͬÒ⹦ÄÜ˵Ã÷.md
New file @@ -0,0 +1,324 @@ # ç»å½æ³¨ååè®®åæåè½è¯´æ ## ä¸ãåè½æ¦è¿° å¨ç»å½å注åç颿·»å äºç¨æ·åè®®åéç§æ¿ççåæé项ï¼ç¡®ä¿ç¨æ·å¨ä½¿ç¨ç³»ç»åå·²é 读并åæç¸å ³æ¡æ¬¾ï¼ç¬¦ååºç¨åè§è¦æ±ã ## äºãæ¶åæä»¶ ### 1. ç»å½é¡µé¢ **æä»¶è·¯å¾**: `app/pages/login.vue` **ä¿®æ¹å 容**: - æ°å¢ `agreedToPolicy` æ°æ®å±æ§ï¼é»è®¤å¼ä¸º `true`ï¼é»è®¤éä¸ï¼ - æ·»å åè®®åæå¤éæ¡ç»ä»¶ - æ·»å `onAgreementChange` æ¹æ³å¤çå¤éæ¡ç¶æåæ´ - ä¿®æ¹ `handleLogin` æ¹æ³ï¼å¢å åè®®åææ ¡éª - ä¼åæ ·å¼å¸å±ï¼åè®®å¤éæ¡ä½äºç»å½æé®ä¸æ¹ ### 2. 注åé¡µé¢ **æä»¶è·¯å¾**: `app/pages/register.vue` **ä¿®æ¹å 容**: - ä¿®æ¹ `agreedToTerms` é»è®¤å¼ä¸º `true`ï¼å为 `false`ï¼ - ä¿æåæçåè®®åæåè½åæ ¡éªé»è¾ ## ä¸ãåè½è¯¦æ ### ç»å½é¡µé¢ #### 1. çé¢å¸å± ``` âââââââââââââââââââââââââââ â Logo + æ é¢ â ââââââââââââââââââââââââââ⤠â è´¦å·è¾å ¥æ¡ â â å¯ç è¾å ¥æ¡ â â éªè¯ç è¾å ¥æ¡ â ââââââââââââââââââââââââââ⤠â â æå·²é è¯»å¹¶åæ â â ãç¨æ·åè®®ãå â â ãéç§æ¿çã â ââââââââââââââââââââââââââ⤠â ãç»å½ãæé® â âââââââââââââââââââââââââââ ``` #### 2. æ ¸å¿ä»£ç ```javascript data() { return { agreedToPolicy: true, // é»è®¤éä¸ // ... } } // åè®®åæç¶æåæ´ onAgreementChange(e) { this.agreedToPolicy = e.detail.value.length > 0 } // ç»å½éªè¯ async handleLogin() { if (!this.agreedToPolicy) { this.$modal.msgError("请å é 读并åæç¨æ·åè®®åéç§æ¿ç") return } // ... å ¶ä»éªè¯é»è¾ } ``` #### 3. çé¢ç»ä»¶ ```vue <view class="agreement-checkbox"> <checkbox-group @change="onAgreementChange"> <label class="checkbox-label"> <checkbox :checked="agreedToPolicy" :value="agreedToPolicy" color="#007AFF" /> <text class="agreement-text"> <text class="text-grey1">æå·²é 读并åæ</text> <text @click.stop="handleUserAgrement" class="text-blue agreement-link">ãç¨æ·åè®®ã</text> <text class="text-grey1">å</text> <text @click.stop="handlePrivacy" class="text-blue agreement-link">ãéç§æ¿çã</text> </text> </label> </checkbox-group> </view> ``` ### 注åé¡µé¢ #### 1. çé¢å¸å± ``` âââââââââââââââââââââââââââ â Logo + æ é¢ â ââââââââââââââââââââââââââ⤠â è´¦å·è¾å ¥æ¡ â â å¯ç è¾å ¥æ¡ â â 确认å¯ç è¾å ¥æ¡ â â éªè¯ç è¾å ¥æ¡ â ââââââââââââââââââââââââââ⤠â â æå·²é è¯»å¹¶åæ â â ãç¨æ·æå¡åè®®ãå â â ãéç§æ¿çã â ââââââââââââââââââââââââââ⤠â ãæ³¨åãæé® â âââââââââââââââââââââââââââ ``` #### 2. æ ¸å¿ä»£ç ```javascript data() { return { agreedToTerms: true, // é»è®¤éä¸ï¼å·²ä¿®æ¹ï¼ // ... } } // 注åéªè¯ async handleRegister() { // ... å ¶ä»éªè¯ if (!this.agreedToTerms) { this.$modal.msgError("请å é 读并åæç¨æ·æå¡åè®®åéç§æ¿ç") return } // ... } ``` ## åãé»è®¤ç¶æè¯´æ ### 为ä»ä¹é»è®¤éä¸ï¼ 1. **ç¨æ·ä½éªä¼å** - åå°ç¨æ·æä½æ¥éª¤ - é¿å ç¨æ·å å¿è®°å¾éèæ æ³ç»å½/注å - 符å大夿°ç¨æ·ç使ç¨ä¹ æ¯ 2. **åè§æ§ä¿é** - å¤éæ¡ä»ç¶å¯è§ï¼ç¨æ·å¯ä»¥ä¸»å¨åæ¶ - åè®®é¾æ¥å¯ç¹å»æ¥çï¼ä¿¡æ¯éæ - ç¨æ·æå åçç¥æ æåéæ©æ 3. **æ³å¾è¦æ±** - æç¡®å±ç¤ºåè®®å 容 - æä¾ä¾¿æ·çåè®®æ¥çéå¾ - ç¨æ·å¯ä»¥èªä¸»éæ©æ¯å¦åæ ## äºãå议页é¢è¯´æ ### 1. ç¨æ·åè®® **è·¯å¾**: `/pages/mine/user-agreement/index` - 详ç»è¯´æç¨æ·æå©åä¹å¡ - æå¡æ¡æ¬¾å使ç¨è§è - æ¯æå¿å访é®ï¼å·²é ç½®ç½ååï¼ ### 2. éç§æ¿ç **è·¯å¾**: `/pages/mine/privacy-policy/index` - ä¸ªäººä¿¡æ¯æ¶é说æ - ä¿¡æ¯ä½¿ç¨ååå¨è§å - ç¨æ·æçä¿æ¤æªæ½ - æ¯æå¿å访é®ï¼å·²é ç½®ç½ååï¼ ## å ãäº¤äºæµç¨ ### ç»å½æµç¨ ```mermaid graph TD A[æå¼ç»å½é¡µ] --> B[åè®®é»è®¤éä¸] B --> C{è¾å ¥è´¦å·å¯ç } C --> D{ç¹å»ç»å½} D --> E{æ£æ¥åè®®æ¯å¦åæ} E -->|æªåæ| F[æç¤º:请å åæåè®®] E -->|å·²åæ| G[éªè¯è´¦å·å¯ç ] G --> H[ç»å½æå] B --> I[ç¹å»åè®®é¾æ¥] I --> J[æ¥çå议详æ ] J --> B ``` ### æ³¨åæµç¨ ```mermaid graph TD A[æå¼æ³¨å页] --> B[åè®®é»è®¤éä¸] B --> C{è¾å ¥æ³¨åä¿¡æ¯} C --> D{ç¹å»æ³¨å} D --> E{æ£æ¥åè®®æ¯å¦åæ} E -->|æªåæ| F[æç¤º:请å åæåè®®] E -->|å·²åæ| G[éªè¯æ³¨åä¿¡æ¯] G --> H[注åæå] B --> I[ç¹å»åè®®é¾æ¥] I --> J[æ¥çå议详æ ] J --> B ``` ## ä¸ãæ ·å¼è¯´æ ### ç»å½é¡µé¢æ ·å¼ ```scss .agreement-checkbox { margin: 30rpx 0 20rpx 0; padding: 0 20rpx; .checkbox-label { display: flex; align-items: flex-start; checkbox { margin-right: 10rpx; margin-top: 4rpx; flex-shrink: 0; } .agreement-text { flex: 1; line-height: 1.8; font-size: 24rpx; .text-grey1 { color: #888; } .text-blue { color: #007AFF; margin: 0 5rpx; } } } } ``` ### 注å页颿 ·å¼ ```scss .agreement-section { margin: 30rpx 0; .agreement-label { display: flex; align-items: flex-start; checkbox { margin-right: 15rpx; transform: scale(0.9); flex-shrink: 0; } .agreement-text { flex: 1; font-size: 26rpx; color: #666; line-height: 2; text-align: left; .agreement-link { color: #007AFF; text-decoration: underline; } } } } ``` ## å «ãé误æç¤º ### ç»å½é¡µé¢ - **æªåæåè®®**: "请å é 读并åæç¨æ·åè®®åéç§æ¿ç" - **è´¦å·ä¸ºç©º**: "请è¾å ¥æ¨çè´¦å·" - **å¯ç 为空**: "请è¾å ¥æ¨çå¯ç " - **éªè¯ç 为空**: "请è¾å ¥éªè¯ç " ### 注åé¡µé¢ - **æªåæåè®®**: "请å é 读并åæç¨æ·æå¡åè®®åéç§æ¿ç" - **è´¦å·ä¸ºç©º**: "请è¾å ¥æ¨çè´¦å·" - **å¯ç 为空**: "请è¾å ¥æ¨çå¯ç " - **确认å¯ç 为空**: "è¯·åæ¬¡è¾å ¥æ¨çå¯ç " - **å¯ç ä¸ä¸è´**: "两次è¾å ¥çå¯ç ä¸ä¸è´" - **éªè¯ç 为空**: "请è¾å ¥éªè¯ç " ## ä¹ã注æäºé¡¹ 1. **åè®®æ´æ°** - åè®®å å®¹æ´æ°æ¶ï¼éåæ¥æ´æ°åè®®é¡µé¢ - 建议å¨åè®®é¡µé¢æ¾ç¤ºæ´æ°æ¥æ 2. **ç¨æ·æç** - ç¨æ·å¯ä»¥éæ¶åæ¶å¾é - åæ¶åæ æ³ç»å½/注å - åè®®é¾æ¥å§ç»å¯ç¹å»æ¥ç 3. **åè§æ§** - ç¡®ä¿åè®®å 容宿´ãåç¡® - æä¾æ¸ æ°çåè®®æ¥çéå¾ - ä¿éç¨æ·ç¥æ æåéæ©æ 4. **æµè¯å»ºè®®** - æµè¯é»è®¤éä¸ç¶æ - æµè¯åæ¶éä¸åçç»å½/æ³¨åæµç¨ - æµè¯åè®®é¾æ¥è·³è½¬åè½ - æµè¯ä¸å设å¤çæ¾ç¤ºææ ## åãåç»ä¼å建议 1. **åè®®çæ¬ç®¡ç** - è®°å½ç¨æ·åæçåè®®çæ¬ - åè®®æ´æ°æ¶æç¤ºç¨æ·éæ°ç¡®è®¤ 2. **ç¨æ·ä½éª** - æ·»å åè®®é¢è§åè½ï¼å¼¹çªæ¥çï¼ - æ¯æåè®®å ³é®å 容é«äº®æ¾ç¤º 3. **æ°æ®ç»è®¡** - ç»è®¡ç¨æ·åè®®åæç - åæç¨æ·åè®®æ¥çæ åµ 4. **å¤è¯è¨æ¯æ** - æ¯æä¸è±æåæ¢ - ä¸åå°åºæ¾ç¤ºå¯¹åºçæ³å¾æ¡æ¬¾ --- **ææ¡£çæ¬**: v1.0 **åå»ºæ¥æ**: 2025-01-XX **æåæ´æ°**: 2025-01-XX **ç»´æ¤äººå**: ç³»ç»ç®¡çå prd/APP½Ó¿ÚȨÏÞÒÆ³ý˵Ã÷.md
New file @@ -0,0 +1,146 @@ # APP æ¥å£æéç§»é¤è¯´æ ## ä¿®æ¹æ¦è¿° æ ¹æ®éæ±ï¼ç§»é¤äºææè¢« app 端è°ç¨çåå°æ¥å£çæééªè¯æ³¨è§£ï¼`@PreAuthorize`ï¼ï¼ä½¿è¿äºæ¥å£å¯ä»¥å¨ç¨æ·ç»å½åæ éé¢å¤æéå³å¯è®¿é®ã ## 已修æ¹ç Controller åæ¥å£ ### 1. SysTaskControllerï¼ä»»å¡ç®¡çï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /task/list` - æ¥è¯¢ä»»å¡å表 - `POST /task/export` - 导åºä»»å¡å表 - `GET /task/{taskId}` - è·åä»»å¡è¯¦æ - `POST /task` - æ°å¢ä»»å¡ - `PUT /task` - ä¿®æ¹ä»»å¡ - `DELETE /task/{taskIds}` - å é¤ä»»å¡ - `PUT /task/{taskId}/assign` - åé ä»»å¡ - `PUT /task/{taskId}/status` - æ´æ°ä»»å¡ç¶æ - `GET /task/statistics` - æ¥è¯¢ä»»å¡ç»è®¡ - `GET /task/overdue` - æ¥è¯¢è¶ æ¶ä»»å¡ - `GET /task/my` - æ¥è¯¢æçä»»å¡ ### 2. SysTaskVehicleControllerï¼ä»»å¡è½¦è¾å ³èï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /task/vehicle/list/{taskId}` - æ¥è¯¢ä»»å¡å ³èç车è¾å表 - `GET /task/vehicle/available` - æ¥è¯¢å¯ç¨è½¦è¾å表 - `POST /task/vehicle/assign/{taskId}` - åé 车è¾ç»ä»»å¡ - `POST /task/vehicle/assign-batch/{taskId}` - æ¹éåé 车è¾ç»ä»»å¡ - `DELETE /task/vehicle/{taskId}/{vehicleId}` - åæ¶ä»»å¡è½¦è¾åé ### 3. VehicleInfoControllerï¼è½¦è¾ä¿¡æ¯ç®¡çï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VehicleInfoController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /system/vehicle/list` - æ¥è¯¢è½¦è¾ä¿¡æ¯å表 - `GET /system/vehicle/export` - 导åºè½¦è¾ä¿¡æ¯å表 - `GET /system/vehicle/{vehicleId}` - è·å车è¾ä¿¡æ¯è¯¦æ - `POST /system/vehicle` - æ°å¢è½¦è¾ä¿¡æ¯ - `PUT /system/vehicle` - ä¿®æ¹è½¦è¾ä¿¡æ¯ - `DELETE /system/vehicle/{vehicleIds}` - å é¤è½¦è¾ä¿¡æ¯ **注æ**ï¼ä»¥ä¸æ¥å£å·²ä½¿ç¨ `@Anonymous` 注解ï¼ä¿æä¸åï¼ - `POST /system/vehicle/bind` - ç»å®è½¦è¾å°ç¨æ· - `POST /system/vehicle/unbind` - è§£ç»ç¨æ·è½¦è¾ - `GET /system/vehicle/user/bound/{userId}` - è·åç¨æ·ç»å®çè½¦è¾ ### 4. SysDeptControllerï¼é¨é¨ç®¡çï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /system/dept/list` - è·åé¨é¨å表 - `GET /system/dept/list/exclude/{deptId}` - æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ - `GET /system/dept/{deptId}` - æ ¹æ®é¨é¨ç¼å·è·å详ç»ä¿¡æ¯ ### 5. SysUserControllerï¼ç¨æ·ç®¡çï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /system/user/list` - è·åç¨æ·å表 ### 6. SysDictDataControllerï¼åå ¸æ°æ®ï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java` **注æ**ï¼ä»¥ä¸æ¥å£åæ¬å°±æ²¡ææé注解ï¼ä¿æä¸åï¼ - `GET /system/dict/data/type/{dictType}` - æ ¹æ®åå ¸ç±»åæ¥è¯¢åå ¸æ°æ® ### 7. SqlServerDictionaryControllerï¼SQL Serveråå ¸æ¥è¯¢ï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/sqlserver/SqlServerDictionaryController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /sqlserver/dictionary/serviceOrdAreaTypes` - æ¥è¯¢åæ®ç±»åå表 - `GET /sqlserver/dictionary/serviceOrderClass` - æ¥è¯¢æå¡åç¼ç å表 - `GET /sqlserver/dictionary/dispatchOrderClass` - æ¥è¯¢è°åº¦åç¼ç å表 - `GET /sqlserver/dictionary/serviceOrderTypes` - æ¥è¯¢æå¡è®¢åç±»åå表 - `GET /sqlserver/dictionary/hospitalDepartments` - æ¥è¯¢å»é¢ç§å®¤å表 ### 8. SysMessageControllerï¼ç³»ç»æ¶æ¯ï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMessageController.java` ç§»é¤ä»¥ä¸æ¥å£çæéæ³¨è§£ï¼ - `GET /system/message/list` - æ¥è¯¢ç³»ç»æ¶æ¯å表 - `POST /system/message/export` - 导åºç³»ç»æ¶æ¯å表 - `GET /system/message/{messageId}` - è·åç³»ç»æ¶æ¯è¯¦ç»ä¿¡æ¯ - `POST /system/message` - æ°å¢ç³»ç»æ¶æ¯ - `PUT /system/message` - ä¿®æ¹ç³»ç»æ¶æ¯ - `DELETE /system/message/{messageIds}` - å é¤ç³»ç»æ¶æ¯ **注æ**ï¼ä»¥ä¸æ¥å£åæ¬å°±æ²¡ææé注解ï¼ä¿æä¸åï¼ - `GET /system/message/my` - æ¥è¯¢å½åç¨æ·çæ¶æ¯å表 - `GET /system/message/unread/count` - æ¥è¯¢æªè¯»æ¶æ¯æ°é - `PUT /system/message/read/{messageId}` - æ è®°æ¶æ¯ä¸ºå·²è¯» - `PUT /system/message/read/all` - æ è®°æææ¶æ¯ä¸ºå·²è¯» ### 9. HospDataControllerï¼å»é¢æ°æ®ï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java` **注æ**ï¼è¯¥ Controller åæ¬å°±æ²¡ææé注解ï¼ä¿æä¸åï¼ - `GET /system/hospital/search` - æç´¢å»é¢ - `GET /system/hospital/detail` - è·åå»é¢è¯¦æ ### 10. Icd10Controllerï¼ICD-10ç¾ç åç±»ï¼ **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/Icd10Controller.java` **注æ**ï¼è¯¥ Controller åæ¬å°±æ²¡ææé注解ï¼ä¿æä¸åï¼ - `GET /system/icd10/search` - æç´¢ICD-10ç¾ç - `GET /system/icd10/detail` - è·åICD-10详æ ## å®å ¨è¯´æ 1. **ç»å½éªè¯ä»ç¶ææ**ï¼è½ç¶ç§»é¤äº `@PreAuthorize` æé注解ï¼ä½æææ¥å£ä»ç¶éè¦ç¨æ·ç»å½æè½è®¿é®ï¼éè¿ Spring Security çè®¤è¯æºå¶ï¼ã 2. **æ°æ®æéæ§å¶**ï¼ - é¨åæ¥å£å¨ä¸å¡å±ä»ç¶ä¼è¿è¡æ°æ®æéæ£æ¥ - ä¾å¦ï¼ç¨æ·åªè½æ¥çåæä½èªå·±æå¨é¨é¨æææéçæ°æ® 3. **åå°ç®¡çç³»ç»**ï¼ - åå°ç®¡çç³»ç»ï¼ruoyi-uiï¼ä»ç¶ä¿æåæçæéæ§å¶ - åªæ¯ app 端è°ç¨çæ¥å£ç§»é¤äºæééªè¯ ## å½±åèå´ - â APP 端ï¼å¯ä»¥æ£å¸¸è°ç¨ææä»»å¡ã车è¾ãç¨æ·ãé¨é¨çæ¥å£ - â åå°ç®¡çï¼ä¸åå½±åï¼æéæ§å¶éè¿å端路ç±åèåæéå®ç° - â å®å ¨æ§ï¼ç¨æ·ä»éç»å½ï¼åªæ¯æ éé ç½®ç»ç²åº¦çåè½æé ## æµè¯å»ºè®® 1. æµè¯ app 端ç»å½åæ¯å¦è½æ£å¸¸è°ç¨æææ¥å£ 2. æµè¯æªç»å½ç¨æ·æ¯å¦ä»ç¶æ æ³è®¿é®æ¥å£ï¼åºè¿å 401ï¼ 3. æµè¯åå°ç®¡çç³»ç»çæéæ§å¶æ¯å¦æ£å¸¸å·¥ä½ 4. éªè¯æ°æ®æéæ¯å¦çæï¼ç¨æ·åªè½æä½èªå·±æéèå´å çæ°æ®ï¼ ## åç»ä¼å建议 妿éè¦å¯¹ app 端ä¹å®æ½ç»ç²åº¦æéæ§å¶ï¼å¯ä»¥èèï¼ 1. å¨ `sys_role` 表ä¸ä¸º app ç¨æ·å建ä¸é¨çè§è² 2. é ç½®ç¸åºçèååæéæ è¯ 3. å¨ç¨æ·ç»å½æ¶åé 对åºçè§è²åæé 4. æ¢å¤æ¥å£ç `@PreAuthorize` 注解 ## ä¿®æ¹æ¥æ 2025-10-26 ruoyi-admin/src/main/java/com/ruoyi/web/controller/sqlserver/SqlServerDictionaryController.java
@@ -38,7 +38,6 @@ * * @return åæ®ç±»åå表 */ @PreAuthorize("@ss.hasPermi('sqlserver:dictionary:list')") @GetMapping("/serviceOrdAreaTypes") public AjaxResult getServiceOrdAreaTypes() { @@ -61,7 +60,6 @@ * * @return æå¡åç¼ç å表 */ @PreAuthorize("@ss.hasPermi('sqlserver:dictionary:list')") @GetMapping("/serviceOrderClass") public AjaxResult getServiceOrderClass() { @@ -84,7 +82,6 @@ * * @return è°åº¦åç¼ç å表 */ @PreAuthorize("@ss.hasPermi('sqlserver:dictionary:list')") @GetMapping("/dispatchOrderClass") public AjaxResult getDispatchOrderClass() { @@ -108,7 +105,6 @@ * * @return æå¡è®¢åç±»åå表 */ @PreAuthorize("@ss.hasPermi('sqlserver:dictionary:list')") @GetMapping("/serviceOrderTypes") public AjaxResult getServiceOrderTypes() { @@ -132,7 +128,6 @@ * * @return å»é¢ç§å®¤å表 */ @PreAuthorize("@ss.hasPermi('sqlserver:dictionary:list')") @GetMapping("/hospitalDepartments") public AjaxResult getHospitalDepartments() { ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
@@ -37,7 +37,6 @@ /** * è·åé¨é¨å表 */ @PreAuthorize("@ss.hasPermi('system:dept:list')") @GetMapping("/list") public AjaxResult list(SysDept dept) { @@ -48,7 +47,6 @@ /** * æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ */ @PreAuthorize("@ss.hasPermi('system:dept:list')") @GetMapping("/list/exclude/{deptId}") public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) { @@ -60,7 +58,6 @@ /** * æ ¹æ®é¨é¨ç¼å·è·å详ç»ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:dept:query')") @GetMapping(value = "/{deptId}") public AjaxResult getInfo(@PathVariable Long deptId) { ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMessageController.java
@@ -38,7 +38,6 @@ /** * æ¥è¯¢ç³»ç»æ¶æ¯å表 */ @PreAuthorize("@ss.hasPermi('system:message:list')") @GetMapping("/list") public TableDataInfo list(SysMessage sysMessage) { startPage(); @@ -69,7 +68,6 @@ /** * 导åºç³»ç»æ¶æ¯å表 */ @PreAuthorize("@ss.hasPermi('system:message:export')") @Log(title = "ç³»ç»æ¶æ¯", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, SysMessage sysMessage) { @@ -81,7 +79,6 @@ /** * è·åç³»ç»æ¶æ¯è¯¦ç»ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:message:query')") @GetMapping(value = "/{messageId}") public AjaxResult getInfo(@PathVariable("messageId") Long messageId) { return AjaxResult.success(sysMessageService.selectSysMessageByMessageId(messageId)); @@ -90,7 +87,6 @@ /** * æ°å¢ç³»ç»æ¶æ¯ */ @PreAuthorize("@ss.hasPermi('system:message:add')") @Log(title = "ç³»ç»æ¶æ¯", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody SysMessage sysMessage) { @@ -100,7 +96,6 @@ /** * ä¿®æ¹ç³»ç»æ¶æ¯ */ @PreAuthorize("@ss.hasPermi('system:message:edit')") @Log(title = "ç³»ç»æ¶æ¯", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody SysMessage sysMessage) { @@ -110,7 +105,6 @@ /** * å é¤ç³»ç»æ¶æ¯ */ @PreAuthorize("@ss.hasPermi('system:message:remove')") @Log(title = "ç³»ç»æ¶æ¯", businessType = BusinessType.DELETE) @DeleteMapping("/{messageIds}") public AjaxResult remove(@PathVariable Long[] messageIds) { ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -56,7 +56,6 @@ /** * è·åç¨æ·å表 */ @PreAuthorize("@ss.hasPermi('system:user:list')") @GetMapping("/list") public TableDataInfo list(SysUser user) { ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VehicleInfoController.java
@@ -36,7 +36,6 @@ /** * æ¥è¯¢è½¦è¾ä¿¡æ¯å表 */ @PreAuthorize("@ss.hasPermi('system:vehicle:list')") @GetMapping("/list") public TableDataInfo list(VehicleInfo vehicleInfo) { startPage(); @@ -47,7 +46,6 @@ /** * 导åºè½¦è¾ä¿¡æ¯å表 */ @PreAuthorize("@ss.hasPermi('system:vehicle:export')") @Log(title = "车è¾ä¿¡æ¯", businessType = BusinessType.EXPORT) @GetMapping("/export") public AjaxResult export(VehicleInfo vehicleInfo) { @@ -59,7 +57,6 @@ /** * è·å车è¾ä¿¡æ¯è¯¦ç»ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:vehicle:query')") @GetMapping(value = "/{vehicleId}") public AjaxResult getInfo(@PathVariable("vehicleId") Long vehicleId) { return success(vehicleInfoService.selectVehicleInfoById(vehicleId)); @@ -68,7 +65,6 @@ /** * æ°å¢è½¦è¾ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:vehicle:add')") @Log(title = "车è¾ä¿¡æ¯", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody VehicleInfo vehicleInfo) { @@ -78,7 +74,6 @@ /** * ä¿®æ¹è½¦è¾ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:vehicle:edit')") @Log(title = "车è¾ä¿¡æ¯", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody VehicleInfo vehicleInfo) { @@ -88,7 +83,6 @@ /** * å é¤è½¦è¾ä¿¡æ¯ */ @PreAuthorize("@ss.hasPermi('system:vehicle:remove')") @Log(title = "车è¾ä¿¡æ¯", businessType = BusinessType.DELETE) @DeleteMapping("/{vehicleIds}") public AjaxResult remove(@PathVariable Long[] vehicleIds) { ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
@@ -41,22 +41,34 @@ private ISysTaskService sysTaskService; /** * æ¥è¯¢ä»»å¡ç®¡çå表 * æ¥è¯¢ä»»å¡ç®¡çå表ï¼åå°ç®¡çç«¯ï¼ * 管çåæéï¼å¯ä»¥æ¥çææä»»å¡ */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/list") public TableDataInfo adminList(TaskQueryVO queryVO) { startPage(); List<SysTask> list = sysTaskService.selectSysTaskList(queryVO); return getDataTable(list); } /** * æ¥è¯¢ä»»å¡å表ï¼APPç«¯ï¼ * ä» æ¾ç¤ºå½åç¨æ·ç¸å ³çä»»å¡ï¼ * 1. å½åç¨æ·æå¨æºæçä»»å¡ * 2. å½åç¨æ·å建çä»»å¡ * 3. åé ç»å½åç¨æ·çä»»å¡ */ @GetMapping("/list") public TableDataInfo list(TaskQueryVO queryVO) { public TableDataInfo appList(TaskQueryVO queryVO) { // å¨å端èªå¨è·åå½åç¨æ·ä¿¡æ¯ï¼å®ç°ç»¼åæ¥è¯¢ // ç»¼åæ¥è¯¢ï¼å½åç¨æ·æå¨æºæä»»å¡ + å½åç¨æ·å建çä»»å¡ + åé ç»å½åç¨æ·çä»»å¡ Long currentUserId = getUserId(); Long currentDeptId = getDeptId(); // 妿å端没æä¼ éè¿äºåæ°ï¼å使ç¨å½åç»å½ç¨æ·ä¿¡æ¯ if (queryVO.getCreatorId() == null && queryVO.getAssigneeId() == null && queryVO.getDeptId() == null) { queryVO.setDeptId(currentDeptId); queryVO.setCreatorId(currentUserId); queryVO.setAssigneeId(currentUserId); } // APP端强å¶ä½¿ç¨å½åç»å½ç¨æ·ä¿¡æ¯è¿è¡è¿æ»¤ queryVO.setDeptId(currentDeptId); queryVO.setCreatorId(currentUserId); queryVO.setAssigneeId(currentUserId); startPage(); List<SysTask> list = sysTaskService.selectSysTaskList(queryVO); @@ -64,11 +76,11 @@ } /** * 导åºä»»å¡ç®¡çå表 * 导åºä»»å¡ç®¡çå表ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:export')") @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.EXPORT) @PostMapping("/export") @PostMapping("/admin/export") public void export(HttpServletResponse response, TaskQueryVO queryVO) { List<SysTask> list = sysTaskService.selectSysTaskList(queryVO); ExcelUtil<SysTask> util = new ExcelUtil<SysTask>(SysTask.class); @@ -76,61 +88,119 @@ } /** * è·åä»»å¡ç®¡ç详ç»ä¿¡æ¯ * è·åä»»å¡è¯¦ç»ä¿¡æ¯ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping(value = "/{taskId}") public AjaxResult getInfo(@PathVariable("taskId") Long taskId) { @GetMapping(value = "/admin/{taskId}") public AjaxResult adminGetInfo(@PathVariable("taskId") Long taskId) { return success(sysTaskService.getTaskDetail(taskId)); } /** * æ°å¢ä»»å¡ç®¡ç * è·åä»»å¡è¯¦ç»ä¿¡æ¯ï¼APPç«¯ï¼ */ @GetMapping(value = "/{taskId}") public AjaxResult appGetInfo(@PathVariable("taskId") Long taskId) { return success(sysTaskService.getTaskDetail(taskId)); } /** * æ°å¢ä»»å¡ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:add')") @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody TaskCreateVO createVO) { @PostMapping("/admin") public AjaxResult adminAdd(@RequestBody TaskCreateVO createVO) { return toAjax(sysTaskService.insertSysTask(createVO)); } /** * ä¿®æ¹ä»»å¡ç®¡ç * æ°å¢ä»»å¡ï¼APPç«¯ï¼ */ @Log(title = "ä»»å¡å建", businessType = BusinessType.INSERT) @PostMapping public AjaxResult appAdd(@RequestBody TaskCreateVO createVO) { return toAjax(sysTaskService.insertSysTask(createVO)); } /** * ä¿®æ¹ä»»å¡ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody TaskUpdateVO updateVO) { @PutMapping("/admin") public AjaxResult adminEdit(@RequestBody TaskUpdateVO updateVO) { return toAjax(sysTaskService.updateSysTask(updateVO)); } /** * å é¤ä»»å¡ç®¡ç * ä¿®æ¹ä»»å¡ï¼APPç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:remove')") @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.DELETE) @Log(title = "ä»»å¡ä¿®æ¹", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult appEdit(@RequestBody TaskUpdateVO updateVO) { return toAjax(sysTaskService.updateSysTask(updateVO)); } /** * å é¤ä»»å¡ï¼APPç«¯ï¼ */ @Log(title = "ä»»å¡å é¤", businessType = BusinessType.DELETE) @DeleteMapping("/{taskIds}") public AjaxResult remove(@PathVariable Long[] taskIds) { public AjaxResult appRemove(@PathVariable Long[] taskIds) { return toAjax(sysTaskService.deleteSysTaskByTaskIds(taskIds)); } /** * åé ä»»å¡ * å é¤ä»»å¡ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:assign')") @PreAuthorize("@ss.hasPermi('task:general:remove')") @Log(title = "ä»»å¡ç®¡ç", businessType = BusinessType.DELETE) @DeleteMapping("/admin/{taskIds}") public AjaxResult adminRemove(@PathVariable Long[] taskIds) { return toAjax(sysTaskService.deleteSysTaskByTaskIds(taskIds)); } /** * åé ä»»å¡ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "ä»»å¡åé ", businessType = BusinessType.UPDATE) @PutMapping("/{taskId}/assign") public AjaxResult assignTask(@PathVariable Long taskId, @RequestBody AssignTaskRequest request) { @PutMapping("/admin/{taskId}/assign") public AjaxResult adminAssignTask(@PathVariable Long taskId, @RequestBody AssignTaskRequest request) { return toAjax(sysTaskService.assignTask(taskId, request.getAssigneeId(), request.getRemark())); } /** * æ´æ°ä»»å¡ç¶æ * åé ä»»å¡ï¼APPç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:status')") @Log(title = "ä»»å¡åé ", businessType = BusinessType.UPDATE) @PutMapping("/{taskId}/assign") public AjaxResult appAssignTask(@PathVariable Long taskId, @RequestBody AssignTaskRequest request) { return toAjax(sysTaskService.assignTask(taskId, request.getAssigneeId(), request.getRemark())); } /** * æ´æ°ä»»å¡ç¶æï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "ä»»å¡ç¶æåæ´", businessType = BusinessType.UPDATE) @PutMapping("/admin/{taskId}/status") public AjaxResult adminChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { TaskStatus newStatus = TaskStatus.getByCode(request.getTaskStatus()); if (newStatus == null) { return error("æ æçä»»å¡ç¶æ"); } return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark())); } /** * æ´æ°ä»»å¡ç¶æï¼APPç«¯ï¼ * æ¯æGPSä½ç½®ä¿¡æ¯ä¸æ¥ */ @Log(title = "ä»»å¡ç¶æåæ´", businessType = BusinessType.UPDATE) @PutMapping("/{taskId}/status") public AjaxResult changeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { public AjaxResult appChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { TaskStatus newStatus = TaskStatus.getByCode(request.getTaskStatus()); if (newStatus == null) { return error("æ æçä»»å¡ç¶æ"); @@ -157,9 +227,8 @@ } /** * æ¥è¯¢ä»»å¡ç»è®¡ä¿¡æ¯ * æ¥è¯¢ä»»å¡ç»è®¡ä¿¡æ¯ï¼APPç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/statistics") public AjaxResult getStatistics() { TaskStatisticsVO statistics = sysTaskService.getTaskStatistics(); @@ -167,9 +236,18 @@ } /** * æ¥è¯¢è¶ æ¶ä»»å¡å表 * æ¥è¯¢ä»»å¡ç»è®¡ä¿¡æ¯ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/statistics") public AjaxResult adminGetStatistics() { TaskStatisticsVO statistics = sysTaskService.getTaskStatistics(); return success(statistics); } /** * æ¥è¯¢è¶ æ¶ä»»å¡å表ï¼APPç«¯ï¼ */ @GetMapping("/overdue") public AjaxResult getOverdueTasks() { List<SysTask> list = sysTaskService.selectOverdueTasks(); @@ -177,9 +255,18 @@ } /** * æ¥è¯¢æçä»»å¡å表 * æ¥è¯¢è¶ æ¶ä»»å¡å表ï¼åå°ç®¡çç«¯ï¼ */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/overdue") public AjaxResult adminGetOverdueTasks() { List<SysTask> list = sysTaskService.selectOverdueTasks(); return success(list); } /** * æ¥è¯¢æçä»»å¡å表ï¼APPç«¯ï¼ */ @GetMapping("/my") public AjaxResult getMyTasks() { List<SysTask> list = sysTaskService.selectMyTasks(getUserId()); ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskVehicleController.java
@@ -34,7 +34,6 @@ /** * æ¥è¯¢ä»»å¡å ³èç车è¾å表 */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/list/{taskId}") public AjaxResult list(@PathVariable("taskId") Long taskId) { List<SysTaskVehicle> list = sysTaskService.getTaskVehicles(taskId); @@ -44,7 +43,6 @@ /** * æ¥è¯¢å¯ç¨è½¦è¾å表 */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/available") public AjaxResult getAvailableVehicles(@RequestParam Long deptId, @RequestParam(required = false) String taskType) { List<SysTaskVehicle> list = sysTaskService.getAvailableVehicles(deptId, taskType); @@ -54,7 +52,6 @@ /** * åé 车è¾ç»ä»»å¡ */ @PreAuthorize("@ss.hasPermi('task:general:assign')") @Log(title = "ä»»å¡è½¦è¾åé ", businessType = BusinessType.INSERT) @PostMapping("/assign/{taskId}") public AjaxResult assignVehicle(@PathVariable("taskId") Long taskId, @RequestBody AssignVehicleRequest request) { @@ -73,7 +70,6 @@ /** * æ¹éåé 车è¾ç»ä»»å¡ */ @PreAuthorize("@ss.hasPermi('task:general:assign')") @Log(title = "ä»»å¡è½¦è¾æ¹éåé ", businessType = BusinessType.INSERT) @PostMapping("/assign-batch/{taskId}") public AjaxResult assignVehicles(@PathVariable("taskId") Long taskId, @RequestBody BatchAssignVehicleRequest request) { @@ -94,7 +90,6 @@ /** * åæ¶ä»»å¡è½¦è¾åé */ @PreAuthorize("@ss.hasPermi('task:general:assign')") @Log(title = "åæ¶ä»»å¡è½¦è¾åé ", businessType = BusinessType.DELETE) @DeleteMapping("/{taskId}/{vehicleId}") public AjaxResult unassignVehicle(@PathVariable("taskId") Long taskId, @PathVariable("vehicleId") Long vehicleId) { ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml
@@ -30,20 +30,27 @@ HospIntroducerID, HospIntroducerDate, HospLevel FROM HospData WHERE 1=1 <!-- å°åè¿æ»¤ï¼å¯¹HospProvince, HospCity, HospAreaè¿è¡ORå¹é --> <if test="region != null and region != ''"> AND (HopsProvince LIKE '%' + #{region} + '%' OR HopsCity LIKE '%' + #{region} + '%' OR HopsArea LIKE '%' + #{region} + '%') </if> <!-- å ³é®è¯è¿æ»¤ï¼å¯¹å¤ä¸ªå段è¿è¡ORå¹é --> <!-- æ keyword å°±åªç¨ keywordï¼ä¸ç¨ region --> <if test="keyword != null and keyword != ''"> AND (HopsProvince LIKE '%' + #{keyword} + '%' OR HopsCity LIKE '%' + #{keyword} + '%' OR HopsArea LIKE '%' + #{keyword} + '%' OR HospAddress LIKE '%' + #{keyword} + '%' OR HospName LIKE '%' + #{keyword} + '%' OR HospShort LIKE '%' + #{keyword} + '%') AND ( HopsProvince LIKE '%' + #{keyword} + '%' OR HopsCity LIKE '%' + #{keyword} + '%' OR HopsArea LIKE '%' + #{keyword} + '%' OR HospAddress LIKE '%' + #{keyword} + '%' OR HospName LIKE '%' + #{keyword} + '%' OR HospShort LIKE '%' + #{keyword} + '%' ) </if> <!-- 没æ keyword æ¶æç¨ region --> <if test="(keyword == null or keyword == '') and (region != null and region != '')"> AND ( HopsProvince LIKE '%' + #{region} + '%' OR HopsCity LIKE '%' + #{region} + '%' OR HopsArea LIKE '%' + #{region} + '%' OR HospAddress LIKE '%' + #{region} + '%' OR HospName LIKE '%' + #{region} + '%' OR HospShort LIKE '%' + #{region} + '%' ) </if> AND (HospState IS NULL OR HospState = 1) ORDER BY HospName ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -51,8 +51,7 @@ <if test="dispatchOrderClass != null and dispatchOrderClass != ''"> AND dispatch_order_class = #{dispatchOrderClass} </if> <!-- æ°æ®èå´è¿æ»¤ --> ${params.dataScope} order by d.parent_id, d.order_num </select> ruoyi-ui/src/api/task.js
@@ -1,86 +1,86 @@ import request from '@/utils/request' // æ¥è¯¢ä»»å¡ç®¡çå表 // æ¥è¯¢ä»»å¡ç®¡çå表 (åå°ç®¡ç端) export function listTask(query) { return request({ url: '/task/list', url: '/task/admin/list', method: 'get', params: query }) } // æ¥è¯¢ä»»å¡ç®¡çè¯¦ç» // æ¥è¯¢ä»»å¡ç®¡çè¯¦ç» (åå°ç®¡ç端) export function getTask(taskId) { return request({ url: '/task/' + taskId, url: '/task/admin/' + taskId, method: 'get' }) } // æ°å¢ä»»å¡ç®¡ç // æ°å¢ä»»å¡ç®¡ç (åå°ç®¡ç端) export function addTask(data) { return request({ url: '/task', url: '/task/admin', method: 'post', data: data }) } // ä¿®æ¹ä»»å¡ç®¡ç // ä¿®æ¹ä»»å¡ç®¡ç (åå°ç®¡ç端) export function updateTask(data) { return request({ url: '/task', url: '/task/admin', method: 'put', data: data }) } // å é¤ä»»å¡ç®¡ç // å é¤ä»»å¡ç®¡ç (åå°ç®¡ç端) export function delTask(taskIds) { return request({ url: '/task/' + taskIds, url: '/task/admin/' + taskIds, method: 'delete' }) } // åé ä»»å¡ // åé ä»»å¡ (åå°ç®¡ç端) export function assignTask(taskId, data) { return request({ url: '/task/' + taskId + '/assign', url: '/task/admin/' + taskId + '/assign', method: 'put', data: data }) } // æ´æ°ä»»å¡ç¶æ // æ´æ°ä»»å¡ç¶æ (åå°ç®¡ç端) export function changeTaskStatus(taskId, data) { return request({ url: '/task/' + taskId + '/status', url: '/task/admin/' + taskId + '/status', method: 'put', data: data }) } // æ¥è¯¢ä»»å¡ç»è®¡ä¿¡æ¯ // æ¥è¯¢ä»»å¡ç»è®¡ä¿¡æ¯ (åå°ç®¡ç端) export function getTaskStatistics() { return request({ url: '/task/statistics', url: '/task/admin/statistics', method: 'get' }) } // æ¥è¯¢è¶ æ¶ä»»å¡å表 // æ¥è¯¢è¶ æ¶ä»»å¡å表 (åå°ç®¡ç端) export function getOverdueTasks() { return request({ url: '/task/overdue', url: '/task/admin/overdue', method: 'get' }) } // æ¥è¯¢æçä»»å¡å表 // æ¥è¯¢æçä»»å¡å表 (åå°ç®¡ç端 - ä» ä¾åè) export function getMyTasks() { return request({ url: '/task/my', url: '/task/app/my', method: 'get' }) } ruoyi-ui/src/views/task/general/detail.vue
@@ -32,45 +32,92 @@ <!-- æ¥æè½¬è¿ä»»å¡æ©å±ä¿¡æ¯ --> <el-descriptions v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo" title="æ¥æè½¬è¿ä¿¡æ¯" :column="2" border style="margin-top: 20px;"> <el-descriptions-item label="æ£è å§å">{{ taskDetail.emergencyInfo.patientName }}</el-descriptions-item> <el-descriptions-item label="æ£è æ§å«"> <dict-tag :options="dict.type.sys_user_sex" :value="taskDetail.emergencyInfo.patientGender"/> <el-descriptions-item label="è系人"> <span v-if="taskDetail.emergencyInfo.contactPerson">{{ taskDetail.emergencyInfo.contactPerson }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="æ£è å¹´é¾">{{ taskDetail.emergencyInfo.patientAge }}</el-descriptions-item> <el-descriptions-item label="èç³»çµè¯">{{ taskDetail.emergencyInfo.contactPhone }}</el-descriptions-item> <el-descriptions-item label="æ¥éå»é¢" :span="2">{{ taskDetail.emergencyInfo.hospitalName }}</el-descriptions-item> <el-descriptions-item label="å°±è¯ç§å®¤" :span="2"> <dict-tag v-if="taskDetail.emergencyInfo.hospitalDepartment" :options="dict.type.hospital_department" :value="taskDetail.emergencyInfo.hospitalDepartment"/> <el-descriptions-item label="èç³»çµè¯"> <span v-if="taskDetail.emergencyInfo.contactPhone">{{ taskDetail.emergencyInfo.contactPhone }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="æ£è å§å"> <span v-if="taskDetail.emergencyInfo.patientName">{{ taskDetail.emergencyInfo.patientName }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="æ£è æ§å«"> <dict-tag v-if="taskDetail.emergencyInfo.patientGender" :options="dict.type.sys_user_sex" :value="taskDetail.emergencyInfo.patientGender"/> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="身份信æ¯" :span="2"> <span v-if="taskDetail.emergencyInfo.patientIdCard">{{ taskDetail.emergencyInfo.patientIdCard }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="ç æ æè¿°" :span="2"> <span v-if="taskDetail.emergencyInfo.illnessDescription">{{ taskDetail.emergencyInfo.illnessDescription }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="ç¹æ®éæ±" :span="2"> <span v-if="taskDetail.emergencyInfo.specialRequirements">{{ taskDetail.emergencyInfo.specialRequirements }}</span> </el-descriptions> <!-- æ§ç³»ç»åæ¥ä¿¡æ¯ï¼ä» æ¥æè½¬è¿ä»»å¡æ¾ç¤ºï¼ --> <el-descriptions v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo" title="æ§ç³»ç»åæ¥ä¿¡æ¯" :column="2" border style="margin-top: 20px;"> <el-descriptions-item label="æå¡ååæ¥ç¶æ"> <el-tag v-if="taskDetail.emergencyInfo.syncStatus === 0" type="info" size="small"> <i class="el-icon-warning"></i> æªåæ¥ </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 1" type="warning" size="small"> <i class="el-icon-loading"></i> åæ¥ä¸ </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 2" type="success" size="small"> <i class="el-icon-success"></i> 忥æå </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 3" type="danger" size="small"> <i class="el-icon-error"></i> åæ¥å¤±è´¥ </el-tag> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="æ¯å¦éè¦æ æ¶"> <el-tag v-if="taskDetail.emergencyInfo.needsStretcher == 1" type="success" size="small">æ¯</el-tag> <el-tag v-else type="info" size="small">å¦</el-tag> </el-descriptions-item> <el-descriptions-item label="æ¯å¦éè¦è½®æ¤ "> <el-tag v-if="taskDetail.emergencyInfo.needsWheelchair == 1" type="success" size="small">æ¯</el-tag> <el-tag v-else type="info" size="small">å¦</el-tag> </el-descriptions-item> <el-descriptions-item label="æ¯å¦éè¦æ°§æ°"> <el-tag v-if="taskDetail.emergencyInfo.needsOxygen == 1" type="success" size="small">æ¯</el-tag> <el-tag v-else type="info" size="small">å¦</el-tag> </el-descriptions-item> <el-descriptions-item label="ç´§æ¥ç¨åº¦"> <el-tag v-if="taskDetail.emergencyInfo.urgencyLevel === 'HIGH'" type="danger" size="small">ç´§æ¥</el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.urgencyLevel === 'MEDIUM'" type="warning" size="small">ä¸è¬</el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.urgencyLevel === 'LOW'" type="info" size="small">䏿¥</el-tag> <el-descriptions-item label="æå¡åå·"> <span v-if="taskDetail.emergencyInfo.legacyServiceOrdId"> <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyServiceOrdId }}</el-tag> </span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="éªå人æ°">{{ taskDetail.emergencyInfo.companionCount || 0 }} 人</el-descriptions-item> <el-descriptions-item label="é¢ä¼°è´¹ç¨">{{ taskDetail.emergencyInfo.estimatedCost || '--' }} å </el-descriptions-item> <el-descriptions-item label="æå¡å忥æ¶é´"> <span v-if="taskDetail.emergencyInfo.syncTime">{{ parseTime(taskDetail.emergencyInfo.syncTime) }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="æå¡å忥é误" :span="1"> <span v-if="taskDetail.emergencyInfo.syncErrorMsg" style="color: #F56C6C;">{{ taskDetail.emergencyInfo.syncErrorMsg }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="è°åº¦ååæ¥ç¶æ"> <el-tag v-if="taskDetail.emergencyInfo.dispatchSyncStatus === 0" type="info" size="small"> <i class="el-icon-warning"></i> æªåæ¥ </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 1" type="warning" size="small"> <i class="el-icon-loading"></i> åæ¥ä¸ </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 2" type="success" size="small"> <i class="el-icon-success"></i> 忥æå </el-tag> <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 3" type="danger" size="small"> <i class="el-icon-error"></i> åæ¥å¤±è´¥ </el-tag> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="è°åº¦åå·"> <span v-if="taskDetail.emergencyInfo.legacyDispatchOrdId"> <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyDispatchOrdId }}</el-tag> </span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="è°åº¦å忥æ¶é´"> <span v-if="taskDetail.emergencyInfo.dispatchSyncTime">{{ parseTime(taskDetail.emergencyInfo.dispatchSyncTime) }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> <el-descriptions-item label="è°åº¦å忥é误" :span="1"> <span v-if="taskDetail.emergencyInfo.dispatchSyncErrorMsg" style="color: #F56C6C;">{{ taskDetail.emergencyInfo.dispatchSyncErrorMsg }}</span> <span v-else style="color: #C0C4CC;">--</span> </el-descriptions-item> </el-descriptions> <!-- ç¦ç¥è½¦ä»»å¡æ©å±ä¿¡æ¯ --> ruoyi-ui/src/views/task/general/index.vue
@@ -94,12 +94,13 @@ <el-table v-loading="loading" :data="taskList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column label="ä»»å¡ç¼å·" align="center" prop="taskCode"> <el-table-column label="ä»»å¡ç¼å·" align="center" prop="taskCode" min-width="180"> <template slot-scope="scope"> <el-button type="text" @click="handleView(scope.row)" v-hasPermi="['task:general:query']" style="font-family: 'Courier New', monospace; font-size: 13px;" >{{ scope.row.taskCode }}</el-button> </template> </el-table-column> @@ -108,6 +109,24 @@ <dict-tag :options="dict.type.sys_task_type" :value="scope.row.taskType"/> <el-tag v-if="scope.row.taskType === 'EMERGENCY_TRANSFER'" type="danger" size="mini" style="margin-left: 5px;"> <i class="el-icon-warning"></i> </el-tag> </template> </el-table-column> <el-table-column label="åæ¥ç¶æ" align="center" prop="syncStatus" width="120" v-if="hasEmergencyTask"> <template slot-scope="scope"> <span v-if="scope.row.taskType !== 'EMERGENCY_TRANSFER'" style="color: #C0C4CC;">--</span> <el-tag v-else-if="!scope.row.emergencyInfo" type="info" size="mini">--</el-tag> <el-tag v-else-if="scope.row.emergencyInfo.syncStatus === 0" type="info" size="mini"> <i class="el-icon-warning"></i> æªåæ¥ </el-tag> <el-tag v-else-if="scope.row.emergencyInfo.syncStatus === 1" type="warning" size="mini"> <i class="el-icon-loading"></i> åæ¥ä¸ </el-tag> <el-tag v-else-if="scope.row.emergencyInfo.syncStatus === 2" type="success" size="mini"> <i class="el-icon-success"></i> 已忥 </el-tag> <el-tag v-else-if="scope.row.emergencyInfo.syncStatus === 3" type="danger" size="mini"> <i class="el-icon-error"></i> åæ¥å¤±è´¥ </el-tag> </template> </el-table-column> @@ -126,14 +145,11 @@ </el-table-column> <el-table-column label="计åå¼å§æ¶é´" align="center" prop="plannedStartTime" width="180"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.plannedStartTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span v-if="scope.row.plannedStartTime">{{ parseTime(scope.row.plannedStartTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span v-else style="color: #C0C4CC;">--</span> </template> </el-table-column> <el-table-column label="计åç»ææ¶é´" align="center" prop="plannedEndTime" width="180"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.plannedEndTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> </template> </el-table-column> <el-table-column label="å建人" align="center" prop="creatorName" /> <el-table-column label="æ§è¡äºº" align="center" prop="assigneeName" /> <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> @@ -400,6 +416,8 @@ total: 0, // ä»»å¡ç®¡çè¡¨æ ¼æ°æ® taskList: [], // æ¯å¦ææ¥æè½¬è¿ä»»å¡ï¼ç¨äºæ§å¶åæ¥ç¶æåæ¾ç¤ºï¼ hasEmergencyTask: false, // å¼¹åºå±æ é¢ title: "", // æ¯å¦æ¾ç¤ºå¼¹åºå± @@ -472,6 +490,8 @@ listTask(this.queryParams).then(response => { this.taskList = response.rows; this.total = response.total; // æ£æ¥æ¯å¦ææ¥æè½¬è¿ä»»å¡ï¼ç¨äºæ§å¶åæ¥ç¶æç¸å ³åçæ¾ç¤º this.hasEmergencyTask = this.taskList.some(task => task.taskType === 'EMERGENCY_TRANSFER'); this.loading = false; }); }, ruoyi-ui/src/views/task/¾Éϵͳͬ²½×´Ì¬ÏÔʾ¹¦ÄÜ˵Ã÷.md
New file @@ -0,0 +1,164 @@ # æ§ç³»ç»åæ¥ç¶ææ¾ç¤ºåè½è¯´æ ## ä¸ãåè½æ¦è¿° å¨ ruoyi-ui 项ç®çä»»å¡å表åä»»å¡è¯¦æ 页é¢ä¸ï¼æ°å¢äºæ§ç³»ç»åæ¥ç¶æåç¸å ³åå·çæ¾ç¤ºåè½ï¼æ¹ä¾¿ç®¡çå宿¶æ¥çæ¥æè½¬è¿ä»»å¡ä¸æ§ç³»ç»ç忥æ åµã ## äºãæ¶åæä»¶ ### 1. ä»»å¡åè¡¨é¡µé¢ **æä»¶è·¯å¾**: `ruoyi-ui/src/views/task/general/index.vue` **ä¿®æ¹å 容**: - æ°å¢ `hasEmergencyTask` æ°æ®å±æ§ï¼ç¨äºå¤æåè¡¨ä¸æ¯å¦å 嫿¥æè½¬è¿ä»»å¡ - æ°å¢ **åæ¥ç¶æ** åï¼æ¾ç¤ºæå¡ååæ¥ç¶æï¼æªåæ¥ã忥ä¸ã已忥ãåæ¥å¤±è´¥ï¼ - æ°å¢ **æå¡åå·** åï¼æ¾ç¤ºæ§ç³»ç»è¿åç ServiceOrdID - æ°å¢ **è°åº¦åå·** åï¼æ¾ç¤ºæ§ç³»ç»è¿åç DispatchOrdID - è¿äºåä» å¨å表ä¸å卿¥æè½¬è¿ä»»å¡æ¶æ¾ç¤ºï¼`v-if="hasEmergencyTask"`ï¼ ### 2. ä»»å¡è¯¦æ é¡µé¢ **æä»¶è·¯å¾**: `ruoyi-ui/src/views/task/general/detail.vue` **ä¿®æ¹å 容**: - æ°å¢ **æ§ç³»ç»åæ¥ä¿¡æ¯** æè¿°å表åºå - æ¾ç¤ºæå¡ååæ¥ç¶æãæå¡åå·ã忥æ¶é´ã忥éè¯¯ä¿¡æ¯ - æ¾ç¤ºè°åº¦ååæ¥ç¶æãè°åº¦åå·ã忥æ¶é´ã忥éè¯¯ä¿¡æ¯ - 该åºåä» å¨æ¥æè½¬è¿ä»»å¡è¯¦æ 页æ¾ç¤º ## ä¸ãåæ¥ç¶æè¯´æ ### åæ¥ç¶æå¼åå«ä¹ | ç¶æå¼ | å«ä¹ | 徿 é¢è² | æ¾ç¤ºææ¬ | |--------|------|----------|----------| | 0 | æªåæ¥ | ç°è²ï¼infoï¼ | <i class="el-icon-warning"></i> æªåæ¥ | | 1 | åæ¥ä¸ | æ©è²ï¼warningï¼ | <i class="el-icon-loading"></i> åæ¥ä¸ | | 2 | 忥æå | 绿è²ï¼successï¼ | <i class="el-icon-success"></i> 已忥/忥æå | | 3 | åæ¥å¤±è´¥ | 红è²ï¼dangerï¼ | <i class="el-icon-error"></i> åæ¥å¤±è´¥ | ### æå¡å忥ä¸è°åº¦å忥 **æå¡å忥** (`syncStatus`): - å¯¹åºæ§ç³»ç» `admin_save_19.gds` æ¥å£ - 忥æååè¿å `ServiceOrdID`ï¼åå¨å¨ `legacy_service_ord_id` åæ®µ - ç± `LegacySystemSyncTask.syncPendingTasks()` 宿¶ä»»å¡æ§è¡ **è°åº¦å忥** (`dispatchSyncStatus`): - å¯¹åºæ§ç³»ç» `admin_save_24.asp` æ¥å£ - 忥æååè¿å `DispatchOrdID`ï¼åå¨å¨ `legacy_dispatch_ord_id` åæ®µ - ç± `LegacySystemSyncTask.syncPendingDispatchOrders()` 宿¶ä»»å¡æ§è¡ - ä¾èµæå¡å忥宿åæè½æ§è¡ ## åãæ°æ®æ¥æº ### å端å®ä½ç±»å段 **SysTask å®ä½** (`sys_task` 表): - `legacySynced`: æ§ç³»ç»åæ¥æ è®°ï¼0-æªåæ¥ï¼1-å·²åæ¥ï¼ **SysTaskEmergency å®ä½** (`sys_task_emergency` 表): æå¡åç¸å ³: - `legacyServiceOrdId`: æ§ç³»ç»æå¡åID - `syncStatus`: æå¡ååæ¥ç¶æ - `syncTime`: æå¡å忥æ¶é´ - `syncErrorMsg`: æå¡å忥éè¯¯ä¿¡æ¯ è°åº¦åç¸å ³: - `legacyDispatchOrdId`: æ§ç³»ç»è°åº¦åID - `dispatchSyncStatus`: è°åº¦ååæ¥ç¶æ - `dispatchSyncTime`: è°åº¦å忥æ¶é´ - `dispatchSyncErrorMsg`: è°åº¦å忥éè¯¯ä¿¡æ¯ ### åç«¯æ°æ®è®¿é®è·¯å¾ å¨ä»»å¡å表ä¸: ```javascript // åæ¥ç¶æ scope.row.emergencyInfo.syncStatus scope.row.emergencyInfo.dispatchSyncStatus // åå· scope.row.emergencyInfo.legacyServiceOrdId scope.row.emergencyInfo.legacyDispatchOrdId ``` å¨ä»»å¡è¯¦æ ä¸: ```javascript // æå¡ååæ¥ä¿¡æ¯ taskDetail.emergencyInfo.syncStatus taskDetail.emergencyInfo.legacyServiceOrdId taskDetail.emergencyInfo.syncTime taskDetail.emergencyInfo.syncErrorMsg // è°åº¦ååæ¥ä¿¡æ¯ taskDetail.emergencyInfo.dispatchSyncStatus taskDetail.emergencyInfo.legacyDispatchOrdId taskDetail.emergencyInfo.dispatchSyncTime taskDetail.emergencyInfo.dispatchSyncErrorMsg ``` ## äºãæ¾ç¤ºé»è¾ ### ä»»å¡å表æ¾ç¤ºè§å 1. **åæ¥ç¶æåãæå¡åå·åãè°åº¦åå·å**ä» å¨å表ä¸å卿¥æè½¬è¿ä»»å¡æ¶æ¾ç¤º 2. 鿥æè½¬è¿ä»»å¡å¨è¿äºå䏿¾ç¤º `--` 3. æ¥æè½¬è¿ä»»å¡æ ¹æ® `emergencyInfo` åæ®µå¤æ: - 妿 `emergencyInfo` ä¸ºç©ºï¼æ¾ç¤º `--` - 妿 `emergencyInfo` åå¨ï¼æ ¹æ®å¯¹åºå段æ¾ç¤ºå ·ä½å 容 ### ä»»å¡è¯¦æ æ¾ç¤ºè§å 1. **æ§ç³»ç»åæ¥ä¿¡æ¯**åºåä» å¨æ¥æè½¬è¿ä»»å¡è¯¦æ 页æ¾ç¤º 2. æ¡ä»¶: `taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo` 3. ææåæ®µä¸ºç©ºæ¶æ¾ç¤º `--` 4. é误信æ¯ä»¥çº¢è²ææ¬æ¾ç¤º ## å ã使ç¨åºæ¯ ### 1. 管çåçæ§åæ¥ç¶æ 管çåå¯ä»¥å¨ä»»å¡å表ä¸å¿«éæ¥çåªäºæ¥æè½¬è¿ä»»å¡å·²å®æä¸æ§ç³»ç»ç忥ï¼åªäºåæ¥å¤±è´¥éè¦å¤çã ### 2. é®é¢ææ¥ å½åæ¥å¤±è´¥æ¶ï¼å¯ä»¥å¨ä»»å¡è¯¦æ 页æ¥ç详ç»çé误信æ¯ï¼å¸®å©ææ¯äººåå®ä½é®é¢ã ### 3. æ°æ®è¿½æº¯ éè¿æå¡åå·åè°åº¦åå·ï¼å¯ä»¥å¨æ§ç³»ç»ä¸æ¥è¯¢å¯¹åºçåæ®ï¼å®ç°æ°æ§ç³»ç»æ°æ®çåå追溯ã ## ä¸ã注æäºé¡¹ 1. **æéæ§å¶**: 页颿¾ç¤ºéµå¾ªåæçæéæ§å¶è§å 2. **æ§è½èè**: å表æ¥è¯¢æ¶éè¦å ³è `sys_task_emergency` 表ï¼ç¡®ä¿ Mapper XML ä¸å·²æ£ç¡®é ç½®å ³èæ¥è¯¢ 3. **鿥æä»»å¡**: å ¶ä»ç±»åä»»å¡ï¼å¦ç¦ç¥è½¦ãæ®éä»»å¡ï¼ä¸æ¾ç¤ºåæ¥ä¿¡æ¯ 4. **宿¶ä»»å¡**: åæ¥ç¶æç±åå°å®æ¶ä»»å¡æ´æ°ï¼å端åªè´è´£å±ç¤º ## å «ãåç»ä¼å建议 1. **æå¨éè¯åè½**: å¨è¯¦æ 页添å "鿰忥"æé®ï¼å 许管çåæå¨è§¦å忥 2. **忥æ¥å¿**: è®°å½æ¯æ¬¡åæ¥çè¯¦ç»æ¥å¿ï¼æ¹ä¾¿é®é¢è¿½æº¯ 3. **æ¶æ¯éç¥**: åæ¥å¤±è´¥æ¶éè¿ç³»ç»æ¶æ¯æé®ä»¶éç¥ç¸å ³äººå 4. **æ¹é忥**: å¨å表页æä¾æ¹é鿰忥åè½ ## ä¹ãç¸å ³å®æ¶ä»»å¡ ### LegacySystemSyncTask **Cron 表达å¼**: - æå¡å忥: `0 */10 * * * ?` (æ¯10åéæ§è¡ä¸æ¬¡) - è°åº¦å忥: `0 5,15,25,35,45,55 * * * ?` (æ¯å°æ¶ç5ã15ã25ã35ã45ã55åæ§è¡) **é ç½®ä½ç½®**: `ruoyi-quartz` 模å **ä»»å¡é»è¾**: 1. æ¥è¯¢æªåæ¥æåæ¥å¤±è´¥çæ¥æè½¬è¿ä»»å¡ 2. è°ç¨æ§ç³»ç» ASP æ¥å£ 3. æ´æ°åæ¥ç¶æååå· 4. è®°å½åæ¥æ¶é´åéè¯¯ä¿¡æ¯ --- **ææ¡£çæ¬**: v1.0 **åå»ºæ¥æ**: 2025-01-XX **æåæ´æ°**: 2025-01-XX **ç»´æ¤äººå**: ç³»ç»ç®¡çå ÈÎÎñ½Ó¿Ú²ð·Ö˵Ã÷.md
New file @@ -0,0 +1,422 @@ # 任塿¥å£æåè¯´æææ¡£ ## ä¸ãä¿®æ¹èæ¯ åæç `/task/list` çæ¥å£åæ¶è¢« APP 端ååå°ç®¡ç端使ç¨ï¼å¯¼è´ä»¥ä¸é®é¢ï¼ 1. **æéæ··ä¹±**ï¼åå°ç®¡çåæ æ³æ¥çææä»»å¡ï¼åªè½çå°å½åç¨æ·ç¸å ³çä»»å¡ 2. **ä¸å¡é»è¾å²çª**ï¼APP 端éè¦è¿æ»¤ç¨æ·æ°æ®ï¼åå°éè¦æ¥çå ¨é¨æ°æ® 3. **å®å ¨éæ£**ï¼APP 端å管çç«¯å ±ç¨æ¥å£ï¼æéæ§å¶å°é¾ ## äºãè§£å³æ¹æ¡ **ä¿çåæ APP 端æ¥å£**ï¼åæ¶æ°å¢åå°ç®¡ç端ç¬ç«æ¥å£ï¼ - **APP 端æ¥å£**ï¼ä¿æåæè·¯å¾ `/task/*`ï¼æ æé注解ï¼èªå¨è¿æ»¤å½åç¨æ·æ°æ® - **åå°ç®¡ç端æ¥å£**ï¼æ°å¢è·¯å¾åç¼ `/task/admin/*`ï¼å¸¦æé注解ï¼ç®¡çå坿¥çæææ°æ® ## ä¸ãæ¶åæä»¶ ### 1. å端 Controller **æä»¶è·¯å¾**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java` ### 2. APP 端 API **æä»¶è·¯å¾**: `app/api/task.js` ### 3. åå°ç®¡ç端 API **æä»¶è·¯å¾**: `ruoyi-ui/src/api/task.js` ## åãæ¥å£å¯¹ç §è¡¨ ### 4.1 ä»»å¡å表æ¥å£ | åè½ | APP 端 | åå°ç®¡ç端 | 说æ | |------|--------|-----------|------| | æ¥è¯¢ä»»å¡å表 | `GET /task/list` | `GET /task/admin/list` | APPç«¯è¿æ»¤å½åç¨æ·ï¼åå°å¯æ¥çå ¨é¨ | | æ¥è¯¢ä»»å¡è¯¦æ | `GET /task/{taskId}` | `GET /task/admin/{taskId}` | è·åå个任å¡è¯¦æ | | æ°å¢ä»»å¡ | `POST /task` | `POST /task/admin` | å建æ°ä»»å¡ | | ä¿®æ¹ä»»å¡ | `PUT /task` | `PUT /task/admin` | æ´æ°ä»»å¡ä¿¡æ¯ | | å é¤ä»»å¡ | `DELETE /task/{taskIds}` | `DELETE /task/admin/{taskIds}` | å é¤ä»»å¡ | ### 4.2 任塿使¥å£ | åè½ | APP 端 | åå°ç®¡ç端 | 说æ | |------|--------|-----------|------| | åé ä»»å¡ | `PUT /task/{taskId}/assign` | `PUT /task/admin/{taskId}/assign` | åé æ§è¡äºº | | æ´æ°ç¶æ | `PUT /task/{taskId}/status` | `PUT /task/admin/{taskId}/status` | APPç«¯æ¯æGPSä½ç½® | | ä»»å¡ç»è®¡ | `GET /task/statistics` | `GET /task/admin/statistics` | ç»è®¡ä¿¡æ¯ | | è¶ æ¶ä»»å¡ | `GET /task/overdue` | `GET /task/admin/overdue` | è¶ æ¶ä»»å¡å表 | | æçä»»å¡ | `GET /task/my` | - | ä» APPç«¯ä½¿ç¨ | ### 4.3 å¯¼åºæ¥å£ | åè½ | åå°ç®¡ç端 | 说æ | |------|-----------|------| | 导åºä»»å¡ | `POST /task/admin/export` | ä» åå°ç®¡çç«¯æ¯æ | | 导åºä»»å¡ï¼å ¼å®¹ï¼ | `POST /task/export` | å ¼å®¹æ§æ¥å£ | ## äºãæ ¸å¿å·®å¼è¯´æ ### 5.1 åå°ç®¡ç端æ¥å£ç¹ç¹ ```java /** * æ¥è¯¢ä»»å¡ç®¡çå表ï¼åå°ç®¡çç«¯ï¼ * 管çåæéï¼å¯ä»¥æ¥çææä»»å¡ */ @PreAuthorize("@ss.hasPermi('task:task:list')") @GetMapping("/admin/list") public TableDataInfo adminList(TaskQueryVO queryVO) { startPage(); List<SysTask> list = sysTaskService.selectSysTaskList(queryVO); return getDataTable(list); } ``` **ç¹ç¹**ï¼ - â 带 `@PreAuthorize` æé注解 - â ç´æ¥ä½¿ç¨åç«¯ä¼ éçæ¥è¯¢æ¡ä»¶ - â 管çåå¯ä»¥æ¥çææä»»å¡ - â æ¯ææé¨é¨ãåå»ºäººãæ§è¡äººçæ¡ä»¶è¿æ»¤ ### 5.2 APP 端æ¥å£ç¹ç¹ ```java /** * æ¥è¯¢ä»»å¡å表ï¼APPç«¯ï¼ * ä» æ¾ç¤ºå½åç¨æ·ç¸å ³çä»»å¡ï¼ * 1. å½åç¨æ·æå¨æºæçä»»å¡ * 2. å½åç¨æ·å建çä»»å¡ * 3. åé ç»å½åç¨æ·çä»»å¡ */ @GetMapping("/app/list") public TableDataInfo appList(TaskQueryVO queryVO) { // å¨å端èªå¨è·åå½åç¨æ·ä¿¡æ¯ï¼å®ç°ç»¼åæ¥è¯¢ Long currentUserId = getUserId(); Long currentDeptId = getDeptId(); // APP端强å¶ä½¿ç¨å½åç»å½ç¨æ·ä¿¡æ¯è¿è¡è¿æ»¤ queryVO.setDeptId(currentDeptId); queryVO.setCreatorId(currentUserId); queryVO.setAssigneeId(currentUserId); startPage(); List<SysTask> list = sysTaskService.selectSysTaskList(queryVO); return getDataTable(list); } ``` **ç¹ç¹**ï¼ - â æ æé注解ï¼å·²å¨ `permission.js` ä¸é ç½®ç½ååï¼ - â 强å¶ä½¿ç¨å½åç»å½ç¨æ·ä¿¡æ¯è¿æ»¤ - â èªå¨éå¶æ°æ®èå´ï¼ä¿è¯æ°æ®å®å ¨ - â ç¨æ·åªè½çå°èªå·±ç¸å ³çä»»å¡ ### 5.3 ç¶ææ´æ°æ¥å£å·®å¼ **APP 端**ï¼æ¯æ GPS ä½ç½®ä¿¡æ¯ä¸æ¥ ```java @PutMapping("/app/{taskId}/status") public AjaxResult appChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { // ... çç¥ç¶ææ ¡éª // 妿å å«GPSä½ç½®ä¿¡æ¯ï¼ä½¿ç¨å¸¦ä½ç½®çæ¹æ³ if (request.getLatitude() != null && request.getLongitude() != null) { SysTaskLog locationLog = new SysTaskLog(); locationLog.setLatitude(request.getLatitude()); locationLog.setLongitude(request.getLongitude()); // ... è®¾ç½®å ¶ä»ä½ç½®ä¿¡æ¯ return toAjax(sysTaskService.changeTaskStatusWithLocation(taskId, newStatus, request.getRemark(), locationLog)); } return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark())); } ``` **åå°ç®¡ç端**ï¼ä» æ¯æåºæ¬ç¶æåæ´ ```java @PreAuthorize("@ss.hasPermi('task:task:edit')") @PutMapping("/admin/{taskId}/status") public AjaxResult adminChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { TaskStatus newStatus = TaskStatus.getByCode(request.getTaskStatus()); if (newStatus == null) { return error("æ æçä»»å¡ç¶æ"); } return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark())); } ``` ## å ãå端è°ç¨ç¤ºä¾ ### 6.1 APP 端è°ç¨ ```javascript // app/api/task.js import request from '@/utils/request' // æ¥è¯¢ä»»å¡å表ï¼APPç«¯ï¼ export function listTask(query) { return request({ url: '/task/app/list', method: 'get', params: query }) } // æ´æ°ä»»å¡ç¶æï¼APPç«¯ï¼æ¯æGPSï¼ export function changeTaskStatus(taskId, data) { return request({ url: '/task/app/' + taskId + '/status', method: 'put', data: data // å¯å å« latitude, longitude çGPSä¿¡æ¯ }) } ``` **使ç¨ç¤ºä¾**ï¼ ```javascript // å¨ APP 页é¢ä¸è°ç¨ import { listTask, changeTaskStatus } from '@/api/task' // æ¥è¯¢ä»»å¡å表 listTask({ taskStatus: 'PENDING' }).then(response => { // èªå¨åªè¿åå½åç¨æ·ç¸å ³çä»»å¡ this.taskList = response.rows }) // æ´æ°ä»»å¡ç¶æå¹¶ä¸æ¥GPSä½ç½® changeTaskStatus(taskId, { taskStatus: 'IN_PROGRESS', remark: 'å·²å°è¾¾ç°åº', latitude: 23.1291, longitude: 113.2644, locationAddress: '广å·å¸å¤©æ²³åº' }).then(response => { this.$modal.msgSuccess('ç¶ææ´æ°æå') }) ``` ### 6.2 åå°ç®¡ç端è°ç¨ ```javascript // ruoyi-ui/src/api/task.js import request from '@/utils/request' // æ¥è¯¢ä»»å¡å表ï¼åå°ç®¡çç«¯ï¼ export function listTask(query) { return request({ url: '/task/admin/list', method: 'get', params: query }) } // æ´æ°ä»»å¡ç¶æï¼åå°ç®¡çç«¯ï¼ export function changeTaskStatus(taskId, data) { return request({ url: '/task/admin/' + taskId + '/status', method: 'put', data: data }) } ``` **使ç¨ç¤ºä¾**ï¼ ```javascript // å¨åå°ç®¡ç页é¢ä¸è°ç¨ import { listTask, changeTaskStatus } from '@/api/task' // æ¥è¯¢ä»»å¡å表ï¼ç®¡çå坿¥çææä»»å¡ï¼ listTask({ deptId: 101, // 坿å®é¨é¨ taskStatus: 'PENDING' }).then(response => { // è¿åææç¬¦åæ¡ä»¶çä»»å¡ this.taskList = response.rows }) // æ´æ°ä»»å¡ç¶æ changeTaskStatus(taskId, { taskStatus: 'COMPLETED', remark: 'ä»»å¡å·²å®æ' }).then(response => { this.$modal.msgSuccess('ç¶ææ´æ°æå') }) ``` ## ä¸ãæéé ç½® ### 7.1 åå°ç®¡ç端æé å¨ `ruoyi-ui/src/views/task/general/index.vue` ä¸éè¦é ç½®æéï¼ ```javascript // éè¦çæéæ è¯ const permissions = [ 'task:task:list', // æ¥è¯¢ä»»å¡å表 'task:task:query', // æ¥è¯¢ä»»å¡è¯¦æ 'task:task:add', // æ°å¢ä»»å¡ 'task:task:edit', // ä¿®æ¹ä»»å¡ 'task:task:remove', // å é¤ä»»å¡ 'task:task:export' // 导åºä»»å¡ ] ``` ### 7.2 APP 端æéé ç½® å¨ `app/permission.js` ä¸é ç½®ç½ååï¼æ éæééªè¯ï¼ï¼ ```javascript const whiteList = [ '/task/app/list', '/task/app/my', '/task/app/overdue', '/task/app/statistics', // ... å ¶ä»APP端æ¥å£ ] ``` ## å «ãæ°æ®å®å ¨ä¿é ### 8.1 APP ç«¯æ°æ®é离 **å®ç°æ¹å¼**ï¼ 1. å端强å¶ä½¿ç¨å½åç»å½ç¨æ·ç `userId` å `deptId` 2. åç«¯ä¼ éçè¿æ»¤æ¡ä»¶ä¼è¢«å端è¦ç 3. SQL æ¥è¯¢æ¶ä½¿ç¨ OR æ¡ä»¶ç»åï¼ - `dept_id = currentDeptId`ï¼åæºæï¼ - `creator_id = currentUserId`ï¼èªå·±åå»ºï¼ - `assignee_id = currentUserId`ï¼åé ç»èªå·±ï¼ **SQL 示ä¾**ï¼ ```xml <select id="selectSysTaskList" resultMap="SysTaskResult"> SELECT ... FROM sys_task t WHERE 1=1 <if test="deptId != null"> AND ( t.dept_id = #{deptId} OR t.creator_id = #{creatorId} OR t.assignee_id = #{assigneeId} ) </if> <!-- å ¶ä»æ¡ä»¶ --> </select> ``` ### 8.2 åå°ç®¡ç端æéæ§å¶ **å®ç°æ¹å¼**ï¼ 1. ä½¿ç¨ `@PreAuthorize` 注解è¿è¡æéæ ¡éª 2. 管çåå¯ä»¥èªç±æå®æ¥è¯¢æ¡ä»¶ 3. æ¯æè·¨é¨é¨ãè·¨ç¨æ·æ¥è¯¢ 4. éè¿è§è²æéæ§å¶è®¿é®èå´ ## ä¹ãè¿ç§»æå ### 9.1 ç°æ APP ç«¯ä»£ç æ éä¿®æ¹ ç±äºå端 API æä»¶å·²ç»æ´æ°ï¼ç°æç APP 页é¢ä»£ç æ éä¿®æ¹ï¼ ```javascript // åæä»£ç ä¿æä¸å import { listTask } from '@/api/task' listTask(query).then(response => { // èªå¨ä½¿ç¨æ°ç /task/app/list æ¥å£ }) ``` ### 9.2 åå°ç®¡çç«¯ä»£ç æ éä¿®æ¹ åå°ç®¡ç页é¢ä»£ç 乿 éä¿®æ¹ï¼ ```javascript // åæä»£ç ä¿æä¸å import { listTask } from '@/api/task' listTask(query).then(response => { // èªå¨ä½¿ç¨æ°ç /task/admin/list æ¥å£ }) ``` ### 9.3 æµè¯éªè¯ **APP 端æµè¯**ï¼ 1. ç»å½ APPï¼æ¥çä»»å¡å表 2. 确认åªè½çå°èªå·±ç¸å ³çä»»å¡ 3. å°è¯æ´æ°ä»»å¡ç¶æï¼éªè¯ GPS ä½ç½®ä¸æ¥ **åå°ç®¡ç端æµè¯**ï¼ 1. ç»å½åå°ç®¡çç³»ç» 2. 以管çå身份æ¥çä»»å¡å表 3. 确认å¯ä»¥çå°ææä»»å¡ 4. éªè¯æéæ§å¶æ¯å¦çæ ## åãæ³¨æäºé¡¹ ### 10.1 æ¥å£å ¼å®¹æ§ - â **ä¸åæ¯æ** `/task/list` çæ§æ¥å£è·¯å¾ - â å¿ é¡»ä½¿ç¨ `/task/app/` æ `/task/admin/` åç¼ - â å端 API æä»¶å·²æ´æ°ï¼æ éæå¨ä¿®æ¹é¡µé¢ä»£ç ### 10.2 æéé ç½® - â APP 端æ¥å£å·²é ç½®ç½ååï¼æ éæééªè¯ - â åå°ç®¡ç端æ¥å£éè¦å¯¹åºçæéæ è¯ - â ï¸ ç¡®ä¿è§è²åé äºæ£ç¡®çæé ### 10.3 æ°æ®è¿æ»¤ - â APP 端强å¶è¿æ»¤å½åç¨æ·æ°æ®ï¼åç«¯æ æ³ç»è¿ - â åå°ç®¡çç«¯æ ¹æ®æéæ¥ç对åºèå´çæ°æ® - â ï¸ ä¸è¦å¨ APP 端使ç¨åå°ç®¡ç端æ¥å£ ### 10.4 GPS ä½ç½®ä¿¡æ¯ - â ä» APP ç«¯ç¶ææ´æ°æ¥å£æ¯æ GPS ä½ç½®ä¸æ¥ - â åå°ç®¡çç«¯ç¶ææ´æ°ä¸éè¦ä½ç½®ä¿¡æ¯ - â ï¸ GPS åæ®µä¸ºå¯éï¼æ ä½ç½®æ¶ä¸å½±åç¶ææ´æ° ## åä¸ã常è§é®é¢ ### Q1: APP 端è½å¦æ¥çå ¶ä»é¨é¨çä»»å¡ï¼ **ç**ï¼ä¸è½ãAPP 端æ¥å£å¼ºå¶ä½¿ç¨å½åç»å½ç¨æ·çé¨é¨IDè¿è¡è¿æ»¤ï¼å³ä½¿åç«¯ä¼ éå ¶ä»é¨é¨IDï¼ä¹ä¼è¢«å端è¦çã ### Q2: åå°ç®¡çåå¦ä½æ¥çææä»»å¡ï¼ **ç**ï¼ä½¿ç¨åå°ç®¡ç端æ¥å£ `/task/admin/list`ï¼ä¸ä¼ éä»»ä½è¿æ»¤æ¡ä»¶å³å¯æ¥çææä»»å¡ãéè¦ç¡®ä¿ç¨æ·æ¥æ `task:task:list` æéã ### Q3: å¦ä½åºå APP 端ååå°ç®¡ç端çè°ç¨ï¼ **ç**ï¼éè¿æ¥å£è·¯å¾åç¼åºåï¼ - APP 端ï¼`/task/app/*` - åå°ç®¡ç端ï¼`/task/admin/*` ### Q4: æ§ç³»ç»çæ¥å£è°ç¨æ¯å¦åå½±åï¼ **ç**ï¼ä¸åå½±åãæ§ç³»ç»åæ¥çåè½ä½¿ç¨çæ¯ç¬ç«çæ¥å£ï¼ä¸ä»»å¡ç®¡çæ¥å£æ å ³ã ### Q5: å¦ä½æ·»å æ°çä»»å¡ç¸å ³æ¥å£ï¼ **ç**ï¼éµå¾ªä»¥ä¸è§åï¼ 1. APP 端æ¥å£ï¼è·¯å¾ä½¿ç¨ `/task/app/*`ï¼æ æé注解ï¼å¼ºå¶è¿æ»¤å½åç¨æ· 2. åå°ç®¡ç端æ¥å£ï¼è·¯å¾ä½¿ç¨ `/task/admin/*`ï¼æ·»å æéæ³¨è§£ï¼æ¯æå ¨å±æ¥è¯¢ ## åäºãæ»ç» éè¿æ¬æ¬¡æ¥å£æåï¼å®ç°äºï¼ 1. â **ä¸å¡å离**ï¼APP 端ååå°ç®¡ç端使ç¨ç¬ç«æ¥å£ 2. â **æéæ¸ æ°**ï¼åå°ç®¡ç端ç»ä¸ä½¿ç¨æé注解 3. â **æ°æ®å®å ¨**ï¼APP 端强å¶è¿æ»¤å½åç¨æ·æ°æ® 4. â **åè½æ©å±**ï¼APP ç«¯æ¯æ GPS ä½ç½®ä¸æ¥ 5. â **代ç ç»´æ¤**ï¼æ¥å£èè´£åä¸ï¼æäºç»´æ¤ 6. â **åä¸å ¼å®¹**ï¼åç«¯ä»£ç æ éä¿®æ¹ï¼èªå¨ä½¿ç¨æ°æ¥å£ --- **ææ¡£çæ¬**: v1.0 **åå»ºæ¥æ**: 2025-01-XX **æåæ´æ°**: 2025-01-XX **ç»´æ¤äººå**: ç³»ç»ç®¡çå