Explorar o código

feat:"添加国家城市选择功能"

soobin hai 8 meses
pai
achega
451ee05ef8

+ 27 - 7
src/assets/language/en.json

@@ -1357,12 +1357,12 @@
   },
   "register": {
     "header": "User Registration",
-    "usernameLabel": "UserName",
-    "usernamePlaceholder": "Please enter the userName",
+    "usernameLabel": "Account name",
+    "usernamePlaceholder": "Please enter the Account name",
     "usernameRequired": "Alphanumeric with letter as the first character",
-    "nameLabel": "Name",
-    "namePlaceholder": "Please enter the name",
-    "nameRequired": "Please enter the name",
+    "nameLabel": "Personal Name",
+    "namePlaceholder": "Please enter the Personal Name",
+    "nameRequired": "Please enter the Personal Name",
     "passwordLabel": "Login password",
     "passwordPlaceholder": "Please enter a password with more than 10 digits",
     "passwordRequired": "Please enter a password with more than 10 digits",
@@ -1370,7 +1370,13 @@
     "passwordCheckLabel": "Confirm Password",
     "passwordCheckPlaceholder": "Please enter the password again to confirm",
     "passwordCheckRequired": "Please enter the password again to confirm",
-    "country": "Country/region",
+    "countryCity": "Country and city",
+    "clickCountryCity": "Click to select country and city",
+    "chooseCountryCity": "Please select a country and city",
+    "areaLabel": "Regional selection",
+    "areaPlaceholder": "Click to select Province",
+    "areaRequired": "Please select a province",
+    "country": "Region",
     "chinese": "中国大陆",
     "other": "Abroad/HKMT",
     "logonMode": "Logon mode",
@@ -1394,7 +1400,21 @@
     "replaysInSeconds": "Replays in seconds",
     "emailRegistration": "Email",
     "phoneRegistration": "Phone",
-    "twoTypedDiff": "The two passwords are different"
+    "twoTypedDiff": "The two passwords are different",
+    "registerSucess": "Successful",
+    "registerFail": "Registration failed. Please contact the administrator",
+    "R0001": "The invitation code does not exist",
+    "R0002": "The phone number is empty",
+    "R0003": "Mailbox is empty",
+    "R0004": "Not a valid phone number or email address",
+    "R0005": "The verification code is empty",
+    "R0006": "Verification code error",
+    "R0008": "The verification code does not exist",
+    "R0009": "Do not send frequently, try again in 10 minutes",
+    "A0201": "Email not registered",
+    "A0202": "The user's mobile phone already exists",
+    "A0203": "The phone number is not registered",
+    "A0207": "The user mailbox already exists"
   },
   "robotRanking": {
     "noPermission": "insufficient permissions",

+ 22 - 2
src/assets/language/ja.json

@@ -1384,7 +1384,13 @@
         "passwordCheckLabel": "パスワード確認",
         "passwordCheckPlaceholder": "確認のためパスワードを再入力してください",
         "passwordCheckRequired": "確認のためパスワードを再入力してください",
-        "country": "国/地域",
+        "countryCity": "国と市",
+        "clickCountryCity": "国と都市をクリックして選択します",
+        "chooseCountryCity": "国と都市を選択してください",
+        "areaLabel": "地域選択です",
+        "areaPlaceholder": "クリックして都道府県を選びます",
+        "areaRequired": "都道府県を選びます。",
+        "country": "地域",
         "chinese": "中国本土",
         "other": "海外/香港・マカオ・台湾",
         "logonMode": "登録方法",
@@ -1410,7 +1416,21 @@
         "replaysInSeconds": "数秒後に再送信できます",
         "emailRegistration": "メールでの登録",
         "phoneRegistration": "電話での登録",
-        "twoTypedDiff": "入力したパスワードが一致しません"
+        "twoTypedDiff": "入力したパスワードが一致しません",
+        "registerSucess": "成功です",
+        "registerFail": "失敗しました,管理人に連絡してください",
+        "R0001": "招待コードは存在しません",
+        "R0002": "携帯番号は空です",
+        "R0003": "メールボックスは空です。",
+        "R0004": "有効な携帯番号やメールアドレスではありません",
+        "R0005": "認証コードがNULLです",
+        "R0006": "認証コードエラー",
+        "R0008": "認証コードが存在しません",
+        "R0009": "頻繁に送信せず、10分後に再試行してください",
+        "A0201": "メールボックスは登録されていません",
+        "A0202": "ユーザーの携帯電話はすでに存在します",
+        "A0203": "携帯番号未登録",
+        "A0207": "ユーザーメールボックスはすでに存在します"
     },
     "robotRanking": {
         "noPermission": "権限が不十分",

+ 22 - 2
src/assets/language/zh.json

@@ -1438,9 +1438,15 @@
     "passwordCheckLabel": "确认密码",
     "passwordCheckPlaceholder": "请再次输入密码进行确认",
     "passwordCheckRequired": "请再次输入密码进行确认",
-    "country": "国家/地区",
+    "countryCity": "国家城市",
+    "clickCountryCity": "点击选择国家城市",
+    "chooseCountryCity": "请选择国家城市",
+    "country": "地区",
     "chinese": "中国大陆",
     "other": "海外/港澳台",
+    "areaLabel": "地区选择",
+    "areaPlaceholder": "点击选择省市",
+    "areaRequired": "请选择省市",
     "logonMode": "注册方式",
     "phoneLabel": "手机号码",
     "phonePlaceholder": "请输入手机号码",
@@ -1464,7 +1470,21 @@
     "replaysInSeconds": "秒后可重发",
     "emailRegistration": "邮箱注册",
     "phoneRegistration": "手机注册",
-    "twoTypedDiff": "两次输入的密码不一致"
+    "twoTypedDiff": "两次输入的密码不一致",
+    "registerSucess": "注册成功",
+    "registerFail": "注册失败,请联系管理员",
+    "R0001": "邀请码不存在",
+    "R0002": "手机号为空",
+    "R0003": "邮箱为空",
+    "R0004": "不是有效的手机号或邮箱地址",
+    "R0005": "验证码为空",
+    "R0006": "验证码错误",
+    "R0008": "验证码不存在",
+    "R0009": "请勿频繁发送, 10分钟后再试",
+    "A0201": "邮箱未注册",
+    "A0202": "用户手机已存在",
+    "A0203": "手机号未注册",
+    "A0207": "用户邮箱已存在"
   },
   "robotRanking": {
     "noPermission": "权限不足",

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2106 - 0
src/common/js/countries-en.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2103 - 0
src/common/js/countries.js


+ 0 - 2
src/components/commom/kSelectPop/index.vue

@@ -82,8 +82,6 @@ export default {
       if (tempOptions.value.length == 0) {
         tempOptions.value = props.selOptions;
       }
-      // console.log("关键词", searchValue.value);
-      // console.log("原始数据", tempOptions.value);
       let newOptions = [];
       tempOptions.value.forEach((item) => {
         if (item.name.includes(searchValue.value) || (item.username != null && item.username.includes(searchValue.value)) || (item.clientId != null && item.clientId.includes(searchValue.value))) {

+ 36 - 13
src/components/commom/kTimezone/index.vue

@@ -26,19 +26,42 @@ export default {
         };
 
         const options = ref([
-            { text: '上海(UTC+8)', value: 'Asia/Shanghai' },
-            { text: '東京(UTC+9)', value: 'Asia/Tokyo' },
-            { text: 'NewYork(UTC-5)', value: 'America/New_York' },
-            { text: 'Riyadh(UTC+3)', value: 'Asia/Riyadh' },
-            { text: 'Paris(UTC+1)', value: 'Europe/Paris' },
-            { text: 'London(UTC+0)', value: 'Europe/London' },
-            { text: 'Madrid(UTC+1)', value: 'Europe/Madrid' },
-            { text: 'São Paulo(UTC-3)', value: 'America/Sao_Paulo' },
-            { text: 'Vancouver(UTC-8)', value: 'America/Vancouver' },
-            { text: 'Edmonton(UTC-7)', value: 'America/Edmonton' },
-            { text: 'Winnipeg(UTC-6)', value: 'America/Winnipeg' },
-            { text: 'Toronto(UTC-5)', value: 'America/Toronto' },
-            { text: 'Moncton(UTC-4)', value: 'America/Moncton' }
+            { text: 'UTC-10', value: 'Pacific/Honolulu' },
+            { text: 'UTC-9', value: 'America/Anchorage' },
+            { text: 'UTC-8', value: 'America/Los_Angeles' },
+            { text: 'UTC-7', value: 'America/Denver' },
+            { text: 'UTC-6', value: 'America/Chicago' },
+            { text: 'UTC-5', value: 'America/New_York' },
+            { text: 'UTC-4', value: 'America/Caracas' },
+            { text: 'UTC-3', value: 'America/Sao_Paulo' },
+            { text: 'UTC-2', value: 'Atlantic/South_Georgia' },
+            { text: 'UTC-1', value: 'Atlantic/Cape_Verde' },
+            { text: 'UTC+0', value: 'Europe/London' },
+            { text: 'UTC+1', value: 'Europe/Paris' },
+            { text: 'UTC+2', value: 'Europe/Helsinki' },
+            { text: 'UTC+3', value: 'Europe/Moscow' },
+            { text: 'UTC+4', value: 'Asia/Dubai' },
+            { text: 'UTC+5', value: 'Asia/Karachi' },
+            { text: 'UTC+6', value: 'Asia/Bishkek' },
+            { text: 'UTC+7', value: 'Asia/Bangkok' },
+            { text: 'UTC+8', value: 'Asia/Shanghai' },
+            { text: 'UTC+9', value: 'Asia/Tokyo' },
+            { text: 'UTC+10', value: 'Australia/Sydney' },
+            { text: 'UTC+11', value: 'Asia/Magadan' },
+            { text: 'UTC+12', value: 'Pacific/Auckland' },
+            // { text: '上海(UTC+8)', value: 'Asia/Shanghai' },
+            // { text: '東京(UTC+9)', value: 'Asia/Tokyo' },
+            // { text: 'NewYork(UTC-5)', value: 'America/New_York' },
+            // { text: 'Riyadh(UTC+3)', value: 'Asia/Riyadh' },
+            // { text: 'Paris(UTC+1)', value: 'Europe/Paris' },
+            // { text: 'London(UTC+0)', value: 'Europe/London' },
+            // { text: 'Madrid(UTC+1)', value: 'Europe/Madrid' },
+            // { text: 'São Paulo(UTC-3)', value: 'America/Sao_Paulo' },
+            // { text: 'Vancouver(UTC-8)', value: 'America/Vancouver' },
+            // { text: 'Edmonton(UTC-7)', value: 'America/Edmonton' },
+            // { text: 'Winnipeg(UTC-6)', value: 'America/Winnipeg' },
+            // { text: 'Toronto(UTC-5)', value: 'America/Toronto' },
+            // { text: 'Moncton(UTC-4)', value: 'America/Moncton' }
         ]);
 
 

+ 14 - 0
src/service/user.js

@@ -51,3 +51,17 @@ export function updateOnOffNotice(params) {
   return axios.get(`/SZWL-SERVER/tAdmin/updateOnOffNotice?${stringToUrl(params)}`, params);
 } 
 
+// 修改地区
+export function updateArea(params) {
+  return axios.get(`/SZWL-SERVER/tAdmin/updateArea?${stringToUrl(params)}`, params);
+} 
+
+// 国内账号获取所属地区
+export function getAreaById(params) {
+  return axios.get(`/SZWL-SERVER/tAdmin/getAreaById?${stringToUrl(params)}`, params);
+}
+
+// 海外账号获取所属地区
+export function getCitiesById(params) {
+  return axios.get(`/SZWL-SERVER/tAdmin/getCitiesById?${stringToUrl(params)}`, params);
+}

+ 15 - 27
src/styles/register/index.less

@@ -64,39 +64,26 @@
 					}
 
 
-					// .van-icon-success::before {
-					// 	content: '';
-					// 	background: #fff;
-					// 	width: 40%;
-					// 	height: 40%;
-					// 	position: absolute;
-					// 	top: 30%;
-					// 	left: 29%;
-					// 	border-radius: 100%;
-					// }
-
 					.van-radio__icon--checked+.van-radio__label {
 						color: #4d6add;
 					}
 				}
 			}
-		}
-	}
-
-	.van-tabs__nav {
-
-		.van-tab--card {
-			color: #4d6add;
-			border-right: #4d6add
-		}
-
-		border-color: #4d6add;
+			.searchCity {
+				margin-top: auto;
+				// background-color: #4d6add;
+				padding: 5px 0px;
+
+				.van-search__content {
+					background-color: #fff;
+					padding: 10px;
+				}
 
-		.van-tab--active {
-			color: #fff;
-			background-color: #4d6add;
+				.van-cell__value {
+					height: auto;
+				}
+			}
 		}
-
 	}
 
 	.register {
@@ -104,8 +91,9 @@
 		border-radius: 17px;
 		height: 34px;
 		width: 220px;
-		margin-top: 60px;
+		margin-top: 30px;
 		font-size: 15px;
 		font-family: PingFangSC-Medium;
 	}
