2 Commits 6c90d73fad ... f6904544f5

Auteur SHA1 Bericht Datum
  Luka f6904544f5 Merge branch 'master' of ssh://www.yixzm.cn:22022/Dim5-ideal/bj-maritime-dcds 6 dagen geleden
  Luka 37cddc2008 Merge branch 'master' of ssh://www.yixzm.cn:22022/Dim5-ideal/bj-maritime-dcds 6 dagen geleden
4 gewijzigde bestanden met toevoegingen van 509 en 1 verwijderingen
  1. 10 0
      frontend/.eslintrc.js
  2. 293 0
      frontend/src/views/login.vue
  3. 1 1
      frontend/src/views/preview.vue
  4. 205 0
      frontend/src/views/system/user/index.vue

+ 10 - 0
frontend/.eslintrc.js

@@ -45,6 +45,12 @@ module.exports = {
         ],
         'no-eval': 2,
         semi: 1,
+<<<<<<< HEAD
+<<<<<<< HEAD
+        indent: off,
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
         indent: [
             2,
             4,
@@ -52,6 +58,10 @@ module.exports = {
                 SwitchCase: 1,
             },
         ],
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
         camelcase: 2,
         'vue/no-empty-component-block': 2, // 禁止<template> <script> <style>块为空
         'vue/html-self-closing': 0,

+ 293 - 0
frontend/src/views/login.vue

@@ -84,6 +84,23 @@ import { ref } from 'vue';
 const userStore = useUserStore();
 const router = useRouter();
 const loginForm = ref<any>({
+<<<<<<< HEAD
+<<<<<<< HEAD
+	username: 'admin',
+	password: 'admin123',
+	rememberMe: false,
+	code: '',
+	uuid: '',
+	phone: '',
+});
+
+const loginRules = {
+	username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
+	password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }],
+	code: [{ required: true, trigger: 'change', message: '请输入验证码' }],
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     username: 'admin',
     password: 'admin123',
     rememberMe: false,
@@ -96,6 +113,10 @@ const loginRules = {
     username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
     password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }],
     code: [{ required: true, trigger: 'change', message: '请输入验证码' }],
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 };
 
 const codeUrl = ref('');
