修复总结后的问题,详见企业微信文档
This commit is contained in:
@@ -386,6 +386,7 @@ const emit = defineEmits<{
|
||||
editClick: [row: IObject];
|
||||
operatClick: [data: IOperatData];
|
||||
filterChange: [data: IObject];
|
||||
selectChange: []
|
||||
}>();
|
||||
|
||||
// 主键
|
||||
@@ -490,6 +491,7 @@ function handleSelectionChange(selection: any[]) {
|
||||
console.log("defaultSelData.value", defaultSelData.value);
|
||||
selectionData.value = selection;
|
||||
removeIds.value = selection.map((item) => item[pk]);
|
||||
emit('selectChange', getselectTable())
|
||||
}
|
||||
// 获取选中的表格数据
|
||||
function getselectTable() {
|
||||
|
||||
@@ -5,18 +5,8 @@
|
||||
<el-input v-model="searhForm.name" placeholder="商品名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select
|
||||
style="width: 200px"
|
||||
v-model="searhForm.category"
|
||||
placeholder="商品分类"
|
||||
:disabled="disableCategory"
|
||||
>
|
||||
<el-option
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in categoryList"
|
||||
:key="item.id"
|
||||
></el-option>
|
||||
<el-select style="width: 200px" v-model="searhForm.category" placeholder="商品分类" :disabled="disableCategory">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in categoryList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -25,7 +15,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="head-container">
|
||||
<el-table ref="table" :data="tableData.list" height="500" v-loading="tableData.loading">
|
||||
<el-table ref="table" :data="tableData.list" height="500" border stripe v-loading="tableData.loading">
|
||||
<el-table-column type="selection" width="55" align="center" v-if="!radio"></el-table-column>
|
||||
<el-table-column label="商品信息">
|
||||
<template v-slot="scope">
|
||||
@@ -72,14 +62,9 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination
|
||||
:total="tableData.total"
|
||||
:current-page="tableData.page"
|
||||
:page-size="tableData.size"
|
||||
@current-change="paginationChange"
|
||||
@size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
></el-pagination>
|
||||
<el-pagination :total="tableData.total" :current-page="tableData.page" :page-size="tableData.size"
|
||||
@current-change="paginationChange" @size-change="sizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||
<template #footer>
|
||||
<span class="dialog-footer" v-if="!radio">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
@@ -132,7 +117,7 @@ export default {
|
||||
},
|
||||
// 确定选商品
|
||||
confirmHandle() {
|
||||
let res = this.$refs.table.selection;
|
||||
let res = this.$refs.table.getSelectionRows();
|
||||
console.log(res);
|
||||
if (!res) {
|
||||
return ElMessage.error("请选择商品");
|
||||
@@ -148,6 +133,7 @@ export default {
|
||||
this.tableData.page = 1;
|
||||
this.tableData.size = 10;
|
||||
this.tableData.list = [];
|
||||
this.getTableData();
|
||||
},
|
||||
// 分页大小改变
|
||||
sizeChange(e) {
|
||||
|
||||
123
src/components/resetPassword/CaptchaBtn.vue
Normal file
123
src/components/resetPassword/CaptchaBtn.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<!-- 验证码按钮 - 纯功能高度定制版 -->
|
||||
<el-button :type="buttonType" :size="buttonSize" :disabled="disabled || isCountingDown" :loading="isLoading"
|
||||
class="captcha-btn" @click="handleGetCaptcha">
|
||||
<!-- 倒计时状态展示 -->
|
||||
<span v-if="isCountingDown">{{ countDown }} 秒后重新获取</span>
|
||||
<!-- 正常状态展示 -->
|
||||
<span v-else>{{ buttonText }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { getSms } from "@/api/common";
|
||||
|
||||
// 接收父组件传递的自定义参数
|
||||
const props = defineProps({
|
||||
// 验证码类型
|
||||
// editShopInfoOpePwd 店铺操作密码
|
||||
// wxMiniPwd 微信小程序用户登录密码
|
||||
// shopPwd 店铺登录密码
|
||||
type: {
|
||||
type: String,
|
||||
default: 'editShopInfoOpePwd'
|
||||
},
|
||||
// 按钮类型(primary/success/warning/danger/info/default)
|
||||
buttonType: {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
// 按钮尺寸(large/default/small)
|
||||
buttonSize: {
|
||||
type: String,
|
||||
default: 'default'
|
||||
},
|
||||
// 正常状态按钮文字
|
||||
buttonText: {
|
||||
type: String,
|
||||
default: '获取验证码'
|
||||
},
|
||||
// 倒计时总秒数
|
||||
countDownNum: {
|
||||
type: Number,
|
||||
default: 60
|
||||
},
|
||||
// 手动控制按钮禁用状态
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
// 发射事件给父组件
|
||||
const emit = defineEmits(['get-captcha'])
|
||||
|
||||
// 加载状态(请求验证码时)
|
||||
const isLoading = ref(false)
|
||||
// 是否正在倒计时
|
||||
const isCountingDown = ref(false)
|
||||
// 倒计时秒数
|
||||
const countDown = ref(0)
|
||||
// 倒计时定时器
|
||||
let timer = null
|
||||
|
||||
// 获取验证码点击事件
|
||||
const handleGetCaptcha = async () => {
|
||||
// 倒计时中 / 加载中 / 禁用状态 禁止点击
|
||||
if (isCountingDown.value || isLoading.value || props.disabled) return
|
||||
|
||||
try {
|
||||
// 开启加载状态
|
||||
isLoading.value = true
|
||||
// 触发父组件的请求方法(真正的接口请求写在父组件)
|
||||
await getSms({ type: props.type });
|
||||
ElNotification.success({
|
||||
title: '成功',
|
||||
message: '验证码已发送,请注意查收',
|
||||
});
|
||||
// ======================
|
||||
// 请求成功 → 开始倒计时
|
||||
// ======================
|
||||
startCountDown()
|
||||
} catch (error) {
|
||||
// 请求失败 → 不触发倒计时,控制台提示
|
||||
console.error('', error)
|
||||
} finally {
|
||||
// 关闭加载状态
|
||||
setTimeout(() => {
|
||||
isLoading.value = false
|
||||
}, 500) // 适当延迟,避免闪烁
|
||||
}
|
||||
}
|
||||
|
||||
// 倒计时核心逻辑
|
||||
const startCountDown = () => {
|
||||
// 初始化倒计时时间
|
||||
countDown.value = props.countDownNum
|
||||
isCountingDown.value = true
|
||||
|
||||
// 开启定时器
|
||||
timer = setInterval(() => {
|
||||
countDown.value--
|
||||
// 倒计时结束
|
||||
if (countDown.value <= 0) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
isCountingDown.value = false
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 页面销毁时清除定时器(防止内存泄漏)
|
||||
onUnmounted(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 你可以在这里自定义按钮默认样式,也可以在父组件覆盖 */
|
||||
.captcha-btn {
|
||||
min-width: 120px;
|
||||
}
|
||||
</style>
|
||||
180
src/components/resetPassword/index.vue
Normal file
180
src/components/resetPassword/index.vue
Normal file
@@ -0,0 +1,180 @@
|
||||
<template>
|
||||
<el-dialog title="修改密码" modal-append-to-body append-to-body v-model="dialogVisible" @close="reset" width="400px">
|
||||
<el-form ref="refForm" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="手机号">
|
||||
<el-input :value="maskPhone(shopInfo.phone)" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="旧密码" prop="originalPassword">
|
||||
<el-input type="password" show-password v-model="form.originalPassword" placeholder="请输入旧密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="password">
|
||||
<el-input type="password" show-password v-model="form.password" placeholder="请输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-top: -10px;"><el-text :type="isPws ? 'danger' : 'info'" size="small"
|
||||
style="line-height: 16px;">注意:新密码必须至少包含字母、数字、特殊符号中的两种,且长度6-18位</el-text></el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkPassword">
|
||||
<el-input type="password" show-password v-model="form.checkPassword" placeholder="请再次输入新密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码" prop="code">
|
||||
<div class="center">
|
||||
<el-input v-model="form.code" placeholder="请输入验证码"></el-input>
|
||||
<captcha-btn type="shopPwd" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import sysUser from "@/api/account/sysUser";
|
||||
import { ElNotification } from "element-plus";
|
||||
import { maskPhone } from "@/utils";
|
||||
import CaptchaBtn from "./CaptchaBtn.vue";
|
||||
|
||||
const props = defineProps({
|
||||
// 修改成功后的跳转类型 1- 跳转到登录页 2- 留在当前页
|
||||
type: {
|
||||
type: [String, Number],
|
||||
default: 1
|
||||
}
|
||||
})
|
||||
|
||||
const shopInfo = ref({
|
||||
phone: ''
|
||||
})
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const formLoading = ref(false);
|
||||
|
||||
const isPws = ref(false);
|
||||
|
||||
const form = reactive({
|
||||
id: '',
|
||||
originalPassword: "", // 原密码
|
||||
code: '', // 验证码
|
||||
checkPassword: "", // 确认新密码
|
||||
password: "", // 新密码
|
||||
});
|
||||
|
||||
function reset() {
|
||||
form.originalPassword = "";
|
||||
form.checkPassword = "";
|
||||
form.password = "";
|
||||
form.code = "";
|
||||
refForm.value.resetFields();
|
||||
}
|
||||
|
||||
const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,}$/;
|
||||
const validateNewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
||||
if (!form.password) {
|
||||
callback(new Error(" "));
|
||||
} else if (form.password === form.originalPassword) {
|
||||
callback(new Error("请输入与旧密码不同的新密码"));
|
||||
} else if (form.password.length < 6 || form.password.length > 18) {
|
||||
// 密码长度6 - 18位
|
||||
callback(new Error("密码长度应为6-18位"));
|
||||
} else if (!reg.test(form.password)) {
|
||||
// 新密码长度不能小于6 需包含字母、数字、特殊符号中至少两种
|
||||
isPws.value = true;
|
||||
callback(new Error(""));
|
||||
} else {
|
||||
isPws.value = false;
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const validateRnewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
||||
if (!form.checkPassword) {
|
||||
callback(new Error(" "));
|
||||
} else if (form.checkPassword !== form.password) {
|
||||
callback(new Error("两次密码输入不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const rules = {
|
||||
originalPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: " ",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateNewPass,
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
checkPassword: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateRnewPass,
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: " ",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
const refForm = ref();
|
||||
// 提交修改密码
|
||||
function submitHandle() {
|
||||
refForm.value.validate(async (vaild: boolean) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true;
|
||||
await sysUser.pwd(form);
|
||||
if (props.type == 1) {
|
||||
ElNotification.success("密码修改成功,请重新登录");
|
||||
setTimeout(() => {
|
||||
router.push("/login");
|
||||
}, 1000);
|
||||
} else {
|
||||
ElNotification.success("密码修改成功");
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
emit('success')
|
||||
} catch (error) {
|
||||
formLoading.value = false;
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function show(e: object) {
|
||||
console.log(e);
|
||||
shopInfo.value = e
|
||||
form.id = e.id
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user