+
 }

+ 5 - 0
src/views/mqtt/message/index.vue

@@ -278,12 +278,17 @@ export default {
 
             .itemRow {
                 width: 100%;
+                overflow-wrap: break-word;
             }
 
             .itemTitle {
                 color: #8787a6;
                 font-size: 13px;
             }
+            
+            // .itemContent {
+                
+            // }
 
             .discount {
                 padding-left: 2em;

+ 6 - 2
src/views/mqtt/topic/index.vue

@@ -98,7 +98,9 @@ export default {
             const { data } = await addMqttTopic(params);
             if (data.code === "00000") {
                 showSuccessToast(t("mqtt.addSuccessfully"));
-                getList();
+                setTimeout(() => {
+                    getList();
+                }, 1000);
             } else {
                 showFailToast(t("mqtt.addFailed"));
             }
@@ -134,7 +136,9 @@ export default {
                 const { data } = await delSubscribe(params)
                 if (data.code === "00000") {
                     showSuccessToast("删除成功");
-                    getList();
+                    setTimeout(() => {
+                        getList();
+                    }, 1000);
                 } else {
                     showFailToast(data.message);
                 }

+ 147 - 58
src/views/register.vue

@@ -13,21 +13,17 @@
           :rules="[{ required: true, message: $t('register.nameRequired') }]" />
         <br>
         <!-- 密码 -->
-        <van-field v-model="password" name="password" type="password" 
-          :label="$t('register.passwordLabel')"
-          :placeholder="$t('register.passwordPlaceholder')" 
-          :rules="[
-            { required: true, message: $t('register.passwordRequired') },
-            { pattern: /^(?=.*[a-zA-Z])(?=.*\d).{10,}$/, message: $t('register.passwordPattern') }
-          ]" />
+        <van-field v-model="password" name="password" type="password" :label="$t('register.passwordLabel')"
+          :placeholder="$t('register.passwordPlaceholder')" :rules="[
+      { required: true, message: $t('register.passwordRequired') },
+      { pattern: /^(?=.*[a-zA-Z])(?=.*\d).{10,}$/, message: $t('register.passwordPattern') }
+    ]" />
         <br>
         <!-- 确认密码 -->
         <van-field v-model="passwordCheck" name="passwordCheck" type="password"
-          :label="$t('register.passwordCheckLabel')" 
-          :placeholder="$t('register.passwordCheckPlaceholder')" 
-          :rules="[
-            { required: true, message: $t('register.passwordCheckRequired') },
-          ]" />
+          :label="$t('register.passwordCheckLabel')" :placeholder="$t('register.passwordCheckPlaceholder')" :rules="[
+      { required: true, message: $t('register.passwordCheckRequired') },
+    ]" />
         <br>
         <!-- 国家或地区 -->
         <div class="van-cell van-field">