@@ -114,6 +135,91 @@ const isFlag = ref(true);
 let countdown = ref(60);
 const isCountingDown = ref(false);
 const countdownText = computed(() => {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	return isCountingDown.value ? `${countdown.value}s 后重新获取` : '获取验证码';
+});
+const getVerificationCode = async () => {
+	if (!isCountingDown.value) {
+		await getPhoneCode({ uuid: loginForm.value.uuid }).then((res: any) => {
+			console.log(res);
+			if (res.code === 200) {
+				ElMessage.success('验证码发送成功');
+			} else {
+				ElMessage.error('验证码发送失败,请稍后重试');
+			}
+		});
+		isCountingDown.value = true;
+		countdown.value = 60;
+		const intervalId = setInterval(() => {
+			countdown.value--;
+			if (countdown.value <= 0) {
+				isCountingDown.value = false;
+				clearInterval(intervalId);
+			}
+		}, 1000);
+	}
+};
+
+const publicKey =
+	'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+	'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';
+const privateKey =
+	'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+	'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+	'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+	'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+	'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+	'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+	'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+	'UP8iWi1Qw0Y=';
+// -------------- 获取验证码 倒计时60秒 end ----------------
+// 有下一步的登陆
+const handleNext = () => {
+	loginFirstRef.value?.validate(valid => {
+		if (valid) {
+			loading.value = true;
+			// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
+			if (loginForm.value.rememberMe) {
+				Cookies.set('username', loginForm.value.username, { expires: 30 });
+				const enPwd = encrypt(loginForm.value.password, publicKey);
+				// const enPwd = loginForm.value.password;
+				if (enPwd) {
+					Cookies.set('password', enPwd, { expires: 30 });
+				}
+				if (loginForm.value.rememberMe) {
+					Cookies.set('rememberMe', String(loginForm.value.rememberMe), { expires: 30 });
+				}
+			} else {
+				// 否则移除
+				Cookies.remove('username');
+				Cookies.remove('password');
+				Cookies.remove('rememberMe');
+			}
+			// 调用action的登录方法
+			userStore
+				.phoneLogin(loginForm.value)
+				.then((res: any) => {
+					console.log(res);
+					// router.push({ path: redirect.value || '/' });
+					isFlag.value = false;
+					loading.value = false;
+					loginForm.value.code = '';
+					loginForm.value.uuid = res.uuid;
+					loginForm.value.phone = res.phone;
+				})
+				.catch(() => {
+					loading.value = false;
+					// 重新获取验证码
+					if (captchaEnabled.value) {
+						getCode();
+					}
+				});
+		}
+	});
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     return isCountingDown.value ? `${countdown.value}s 后重新获取` : '获取验证码';
 });
 const getVerificationCode = async () => {
@@ -194,10 +300,33 @@ const handleNext = () => {
                 });
         }
     });
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 };
 
 // 有下一步的最后一步
 const handleEndLogin = () => {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	userStore
+		.phoneLogin(loginForm.value)
+		.then((res: any) => {
+			if (res.token) {
+				ElMessage.success('登陆成功');
+				router.push({ path: redirect.value || '/' });
+			} else {
+				ElMessage.error('登陆失败');
+			}
+			loading.value = false;
+		})
+		.catch(() => {
+			loading.value = false;
+		});
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     userStore
         .phoneLogin(loginForm.value)
         .then((res: any) => {
@@ -212,10 +341,37 @@ const handleEndLogin = () => {
         .catch(() => {
             loading.value = false;
         });
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 };
 
 // 无下一步的登陆
 function handleLogin() {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	loginFirstRef.value?.validate(valid => {
+		if (valid) {
+			loading.value = true;
+			// 调用action的登录方法
+			userStore
+				.login(loginForm.value)
+				.then(() => {
+					router.push({ path: redirect.value || '/' });
+				})
+				.catch(() => {
+					loading.value = false;
+					// 重新获取验证码
+					if (captchaEnabled.value) {
+						getCode();
+					}
+				});
+		}
+	});
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     loginFirstRef.value?.validate(valid => {
         if (valid) {
             loading.value = true;
@@ -234,10 +390,31 @@ function handleLogin() {
                 });
         }
     });
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 }
 
 // 登陆按钮
 const handleAllLogin = () => {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	// 本地
+	// if (env === 'development') {
+	//     handleLogin();
+	// } else {
+	//     handleNext();
+	// }
+	// handleNext();
+	if (phoneCaptchaEnabled.value) {
+		handleNext();
+	} else {
+		handleLogin();
+	}
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     // 本地
     // if (env === 'development') {
     //     handleLogin();
@@ -250,11 +427,46 @@ const handleAllLogin = () => {
     } else {
         handleLogin();
     }
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 };
 
 // 是否有手机号
 const phoneCaptchaEnabled = ref(false);
 function getCode() {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	getCodeImg().then((res: any) => {
+		captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
+		phoneCaptchaEnabled.value = res.phoneCaptchaEnabled;
+		if (captchaEnabled.value) {
+			codeUrl.value = 'data:image/gif;base64,' + res.img;
+			loginForm.value.uuid = res.uuid;
+		}
+	});
+}
+
+function getCookie() {
+	const username = Cookies.get('username');
+	const password = Cookies.get('password');
+	const rememberMe = Cookies.get('rememberMe');
+	// let publicKey = '';
+
+	// getPublicKey().then((res: any) => {
+	//     publicKey = res.publicKey;
+	// });
+
+	loginForm.value = {
+		username: username === undefined ? loginForm.value.username : username,
+		password: password === undefined ? loginForm.value.password : decrypt(password, privateKey) || '',
+		// password: password === undefined ? loginForm.value.password : password || '',
+		rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
+	};
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     getCodeImg().then((res: any) => {
         captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
         phoneCaptchaEnabled.value = res.phoneCaptchaEnabled;
@@ -281,6 +493,10 @@ function getCookie() {
         // password: password === undefined ? loginForm.value.password : password || '',
         rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
     };
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 }
 
 getCode();
@@ -289,6 +505,79 @@ getCookie();
 
 <style lang="scss" scoped>
 .login {
+<<<<<<< HEAD
+<<<<<<< HEAD
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	height: 100%;
+	background-image: url('../assets/images/login-background.jpg');
+	background-size: cover;
+}
+
+.title {
+	margin: 0px auto 30px auto;
+	text-align: center;
+	color: #707070;
+}
+
+.login-form {
+	border-radius: 6px;
+	background: #ffffff;
+	width: 400px;
+	padding: 25px 25px 5px 25px;
+
+	.el-input {
+		height: 40px;
+
+		input {
+			height: 40px;
+		}
+	}
+
+	.input-icon {
+		height: 39px;
+		width: 14px;
+		margin-left: 0px;
+	}
+}
+
+.login-tip {
+	font-size: 13px;
+	text-align: center;
+	color: #bfbfbf;
+}
+
+.login-code {
+	width: 33%;
+	height: 40px;
+	float: right;
+
+	img {
+		cursor: pointer;
+		vertical-align: middle;
+	}
+}
+
+.el-login-footer {
+	height: 40px;
+	line-height: 40px;
+	position: fixed;
+	bottom: 0;
+	width: 100%;
+	text-align: center;
+	color: #fff;
+	font-family: Arial;
+	font-size: 12px;
+	letter-spacing: 1px;
+}
+
+.login-code-img {
+	height: 40px;
+	padding-left: 12px;
+=======
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     display: flex;
     justify-content: center;
     align-items: center;
@@ -357,5 +646,9 @@ getCookie();
 .login-code-img {
     height: 40px;
     padding-left: 12px;
+<<<<<<< HEAD
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 }
 </style>

+ 1 - 1
frontend/src/views/preview.vue

@@ -141,4 +141,4 @@ onMounted(async () => {
 </style> -->
 <script setup lang="ts"></script>
 <template></template>
-<style scoped></style>
+<style scoped></style>

+ 205 - 0
frontend/src/views/system/user/index.vue

@@ -110,6 +110,20 @@
                                 <el-button v-hasPermi="['system:user:edit']" link type="primary" icon="CircleCheck"
                                     @click="handleAuthRole(scope.row)"></el-button>
                             </el-tooltip>
+<<<<<<< HEAD
+<<<<<<< HEAD
+                            <el-tooltip v-if="scope.row.userId !== 1" content="车牌号录入" placement="top">
+                                <el-button v-hasPermi="['system:user:edit']" link type="primary" icon="List"
+                                    @click="handleAddCar(scope.row)"></el-button>
+                            </el-tooltip>
+                            <el-tooltip v-if="scope.row.userId !== 1" content="座机号录入" placement="top">
+                                <el-button v-hasPermi="['system:user:edit']" link type="primary" icon="PhoneFilled"
+                                    @click="handleAddLandline(scope.row)"></el-button>
+                            </el-tooltip>
+=======
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
                         </template>
                     </el-table-column>
                 </el-table>
@@ -180,6 +194,25 @@
                     </el-col>
                 </el-row>
                 <el-row>
+<<<<<<< HEAD
+<<<<<<< HEAD
+                    <!-- <el-col :span="12">
+                        <el-form-item label="岗位">
+                            <el-select v-model="form.postIds" multiple placeholder="请选择">
+                                <el-option
+                                    v-for="item in postOptions"
+                                    :key="item.postId"
+                                    :label="item.postName"
+                                    :value="item.postId"
+                                    :disabled="item.status == 1"
+                                ></el-option>
+                            </el-select>
+                        </el-form-item>
+                    </el-col> -->
+=======
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
                     <el-col :span="12">
                         <el-form-item label="角色" prop="roleIds">
                             <el-select @change="getLabel" v-model="form.roleIds" multiple placeholder="请选择">
@@ -236,6 +269,48 @@
                 </div>
             </template>
         </el-dialog>
+<<<<<<< HEAD
+<<<<<<< HEAD
+
+        <!-- 录入车牌号对话框 -->
+        <el-dialog :close-on-click-modal="false" v-model="car.open" :title="car.title" width="400px" append-to-body>
+            <div v-for="(item, index) in plateNo" :key="index" class="mb20">
+                <div class="flex">
+                    <el-input v-model="item.number" placeholder="请输入车牌号" style="width: 70%" />
+                    <el-button class="ml20" v-if="plateNo.length > 1" @click="handleCar(0, index)">-</el-button>
+                    <el-button type="primary" v-if="index + 1 === plateNo.length" class="ml20"
+                        @click="handleCar(1, index)">+</el-button>
+                </div>
+            </div>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button type="primary" @click="submitCarForm">确 定</el-button>
+                    <el-button @click="cancelCar">取 消</el-button>
+                </div>
+            </template>
+        </el-dialog>
+        <!-- 录入座机号对话框 -->
+        <el-dialog :close-on-click-modal="false" v-model="landline.open" :title="landline.title" width="400px"
+            append-to-body>
+            <div v-for="(item, index) in landlineNo" :key="index" class="mb20">
+                <div class="flex">
+                    <el-input v-model="item.number" placeholder="请输入座机号" style="width: 70%" />
+                    <el-button class="ml20" v-if="landlineNo.length > 1" @click="handleLandline(0, index)">-</el-button>
+                    <el-button type="primary" v-if="index + 1 === landlineNo.length" class="ml20"
+                        @click="handleLandline(1, index)">+</el-button>
+                </div>
+            </div>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button type="primary" @click="submitLandlineNoForm">确 定</el-button>
+                    <el-button @click="cancelLandline">取 消</el-button>
+                </div>
+            </template>
+        </el-dialog>
+=======
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     </div>
 </template>
 
@@ -299,6 +374,128 @@ const upload = reactive({
     // 上传的地址
     url: import.meta.env.VITE_APP_BASE_API + '/system/user/importData',
 });
+<<<<<<< HEAD
+<<<<<<< HEAD
+/*** 座机录入参数 */
+const landline = reactive({
+    // 是否显示弹出层
+    open: false,
+    // 弹出层标题
+    title: '座机录入',
+    landlineNumber: '',
+});
+/*** 车牌录入参数 */
+const car = reactive({
+    // 是否显示弹出层
+    open: false,
+    // 弹出层标题
+    title: '车牌录入',
+    jobNumber: '',
+});
+// 车牌录入
+const plateNo = ref([{ number: '' }]);
+// 座机录入
+const landlineNo = ref([{ number: '' }]);
+// const plateNo = ref(['12345', '678910']);
+// 座机录入的确定按钮
+function submitLandlineNoForm() {
+    let landlineNumbers = landlineNo.value.map(item => {
+        return item.number;
+    });
+    if (landlineNumbers.length === 1 && landlineNumbers[0] === '') {
+        landlineNumbers = [];
+    }
+    const data = { landlineNumber: landlineNumbers, jobNumber: landline.landlineNumber };
+    addLandlineNumber(data).then((res: any) => {
+        if (res.code === 200) {
+            ElMessage.success(res.msg);
+            cancelLandline();
+            getList();
+        } else {
+            ElMessage.error(res.msg);
+            cancelLandline();
+            getList();
+        }
+    });
+}
+// 车牌录入的确定按钮
+function submitCarForm() {
+    let carNumbers = plateNo.value.map(item => {
+        return item.number;
+    });
+    if (carNumbers.length === 1 && carNumbers[0] === '') {
+        carNumbers = [];
+    }
+    const data = { plateNo: carNumbers, jobNumber: car.jobNumber };
+    addCarNumber(data).then((res: any) => {
+        if (res.code === 200) {
+            ElMessage.success(res.msg);
+            cancelCar();
+            getList();
+        } else {
+            ElMessage.error(res.msg);
+            cancelCar();
+            getList();
+        }
+    });
+}
+// 车牌的加减
+function handleCar(type, index) {
+    if (type === 0) {
+        plateNo.value.splice(index, 1);
+    }
+    if (type === 1) {
+        plateNo.value.push({ number: '' });
+    }
+}
+// 座机的加减
+function handleLandline(type, index) {
+    if (type === 0) {
+        landlineNo.value.splice(index, 1);
+    }
+    if (type === 1) {
+        landlineNo.value.push({ number: '' });
+    }
+}
+// 车牌录入的取消按钮
+function cancelCar() {
+    car.open = false;
+    plateNo.value = [{ number: '' }];
+}
+// 座机录入的取消按钮
+function cancelLandline() {
+    landline.open = false;
+    landlineNo.value = [{ number: '' }];
+}
+/** 车牌号录入 */
+function handleAddCar(row: any) {
+    car.jobNumber = row.jobNumber;
+    car.open = true;
+    if (row.dhPlateNoVos.length > 0) {
+        plateNo.value = [];
+        row.dhPlateNoVos.forEach((item: any) => {
+            plateNo.value.push({ number: item.plateNo });
+        });
+    }
+    proxy!.resetForm('carRef');
+}
+/** 座机号录入 */
+function handleAddLandline(row: any) {
+    landline.landlineNumber = row.jobNumber;
+    landline.open = true;
+    if (row.landlineNumbers.length > 0) {
+        landlineNo.value = [];
+        row.landlineNumbers.forEach((item: any) => {
+            console.log(item, 'xxx');
+            landlineNo.value.push({ number: item.landlineNumber });
+        });
+    }
+    proxy!.resetForm('carRef');
+}
+=======
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
 // 列显隐信息
 const columns = ref([
     { key: 0, label: `用户编号`, visible: true },
@@ -306,6 +503,14 @@ const columns = ref([
     { key: 2, label: `用户昵称`, visible: true },
     { key: 3, label: `部门`, visible: true },
     { key: 4, label: `手机号码`, visible: true },
+<<<<<<< HEAD
+<<<<<<< HEAD
+    { key: 7, label: `工号`, visible: true },
+    { key: 8, label: `车牌号`, visible: true },
+=======
+>>>>>>> e94f5f44564039f665611f42b365b51740d0649c
+=======
+>>>>>>> 6c90d73fadd504a5827e77c4e8dc469f3608d6d0
     { key: 5, label: `状态`, visible: true },
     { key: 6, label: `创建时间`, visible: true },
 ]);