@@ -39,6 +35,27 @@
             </van-radio-group>
           </div>
         </div>
+        <!-- 国家城市 -->
+        <van-field v-model="areaValue" v-if="ifForeign === '0'" readonly name="picker" :label="$t('register.areaLabel')"
+          :placeholder="$t('register.areaPlaceholder')" @click="showArea = true"
+          :rules="[{ required: true, message: $t('register.areaRequired') }]" />
+        <van-popup v-model:show="showArea" position="bottom">
+          <van-cascader :title="$t('register.areaRequired')" :options="areaOptions" @close="showArea = false"
+            @finish="onConfirmArea" />
+        </van-popup>
+
+        <van-field v-model="cityValue" v-if="ifForeign === '1'" readonly name="picker"
+          :label="$t('register.countryCity')" :placeholder="$t('register.clickCountryCity')" @click="showCountry = true"
+          :rules="[{ required: true, message: $t('register.chooseCountryCity') }]" />
+        <van-popup v-model:show="showCountry" round position="bottom">
+          <van-cascader :title="$t('register.chooseCountryCity')" :options="countryOptions" @close="showCountry = false"
+            @finish="onConfirmCountry">
+            <template #options-top="{ tabIndex }" >
+              <van-search v-if="tabIndex === 0" v-model="searchValue" class="searchCity" :placeholder="$t('kSelectPop.searchKey')" @update:model-value="valueChange(tabIndex)"/>
+            </template>
+          </van-cascader>
+        </van-popup>
+        <br>
         <!-- 中国 -->
         <div v-if="ifForeign === '0'">
           <div class="van-cell van-field">
@@ -62,18 +79,18 @@
             <template #button v-if="ifForeign === '0' && logonMode === '10'">
               <van-button size="small" type="primary" @click="seedVerCode()"
                 :disabled="time !== 0 || phone.length === 0" :loading=reqApi :loading-text="$t('register.sending')">{{
-                  time === 0 ?
-                    $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
-                }}
+      time === 0 ?
+        $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
+    }}
               </van-button>
             </template>
           </van-field>
           <!-- 国内邮箱 -->
           <van-field v-if="logonMode === '11'" v-model="email" name="email" :label="$t('register.emailLabel')"
             :placeholder="$t('register.emailPlaceholder')" :rules="[
-              { required: ifForeign === '0' && logonMode === '11', message: $t('register.emailRequired') },
-              { pattern: /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/, message: '邮箱格式错误!' }
-            ]" :minlength="3" :maxlength="20">
+      { required: ifForeign === '0' && logonMode === '11', message: $t('register.emailRequired') },
+      { pattern: /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/, message: '邮箱格式错误!' }
+    ]" :minlength="3" :maxlength="20">
           </van-field>
           <br v-if="ifForeign === '0' && logonMode === '11'">
           <!-- 国内邮箱验证码 -->
@@ -83,9 +100,9 @@
             <template #button v-if="ifForeign === '0' && logonMode === '11'">
               <van-button size="small" type="primary" @click="seedVerCode()"
                 :disabled="time !== 0 || email.length === 0" :loading=reqApi :loading-text="$t('register.sending')">{{
-                  time === 0 ?
-                    $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
-                }}
+      time === 0 ?
+        $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
+    }}
               </van-button>
             </template>
           </van-field>
@@ -104,20 +121,20 @@
             <template #button v-if="ifForeign === '1'">
               <van-button size="small" type="primary" @click="seedVerCode()"
                 :disabled="time !== 0 || email.length === 0" :loading=reqApi :loading-text="$t('register.sending')">{{
-                  time === 0 ?
-                    $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
-                }}
+      time === 0 ?
+        $t('register.seedVerCode') : time + $t('register.replaysInSeconds')
+    }}
               </van-button>
             </template>
           </van-field>
         </div>
+        <br>
         <van-field v-model="inviteCode" name="inviteCode" :label="$t('register.invitationCode')"
           :placeholder="$t('register.invitationCodePlaceholder')" />
-        <br>
         <!-- 提交验证信息 -->
         <van-button round type="primary" class="register" native-type="submit">{{
           $t('register.registerButton')
-        }}
+          }}
         </van-button>
       </van-form>
     </div>
@@ -134,12 +151,16 @@ import logiLogoImgUrl from "@/assets/login/logo.png";
 import { useRouter } from 'vue-router';
 import { getLocal, setLocal, styleUrl } from '@/common/js/utils';
 import { useI18n } from "vue-i18n";
+import { countriesData } from '@/common/js/countries';
+import { countriesDataEn } from '@/common/js/countries-en';
+import { useCascaderAreaData } from '@vant/area-data';
 
 
 
 export default {
   setup() {
     // 引入语言
+    let languageName = ref(getLocal("curLang"));
     const { t } = useI18n();
     const active = ref(0);
     const username = ref('');
@@ -156,13 +177,37 @@ export default {
     const verCodeTime = reactive({
       time: 0
     });
-    // let lastSendTime = ref('');
     let phoneOrEmailStr = ref('');
 
     const router = useRouter();
     const reqApi = ref(false);
     const hostName = ref('');
 
+    const citiesValue = ref('');
+    const showCountry = ref(false);
+    const cityValue = ref('');
+    const countryOptions = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+
+    const onConfirmCountry = ({ selectedOptions }) => {
+      cityValue.value = selectedOptions.map((option) => option.text).join('/');
+      citiesValue.value = selectedOptions[1]?.value;
+      showCountry.value = false;
+    };
+
+    const areaOptions = ref();
+    const areaValue = ref('');
+    const showArea = ref(false);
+    const onConfirmArea = ({ selectedOptions }) => {
+      if (selectedOptions[0]?.text == selectedOptions[1]?.text) {
+        areaValue.value = selectedOptions[0]?.text;
+        citiesValue.value = selectedOptions[0]?.text;
+      } else {
+        areaValue.value = selectedOptions[0]?.text + "/" + selectedOptions[1]?.text;
+        citiesValue.value = selectedOptions[0]?.text + selectedOptions[1]?.text;
+      }
+      showArea.value = false;
+    };
+
     // 注册点击
     const registerSubmit = async () => {
       if (password.value !== passwordCheck.value) {
@@ -174,23 +219,36 @@ export default {
         name: name.value,
         password: md5(password.value),
         ifForeign: ifForeign.value,
-        // phone: phone.value,
-        // email: email.value,
         phoneOrEmail: phone.value || email.value,
         code: code.value,
         companyType: '0',
-        inviteCode: inviteCode.value
+        inviteCode: inviteCode.value,
+        cities: citiesValue.value
       });
 
       if (data.code === '00000') {
-        showToast('注册成功');
+        showToast(t('register.registerSucess'));
         router.push({ path: '/login' });
+      } else if (data.code === 'R0001') {
+        showFailToast(t('register.R0001'));
+      } else if (data.code === 'R0002') {
+        showFailToast(t('register.R0002'));
+      } else if (data.code === 'R0003') {
+        showFailToast(t('register.R0003'));
+      } else if (data.code === 'R0004') {
+        showFailToast(t('register.R0004'));
+      } else if (data.code === 'R0005') {
+        showFailToast(t('register.R0005'));
+      } else if (data.code === 'R0006') {
+        showFailToast(t('register.R0006'));
+      } else if (data.code === 'A0201') {
+        showFailToast(t('register.A0201'));
+      } else if (data.code === 'A0203') {
+        showFailToast(t('register.A0203'));
       } else {
-        showFailToast(data.message);
+        showFailToast(t('register.registerFail'));
       }
     };
-    // const lastSentTimeStr = localStorage.getItem('lastSendTime');
-    // console.log("从本地获取到的lastSendTime>>>", lastSentTimeStr);
 
     // 发送验证码
     const seedVerCode = async () => {
@@ -211,17 +269,25 @@ export default {
         const { data } = await sentRegisterCode({
           ifForeign: ifForeign.value,
           phoneOrEmail: phoneOrEmailStr,
-          // hostName: 'Sunzee',
           hostName: hostName.value,
         });
+        reqApi.value = false;
         if (data.code === '00000') {
-          reqApi.value = false;
           showToast(data.data);
           verCodeTime.time = 1 * 60; // 1分钟定时器,60s后可以更换验证方式
           verCodeTimeInterval();
+        } else if (data.code === 'R0009') {
+          showToast(t('register.R0009'));
+        } else if (data.code === 'R0008') {
+          showToast(t('register.R0008'));
+        } else if (data.code === 'A0202') {
+          showToast(t('register.A0202'));
+        } else if (data.code === 'A0207') {
+          showToast(t('register.A0207'));
+        } else if (data.code === 'R0004') {
+          showToast(t('register.R0004'));
         } else {
-          reqApi.value = false;
-          showFailToast(data.message);
+          showToast(data.message);
         }
       } catch (error) {
         reqApi.value = false;
@@ -251,13 +317,20 @@ export default {
       } else {
         verCodeTime.time = 0;
       }
+      const areaData = useCascaderAreaData();
+      areaData.forEach(province => {
+        province.children.forEach(city => {
+          // 删除城市中的区级信息
+          delete city.children;
+        });
+      });
+      // 删除台湾、澳门和香港
+      const provincesToRemove = ['710000', '810000', '820000'];
+      areaOptions.value = areaData.filter(province => !provincesToRemove.includes(province.value));
     });
 
     const getCurrentDomain = () => {
       const currentDomain = window.location.href;
-      // const currentHostname = window.location.hostname;
-      console.log("currentDomain >>>", currentDomain);
-      // console.log("currentHostname >>>", currentHostname);
       switch (true) {
         case currentDomain.includes('sevencloud.com.cn'):
           hostName.value = 'Sevencloud';
@@ -275,21 +348,27 @@ export default {
       { text: '手机注册', value: "mo" },
       { text: '邮箱注册', value: "ema" }
     ]
-    const option1 = [
-      {
-        text: 'aaaa', value: 0,
-
-      },
-      {
-        text: 'ccc', value: 1
-      }
-    ]
 
-    const option2 = [
-      {
-        text: 'bbb', value: 'b'
+    // 搜索关键词
+    const searchValue = ref('');
+    const countryData = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+    // 搜索数据
+    const valueChange = (index) => {
+      let tempOptions = [];
+      if (searchValue.value) {
+        if (index === 0) {
+          // 国家
+          countryData.value.forEach(item => {
+            if (item.text.includes(searchValue.value)) {
+              tempOptions.push(item);
+            }
+          });
+          countryOptions.value = tempOptions;
+        }
+      } else {
+        countryOptions.value = countryData.value;
       }
-    ]
+    };
 
     return {
       ...toRefs(verCodeTime),
@@ -308,14 +387,24 @@ export default {
       verCodeTimeInterval,
       seedVerCode,
       registerSubmit,
-      option1,
-      option2,
       signOptions,
       signinModel: 'aaabb',
       active,
       logonMode,
-      // lastSendTime,
-      reqApi
+      reqApi,
+
+      cityValue,
+      showCountry,
+      countryOptions,
+      onConfirmCountry,
+      showArea,
+      areaOptions,
+      // areaList,
+      onConfirmArea,
+      areaValue,
+
+      searchValue,
+      valueChange
     }
   },
   components: { sHeader }

+ 192 - 68
src/views/user.vue

@@ -25,20 +25,18 @@
         </div>
         <div class="userInfoBox">
           <!-- 地区 -->
-          <div v-if="isInland && user.type != '0'">
+          <div v-if="user.type == '2'">
             <div v-if="!areaShow" class="userInfo l-flex-between">
               <span class="userInfoLeft">{{ $t("user.region") }}: </span>
               <div class="cust_vantBorder">
                 <div class="filedInpPad">
-                  <van-field @click-input="fieldValueInpClk" readonly clearable v-model="fieldValue"
+                  <van-field @click-input="clickShowArea" readonly clearable v-model="fieldValue"
                     :placeholder="$t('user.regionPlace')">
                     <template #right-icon>
                       <div class="l-flex-RC">
-                        <van-icon v-if="fieldValue" @click="
-                          fieldValue = '';
-                        accountDetail.areaId = '';
-                        " class="o-mr-6" name="clear" />
-                        <van-icon @click="fieldValueInpClk" name="arrow-down" />
+                        <van-icon v-if="fieldValue" @click="fieldValue = ''; accountDetail.areaId = '';
+      " class="o-mr-6" name="clear" />
+                        <van-icon @click="clickShowArea" name="arrow-down" />
                       </div>
                     </template>
                   </van-field>
@@ -114,7 +112,7 @@
 
                 <template #button>
                   <van-button type="primary" @click="mailboxChg(cofficentForm.currencySymbol, 5)">{{
-                    $t("user.confirmLog") }}
+        $t("user.confirmLog") }}
                   </van-button>
                 </template>
               </van-field>
@@ -162,7 +160,7 @@
 
                   <template #button>
                     <van-button type="primary" @click="mailboxChg(diyPassword, 6)">{{
-                      $t("user.confirmLog") }}
+        $t("user.confirmLog") }}
                     </van-button>
                   </template>
                 </van-field>
@@ -319,18 +317,33 @@
       @confirmclk="confirmClk">
     </kDialog>
     <!-- 地区弹窗 -->
-    <kCascader @getareaname="getAreaName" :selectId="accountDetail.areaId" @areapopfinish="areaPopFinish"
-      ref="kCascaderRef"></kCascader>
+    <!-- <kCascader @getareaname="getAreaName" :selectId="accountDetail.areaId" @areapopfinish="areaPopFinish"
+      ref="kCascaderRef"></kCascader> -->
     <!-- 时区弹窗 -->
     <kTimezone @gettimezone="getTimezone" :selectId="accountDetail.timezone" @timezonepopfinish="timezonePopFinish"
       ref="kTimezoneRef"></kTimezone>
+    <!-- 省市选择弹窗 -->
+    <van-popup v-model:show="showArea" position="bottom">
+      <van-cascader :title="$t('register.areaRequired')" :options="areaOptions" @close="showArea = false"
+        @finish="onConfirmArea" />
+    </van-popup>
+    <!-- 国家选择弹窗 -->
+    <van-popup v-model:show="showCountry" round position="bottom">
+      <van-cascader :title="$t('register.chooseCountryCity')" :options="countryOptions" @close="showCountry = false"
+        @finish="onConfirmCountry" >
+        <template #options-top="{ tabIndex }">
+          <van-search v-if="tabIndex === 0" v-model="searchValue" class="searchCity"
+            :placeholder="$t('kSelectPop.searchKey')" @update:model-value="valueChange(tabIndex)" />
+        </template>
+      </van-cascader>
+    </van-popup>
 
   </div>
 </template>
 
 <script>
 // 导入地区弹窗
-import kCascader from "@/components/commom/kCascader/index.vue";
+// import kCascader from "@/components/commom/kCascader/index.vue";
 // 导入时区弹窗
 import kTimezone from "@/components/commom/kTimezone/index.vue";
 // 导入接口
@@ -341,19 +354,24 @@ import kDialog from "@/components/commom/kDialog/index.vue";
 import { onMounted, reactive, ref } from "vue";
 import sHeader from "@/components/SimpleHeader";
 import {
+  getLocal,
   getLoginUser,
   $M_EmailAvailable,
   $M_PhoneTest,
 } from "@/common/js/utils";
 import { useRouter } from "vue-router";
-import { tAdminGetRelation, updatePayPlatform, updateDIYPassword, updateOrderNotice, updateOnOffNotice } from "@/service/user";
+import { tAdminGetRelation, updatePayPlatform, updateDIYPassword, updateOrderNotice, updateOnOffNotice, getAreaById, updateArea, getCitiesById } from "@/service/user";
 import { showFailToast, showToast, showSuccessToast, showConfirmDialog } from 'vant';
 import { useI18n } from "vue-i18n";
 import { styleUrl } from "../common/js/utils";
+import { countriesData } from '@/common/js/countries';
+import { countriesDataEn } from '@/common/js/countries-en';
+import { useCascaderAreaData } from '@vant/area-data';
 
 export default {
-  components: { sHeader, kDialog, kCascader, kTimezone },
+  components: { sHeader, kDialog, kTimezone },
   setup() {
+    let languageName = ref(getLocal("curLang"));
     // 引入语言
     const { t } = useI18n();
     // 账户信息
@@ -383,6 +401,21 @@ export default {
     const orderNotice = ref(false);
     // 设备上/离线通知开关状态
     const onOffNotice = ref(false);
+    // 弹窗省市
+    const showArea = ref(false);
+    const areaOptions = ref();
+    // 弹窗国家
+    const showCountry = ref(false);
+    const countryOptions = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+
+    // 弹窗控制
+    const clickShowArea = () => {
+      if (user.ifForeign == 0) {
+        showArea.value = true;
+      } else {
+        showCountry.value = true;
+      }
+    }
 
     const user = getLoginUser();
     const router = useRouter();
@@ -484,23 +517,6 @@ export default {
     // 点击邮箱的确定按钮
     const mailboxChg = async (e, idx) => {
       switch (idx) {
-        // case 1:
-        //   if (!e) {
-        //     showToast(t("user.associateParentPlace"));
-        //   } else {
-        //     const { data } = await tAdminSetRelationAdmin({
-        //       adminId: user.id,
-        //       username: e,
-        //     });
-        //     relationType.value = true;
-        //     if (data.code === "00000") {
-        //       showToast(data.message);
-        //       setTimeout(() => {
-        //         gettAdminGetRelation();
-        //       }, 500);
-        //     }
-        //   }
-        //   break;
         case 2:
           if (!e) {
             showToast(t("user.mailboxPlace"));
@@ -581,19 +597,27 @@ export default {
           break;
       }
     };
+    // 地区ID
+    const areaId = ref(null);
     // 获取账户详情
-    const getAcccountDetail = () => {
+    const getAcccountDetail = async () => {
       getAdmin({ id: user.id }).then((res) => {
         accountDetail.value = res.data.data;
-        console.log("accountDetail", accountDetail.value)
+        if (accountDetail.value.areaId != null && accountDetail.value.type == 2) {
+          areaId.value = accountDetail.value.areaId;
+          // 查询地址回显
+          if (accountDetail.value.ifForeign == "0") {
+            getArea();
+          } else {
+            getCities();
+          }
+        }
         if (accountDetail.value.orderNotice == "1") {
           orderNotice.value = true;
         }
         if (accountDetail.value.onOffNotice == "1") {
           onOffNotice.value = true;
         }
-        // 查询地址回显
-        kCascaderRef.value.init(accountDetail.value.areaId);
         // 查询时区回显
         kTimezoneRef.value.init(accountDetail.value.timeZone)
       });
@@ -605,7 +629,6 @@ export default {
         if (res.data.data.payPlatform == '1') {
           sunzeePay.value = true;
         }
-        console.log("sunzeePay", sunzeePay.value)
       });
     };
     // 获取七云支付平台
@@ -650,8 +673,6 @@ export default {
         title: t('user.tips'),
         message: t('user.changeTips'),
       }).then(() => {
-        // checked.value = newValue;
-        console.log(value);
         params.id = 2738;
         if (value) {
           params.payPlatform = '1';
@@ -675,8 +696,6 @@ export default {
         title: t('user.tips'),
         message: t('user.changeTips'),
       }).then(() => {
-        // checked.value = newValue;
-        console.log(value);
         params.id = 2739;
         if (value) {
           params.payPlatform = '1';
@@ -705,7 +724,6 @@ export default {
           orderNotice: value ? '1' : '0',
         });
         const { data } = await updateOrderNotice(params);
-        console.log("data", data)
         if (data.code == "00000") {
           showSuccessToast(value ? t('user.openSuccess') : t('user.closeSuccess'));
           orderNotice.value = value;
@@ -730,7 +748,6 @@ export default {
           onOffNotice: value ? '1' : '0',
         });
         const { data } = await updateOnOffNotice(params);
-        console.log("data", data)
         if (data.code == "00000") {
           showSuccessToast(value ? t('user.openSuccess') : t('user.closeSuccess'));
           onOffNotice.value = value;
@@ -761,6 +778,18 @@ export default {
         getSunzeeDetail();
         getSevenCloudDetail();
       }
+      // 省市选择器
+      const areaData = useCascaderAreaData();
+      areaData.forEach(province => {
+        province.children.forEach(city => {
+          // 删除城市中的区级信息
+          delete city.children;
+        });
+      });
+      // 删除台湾、澳门和香港
+      const provincesToRemove = ['710000', '810000', '820000'];
+      areaOptions.value = areaData.filter(province => !provincesToRemove.includes(province.value));
+
     });
     const gettAdminGetRelation = async () => {
       const { data } = await tAdminGetRelation({
@@ -816,29 +845,102 @@ export default {
         return menuList.length > 0;
       }
     };
+
+    // 获取地区
+    const fullName = ref("");
+    const name = ref("");
+    // 国内省市
+    const getArea = async () => {
+      const { data } = await getAreaById({
+        areaId: areaId.value,
+      });
+      if (data.code === "00000") {
+        fullName.value = data.data.fullName;
+        name.value = data.data.name;
+        if (fullName.value != name.value) {
+          fullName.value = fullName.value.replace(name.value, "").trim();
+          fullName.value = fullName.value + "/" + name.value;
+        }
+        fieldValue.value = fullName.value;
+      }
+    };
+    const countryValue = ref("");
+    const cityValue = ref("");
+    // 国外城市
+    const getCities = async () => {
+      const { data } = await getCitiesById({
+        areaId: areaId.value,
+      });
+      if (data.data != "") {
+        const citiesCode = data.data.split('/')[0];
+        const countriesCode = data.data.split('/')[1];
+        countryOptions.value.find(item => {
+          if (item.value === countriesCode) {
+            countryValue.value = item.text;
+            item.children.find(item => {
+              if (item.value === citiesCode) {
+                cityValue.value = item.text;
+              }
+            });
+          }
+        });
+        if (countryValue.value == cityValue.value) {
+          fieldValue.value = cityValue.value;
+        } else {
+          fieldValue.value = countryValue.value + "/" + cityValue.value;
+        }
+      }
+    };
+
     // 地区弹窗
     const fieldValue = ref("");
-    const kCascaderRef = ref(null);
-    // 点击地区输入框
-    const fieldValueInpClk = () => {
-      kCascaderRef.value.openPop();
-    };
-    // 选择地区完成
-    const areaPopFinish = async (e) => {
-      fieldValue.value = e.selectName;
-      accountDetail.value.areaId = e.selectId;
+    // 地区参数值
+    const areaValue = ref('');
+    const onConfirmArea = async ({ selectedOptions }) => {
+      if (selectedOptions[0]?.text == selectedOptions[1]?.text) {
+        fieldValue.value = selectedOptions[0]?.text;
+        if (user.ifForeign === "1") {
+          areaValue.value = selectedOptions[1]?.value;
+        } else {
+          areaValue.value = selectedOptions[0]?.text;
+        }
+      } else {
+        fieldValue.value = selectedOptions[0]?.text + "/" + selectedOptions[1]?.text;
+        if (user.ifForeign === "1") {
+          areaValue.value = selectedOptions[1]?.value;
+        } else {
+          areaValue.value = selectedOptions[0]?.text + selectedOptions[1]?.text;
+        }
+      }
       const params = {
-        id: user.id,
-        areaId: e.selectId,
+        adminId: user.id,
+        areaValue: areaValue.value,
       };
-      const { data } = await updateAdmin(params);
+      const { data } = await updateArea(params);
+      if (data.code === "00000") {
+        getAcccountDetail();
+      }
+
+      showArea.value = false;
       areaShow.value = true;
+    };
+    const onConfirmCountry = async ({ selectedOptions }) => {
+      if (selectedOptions[0]?.text == selectedOptions[1]?.text) {
+        fieldValue.value = selectedOptions[1]?.text;
+      } else {
+        fieldValue.value = selectedOptions.map((option) => option.text).join('/');
+      }
+      areaValue.value = selectedOptions[1]?.value;
+      const params = {
+        adminId: user.id,
+        areaValue: areaValue.value,
+      };
+      const { data } = await updateArea(params);
       if (data.code === "00000") {
-        showToast(data.message);
-        setTimeout(() => {
-          getAcccountDetail();
-        }, 500);
+        getAcccountDetail();
       }
+      showCountry.value = false;
+      areaShow.value = true;
     };
     // 时区弹窗
     const tzFieldValue = ref("");
@@ -893,8 +995,6 @@ export default {
       try {
         const userInfo = localStorage.getItem("loginUser");
         const userIfForeign = JSON.parse(userInfo);
-        // console.log("用户的海内外信息" + userIfForeign.ifForeign);
-        // console.log("看下user是什么***" + user.menuCodeList);
         if (userIfForeign.ifForeign === '1') {
           isAbroad.value = true;
           isInland.value = false;
@@ -909,14 +1009,31 @@ export default {
       checkIsAbroad();
       haveRelationCheck();
     })
-    // 获取地区回显的值
-    const getAreaName = (e) => {
-      fieldValue.value = e;
-    };
     // 获取时区回显的值
     const getTimezone = (e) => {
       tzFieldValue.value = e;
     };
+
+    // 搜索关键词
+    const searchValue = ref('');
+    const countryData = ref(languageName.value == 'zh' ? countriesData : countriesDataEn);
+    // 搜索数据
+    const valueChange = (index) => {
+      let tempOptions = [];
+      if (searchValue.value) {
+        if (index === 0) {
+          // 国家
+          countryData.value.forEach(item => {
+            if (item.text.includes(searchValue.value)) {
+              tempOptions.push(item);
+            }
+          });
+          countryOptions.value = tempOptions;
+        }
+      } else {
+        countryOptions.value = countryData.value;
+      }
+    };
     return {
       user,
       operUnipay,
@@ -939,15 +1056,12 @@ export default {
       accountDetail,
       fieldValue,
       tzFieldValue,
-      kCascaderRef,
       kTimezoneRef,
-      fieldValueInpClk,
       tzFieldValueInpClk,
-      areaPopFinish,
+      // areaPopFinish,
       timezonePopFinish,
       timezoneShowPicker,
       isInWeChat,
-      getAreaName,
       getTimezone,
       isAbroad,
       haveRelation,
@@ -967,6 +1081,16 @@ export default {
       onOffNotice,
       changeOnOffNotice,
       timezoneOnConfirm,
+      clickShowArea,
+      showArea,
+      areaOptions,
+      onConfirmArea,
+      showCountry,
+      countryOptions,
+      onConfirmCountry,
+
+      searchValue,
+      valueChange
     };
   }
 };