保存进度!

This commit is contained in:
2022-12-15 09:25:51 +08:00
parent 5c72437e2d
commit 5dcff64bf5
130 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

View File

@@ -0,0 +1,17 @@
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App" />
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";
export default {
name: "Home",
components: {
HelloWorld
}
};
</script>

View File

@@ -0,0 +1,346 @@
<!-- eslint-disable prettier/prettier -->
<template>
<div id="login">
<div class="form-wrap">
<ul class="menu-tab">
<li @click="data.current_menu = item.type" :class="{'current': data.current_menu === item.type}" v-for="item in data.tab_menu" :key="item.type">{{ item.label }}</li>
</ul>
<el-form ref="account_form" :model="data.form" :rules="data.form_rules">
<el-form-item prop="username">
<label class="form-label">用户名</label>
<el-input v-model="data.form.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<label class="form-label">密码</label>
<el-input type="password" v-model="data.form.password"></el-input>
</el-form-item>
<el-form-item prop="passwords" v-if="data.current_menu === 'register'">
<label class="form-label">确认密码</label>
<el-input type="password" v-model="data.form.passwords"></el-input>
</el-form-item>
<el-form-item prop="code">
<label class="form-label">验证码</label>
<el-row :gutter="10">
<el-col :span="14">
<el-input v-model="data.form.code"></el-input>
</el-col>
<el-col :span="10">
<el-button type="success" class="el-button-block" :loading="data.code_button_loading" :disabled="data.code_button_disabled" @click="handlerGetCode">{{ data.code_button_text }}</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-button type="danger" @click="submitForm" :disabled="data.submit_button_disabled" :loading="data.submit_button_loading" class="el-button-block">
{{ data.current_menu === "login" ? "登录": "注册"}}
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import { reactive, ref, onBeforeUnmount, getCurrentInstance } from 'vue';
import { useStore } from "vuex";
import { useRouter } from "vue-router";
// 校验类
import { validate_email, validate_password, validate_code } from "../../utils/validate";
// sha1
import sha1 from "js-sha1";
// API
import { GetCode } from "../../api/common";
import { Register, Login } from "../../api/account";
export default {
name: "Login",
components: {},
props: {},
setup(props){
const instance = getCurrentInstance();
// 获取实例上下文
const { proxy } = getCurrentInstance();
// store
const store = useStore();
// router
const rotuer = useRouter();
// 用户名校验
const validate_name_rules = (rule, value, callback) => {
let regEmail = validate_email(value);
if (value === '') {
callback(new Error("请输入邮箱"));
} else if(!regEmail) {
callback(new Error("邮箱格式不正确"));
} else {
callback();
}
}
const validate_password_rules = (rule, value, callback) => {
let regPassword = validate_password(value);
// 获取“确认密码”
const passwordsValue = data.form.passwords;
if (value === '') {
callback(new Error("请输入密码"));
} else if(!regPassword) {
callback(new Error("请输入>=6并且<=20位的密码包含数字、字母"));
} else {
callback();
}
}
// 校验确认密码
const validate_passwords_rules = (rule, value, callback) => {
// 如果是登录,不需要校验确认密码,默认通过
if(data.current_menu === "login") { callback(); }
let regPassword = validate_password(value);
// 获取“密码”
const passwordValue = data.form.password;
if (value === '') {
callback(new Error("请输入密码"));
} else if(!regPassword) {
callback(new Error("请输入>=6并且<=20位的密码包含数字、字母"));
} else if(passwordValue && passwordValue !== value){
callback(new Error("两次密码不一致"));
}else {
callback();
}
}
const validate_code_rules = (rule, value, callback) => {
let regCode = validate_code(value);
if (value === '') {
callback(new Error("请输入验证码"));
} else if(!regCode) {
callback(new Error("请输入6位的验证码"));
} else {
callback();
}
}
const data = reactive({
form: {
username: "", // 用户名
password: "", // 密码
passwords: "", // 确认密码
code: "", // 验证码
},
form_rules: {
username: [
{ validator: validate_name_rules, trigger: 'change' }
],
password: [
{ validator: validate_password_rules, trigger: 'change' }
],
passwords: [
{ validator: validate_passwords_rules, trigger: 'change' }
],
code: [
{ validator: validate_code_rules, trigger: 'change' }
]
},
tab_menu: [
{ type: "login", label: "登录" },
{ type: "register", label: "注册" }
],
current_menu: "login",
/**
* 获取验证码按钮交互
*/
code_button_disabled: false,
code_button_loading: false,
code_button_text: "获取验证码",
code_button_timer: null,
// 提交按钮
submit_button_disabled: true,
loading: false
})
// 获取验证码
const handlerGetCode = () => {
const username = data.form.username;
const password = data.form.password;
const passwords = data.form.passwords;
// 校验用户名
if(!validate_email(username)) {
proxy.$message.error({
message: "用户名不能为空 或 格式不正确",
type: "error"
})
return false;
}
// 校验密码
if(!validate_password(password)) {
proxy.$message({
message: "密码不能为空 或 格式不正确",
type: "error"
})
return false;
}
// 判断非 登录 时,校验两次密码
if(data.current_menu === 'register' && (password !== passwords)) {
proxy.$message({
message: "两次密码不一致",
type: "error"
})
return false;
}
// 获取验证码接口
const requestData = {
username: data.form.username,
module: data.current_menu
}
data.code_button_loading = true;
data.code_button_text = "发送中";
GetCode(requestData).then(response => {
const resData = response;
// 激活提交按钮
data.submit_button_disabled = false;
// 用户名存在
if(resData.resCode === 1024) {
proxy.$message.error(resData.message);
return false;
}
// 成功 Elementui 提示
proxy.$message({
message: resData.message,
type: "success"
})
// 执行倒计时
countdown();
}).catch(error => {
data.code_button_loading = false;
data.code_button_text = "获取验证码";
})
}
/** 倒计时 */
const countdown = (time) => {
if(time && typeof time !== 'number') { return false; }
let second = time || 60; // 默认时间
data.code_button_loading = false; // 取消加载
data.code_button_disabled = true; // 禁用按钮
data.code_button_text = `倒计进${second}`; // 按钮文本
// 判断是否存在定时器,存在则先清除
if(data.code_button_timer) { clearInterval(data.code_button_timer) };
// 开启定时器
data.code_button_timer = setInterval(() => {
second--;
data.code_button_text = `倒计进${second}`; // 按钮文本
if(second <= 0) {
data.code_button_text = `重新获取`; // 按钮文本
data.code_button_disabled = false; // 启用按钮
clearInterval(data.code_button_timer); // 清除倒计时
}
}, 1000)
}
/** 表单提交 */
const account_form = ref(null);
const submitForm = (formName) => {
account_form.value.validate((valid) => {
if (valid) {
data.current_menu === "login" ? login() : register();
} else {
alert('表单验证不通过');
return false;
}
});
}
/** 注册 */
const register = () => {
const requestData = {
username: data.form.username,
password: data.form.password,
code: data.form.code
}
data.submit_button_loading = true;
Register(requestData).then(response => {
proxy.$message({
message: response.message,
type: "success"
})
reset();
}).catch(error => {
data.submit_button_loading = false;
})
}
/** 登录 */
const login = () => {
const requestData = {
username: data.form.username,
password: sha1(data.form.password),
code: data.form.code
}
data.submit_button_loading = true;
store.dispatch("app/loginAction", requestData).then(response => {
data.submit_button_loading = false;
proxy.$message({
message: response.message,
type: "success"
})
//路由跳转
rotuer.push({path: "/admin"});
reset();
}).catch(error => {
data.submit_button_loading = false;
console.log("失败");
})
}
/** 重置 */
const reset = () => {
// 重置表单
proxy.$refs.form.resetFields();
// 切回登录模式
data.current_menu = "login";
// 清除定时器
data.code_button_timer && clearInterval(data.code_button_timer);
// 获取验证码重置文本
data.code_button_text = "获取验证码";
// 获取验证码激活
data.code_button_disabled = false;
// 禁用提交按钮
data.submit_button_disabled = true;
// 取消提交按钮加载
data.submit_button_loading = false;
}
// 组件销毁之前 - 生命周期
onBeforeUnmount(() => {
clearInterval(data.code_button_timer); // 清除倒计时
})
return {
data,
handlerGetCode,
submitForm,
account_form
}
}
}
</script>
<style lang='scss' scoped>
#login {
height: 100vh; // 设置高度,居于浏览器可视区高度
background-color: #344a5f; // 设置背景颜色
}
.form-wrap {
width: 320px;
padding-top: 100px; //上内边距
margin: auto; // 块元素水平居中
}
.menu-tab {
text-align: center;
li {
display: inline-block;
padding: 10px 24px;
margin: 0 10px;
color: #fff;
font-size: 14px;
border-radius: 5px;
cursor: pointer;
&.current { background-color: rgba(0, 0, 0, .1);}
}
}
.form-label {
display: block; // 转为块元素
color: #fff; // 设置字体颜色
font-size: 14px; // 设置字体大小
}
</style>

View File

@@ -0,0 +1,18 @@
<template>
<div class="">控制台</div>
</template>
<script>
import { useStore } from 'vuex'
export default {
name: 'NewsIndex',
components: {},
props: {},
setup(props){
const store = useStore();
store.dispatch("app/update_count");
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,304 @@
<template>
<el-button type="danger" @click="handlerCategory('first_category_add')">添加一级分类</el-button>
<hr class="spacing-hr" />
<el-row :gutter="20">
<el-col :span="7">
<el-tree ref="categoryTree" :data="data.tree_data" :props="data.defaultProps" default-expand-all :expand-on-click-node="false">
<template #default="{ node, data }">
<div class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<el-button type="danger" round @click="handlerCategory('child_category_add', node)">添加子级</el-button>
<el-button type="success" round @click="handlerCategory(node.level === 1 ? 'parent_category_edit' : 'child_category_edit', node)">编辑</el-button>
<el-button round @click="handlerCategory('delete_category', node)">删除</el-button>
</span>
</div>
</template>
</el-tree>
</el-col>
<el-col :span="17">
<h4 class="column">{{ config[config.type].title }}</h4>
<el-form label-width="100px">
<el-form-item label="父级分类:">
<el-input v-model.trim="data.parent_category" :disabled="config[config.type].parent_disabled" style="width: 20%;"></el-input>
</el-form-item>
<el-form-item label="子级分类:" v-if="config[config.type].sub_show">
<el-input v-model.trim="data.sub_category" :disabled="config[config.type].sub_disabled" style="width: 20%;"></el-input>
</el-form-item>
<el-form-item label="">
<el-button type="danger" :loading="data.button_loading" @click="handlerSubmit">确定</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<script>
import { ref, reactive, getCurrentInstance, onBeforeMount } from 'vue';
import { firstCategoryAdd, GetCategory, ChildCategoryAdd, CategoryEdit, CategoryDel } from "@/api/info";
export default {
name: 'InfoCategory',
components: {},
props: {},
setup(props){
// 获取实例上下文
const { proxy } = getCurrentInstance();
const data = reactive({
tree_data: [],
defaultProps: {
children: 'children',
label: 'category_name'
},
parent_category: "父级分类文本演示", // 父级分类
sub_category: "子级分类文本演示", // 子级分类
button_loading: false, // 按钮加载
parent_category_data: {},
sub_category_data: {}
})
const config = reactive({
type: "default",
default: {
title: "添加分类", // 标题
parent_disabled: true, // 父级分类禁用/启用
sub_disabled: true, // 子级分类禁用/启用
sub_show: true, // 子级分类显示/隐藏
clear: ["parent_category", "sub_category"]
},
first_category_add: {
title: "一级分类添加", // 标题
parent_disabled: false, // 父级分类禁用/启用
sub_disabled: true, // 子级分类禁用/启用
sub_show: false, // 子级分类显示/隐藏
clear: ["parent_category", "sub_category"]
},
child_category_add: {
title: "子级分类添加", // 标题
parent_disabled: true, // 父级分类禁用/启用
sub_disabled: false, // 子级分类禁用/启用
sub_show: true,
clear: ["sub_category"],
create: ["parent_category"]
},
parent_category_edit: {
title: "父级分类编辑", // 标题
parent_disabled: false, // 父级分类禁用/启用
sub_disabled: true, // 子级分类禁用/启用
sub_show: false,
create: ["parent_category"]
},
child_category_edit: {
title: "子级分类编辑", // 标题
parent_disabled: true, // 父级分类禁用/启用
sub_disabled: false, // 子级分类禁用/启用
sub_show: true,
create: ["parent_category", "sub_category"]
}
});
// const handleNodeClick = (data) => {
// console.log(data)
// }
const categoryTree = ref(null);
const handlerCategory = (type, category_data) => {
console.log(category_data);
if(type === "child_category_edit") {
data.parent_category_data = category_data.parent || null;
data.sub_category_data = category_data || null;
}else{
data.parent_category_data = category_data || null;
}
config.type = type === "delete_category" ? "default": type;
// 文本清除、还原
handlerInputValue();
// 弹窗二次提示
(type === "delete_category") && handlerDeleteComfirm();
}
const handlerInputValue = () => {
// 获取清除数据的对象
const clearObject = config[config.type].clear;
// 获取还原数据的对象
const createObject = config[config.type].create;
// 执行清除动作
if(clearObject && clearObject.length > 0) {
clearObject.forEach(item => {
data[item] = "";
})
}
// 执行还原动作
if(createObject && createObject.length > 0) {
createObject.forEach(item => {
data[item] = data[`${item}_data`].data.category_name;
})
}
}
//
const handlerSubmit = () => {
if(config.type === 'first_category_add') { handlerFirstCategoryAdd(); }
if(config.type === 'child_category_add') { handlerChildCategoryAdd(); }
if(config.type === 'child_category_edit' || config.type === 'parent_category_edit') { handlerCategoryEdit(); }
}
// 一级分类添加
const handlerFirstCategoryAdd = () => {
// 父级为空时提示
if(!data.parent_category) {
proxy.$message.error("父级分类不能为空");
return false
}
data.button_loading = true;
firstCategoryAdd({categoryName: data.parent_category}).then(response => {
data.button_loading = false;
proxy.$message({
message: response.message,
type: "success"
})
data.parent_category = "";
}).catch(error => {
data.button_loading = false;
})
}
const handlerGetCategory = () => {
GetCategory().then(response => {
const response_data = response.data
data.tree_data = response_data || [];
})
}
// 子级分类添加
const handlerChildCategoryAdd = () => {
// 子级为空时提示
if(!data.sub_category) {
proxy.$message.error("子级分类不能为空");
return false
}
// 按钮加载状态
data.button_loading = true;
// 接口
ChildCategoryAdd({
categoryName: data.sub_category, // 分类名称参数
parentId: data.parent_category_data.data.id // 父级分类ID参数
}).then(response => {
// 清除加载状态
data.button_loading = false;
// 成功提示
proxy.$message({
message: response.message,
type: "success"
})
// 清除子级分类文本
data.sub_category = "";
// 追加子级数据
categoryTree.value.append(response.data, data.parent_category_data);
}).catch(error => {
// 清除加载状态
data.button_loading = false;
})
}
// 分类编辑
const handlerCategoryEdit = () => {
// 分级为空时提示
console.log(!data.parent_category);
console.log(data.sub_category);
if(data.parent_category == "" || data.sub_category == "") {
const message = config.type === "parent_category_edit" ? "父级" : "子级";
proxy.$message.error(`${message}分类不能为空`);
return false
}
// 按钮加载状态
data.button_loading = true;
const node_parent = data.parent_category_data.data
const node_sub = data.sub_category_data.data
// 接口
CategoryEdit({
categoryName: config.type === "parent_category_edit" ? data.parent_category : data.sub_category, // 分类名称参数
id: config.type === "parent_category_edit" ? node_parent.id : node_sub.id // 分类ID参数
}).then(response => {
// 清除加载状态
data.button_loading = false;
// 成功提示
proxy.$message({
message: response.message,
type: "success"
})
// 同步更新树形菜单节点
const node_date = config.type === "parent_category_edit" ? node_parent : node_sub;
node_date.category_name = response.data.category_name;
}).catch(error => {
// 清除加载状态
data.button_loading = false;
})
}
const handlerDeleteComfirm = () => {
proxy.$confirm('确认删除该分类吗?删除后将无法恢复', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
showClose: false, // 取消右上角关闭按钮
closeOnClickModal: false, // 取消点击遮罩关闭 MessageBox
closeOnPressEscape: false, // 取消按下ESC键关闭MessageBox
type: 'warning',
beforeClose: (action, instance, done) => {
if(action === "confirm") {
instance.confirmButtonLoading = true;
CategoryDel({categoryId: data.parent_category_data.data.id}).then(response => {
// 成功提示
proxy.$message({
message: response.message,
type: "success"
})
instance.confirmButtonLoading = false;
done();
// 删除交互
categoryTree.value.remove(data.parent_category_data);
}).catch(error => {
instance.confirmButtonLoading = false;
done();
})
}
else{
done();
}
}
})
}
onBeforeMount(() => {
handlerGetCategory();
})
return {
data,
// handleNodeClick,
handlerCategory,
handlerSubmit,
config,
categoryTree
}
}
}
</script>
<style lang="scss" scoped>
.spacing-hr {
border: none; // 设置无边框
border-top: 1px solid #e9e9e9; // 底部1像素实线边框颜色为 e9e9e9
margin:30px 0; // 上下边距为30像素左右为0
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 8px;
}
:deep(.el-tree-node__content) {
height: auto;
button {
padding: 8px 12px;
margin: 8px 3px;
font-size: 12px;
height: auto;
}
}
.column {
height: 44px;
padding: 0 20px;
margin-bottom: 30px;
line-height: 44px;
border-radius: 6px;
background-color: #f3f3f3;
}
</style>

View File

@@ -0,0 +1,120 @@
<template>
<BasisForm @callback="handlerSubmitForm" :item="form_config.form_item" :button="form_config.form_button" label-width="120px" :field="form_config.form_data"/>
</template>
<script>
import { reactive, onBeforeMount, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router";
import BasisForm from "@c/form";
import { InfoCreate, GetDetailed, InfoEdit } from "@/api/info";
// 全局数据
import globalData from "@/js/data";
import dayjs from "dayjs";
export default {
name: 'InfoDetailed',
components: { BasisForm },
props: {},
setup(props){
// 获取实例上下文
const { proxy } = getCurrentInstance();
// router
const { go } = useRouter();
const { query } = useRoute();
const data = reactive({
row_id: query.id,
})
const form_config = reactive({
form_item: [
{
type: "cascader",
label: "信息分类",
prop: "category_id",
props: {
label: "category_name",
value: "id"
},
url: "category",
required: true
},
{
type: "input",
label: "信息标题",
prop: "title",
width: "300px",
placeholder: "请输入标题",
max_length: 50, // 最大输入长度
min_length: 1, // 最小输入长度
required: true,
message: "请务必填写标题"
},
{ type: "upload", label: "缩略图", prop: "image_url" },
{ type: "date", label: "发布日期", prop: "create_date" },
{
type: "radio",
label: "是否发布",
prop: "status",
options: globalData.whether,
required: true
},
{ type: "wangeditor", label: "内容描述", prop: "content" }
],
form_data: {
image_url: "",
category_id: "",
title: "",
create_date: "",
content: "",
status: "1",
},
form_button: [
{ label: "提交", type: "danger", key: "submit" },
// { label: "重置", type: "primary", key: "reset" },
// { label: "关闭", type: "primary", key: "close", callback: () => handlerClose() },
]
})
onBeforeMount(() => {
// 获取详情
data.row_id && handlerGetDetailed();
})
const handlerSubmitForm = (formName) => {
data.row_id ? handlerEditInfo() : handlerAddInfo()
}
// 新增信息
const handlerAddInfo = () => {
// 深度拷贝
const request_data = JSON.parse(JSON.stringify(form_config.form_data));
// 日期处理
request_data.create_date = dayjs(request_data.create_date).format("YYYY-MM-DD HH:mm:ss");
InfoCreate(request_data).then(response => {
// 弹窗提示
proxy.$message.success(response.message);
// 重置表单
go(-1);
})
}
// 编辑信息
const handlerEditInfo = () => {
console.log(22222)
// 深度拷贝
const request_data = JSON.parse(JSON.stringify(form_config.form_data));
InfoEdit(request_data).then(response => {
// 弹窗提示
proxy.$message.success(response.message);
// 重置表单
go(-1);
})
}
// 获取详情
const handlerGetDetailed = () => {
GetDetailed({id:data.row_id}).then(response => {
form_config.form_data = response.data
})
}
return {
handlerSubmitForm,
form_config,
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,169 @@
<template>
<BasisTable :search="false" :columns="table_config.table_header" :config="table_config.config" :request="table_config.request">
<template v-slot:operation="slotData">
<el-button type="danger" @click="handlerDetailed(slotData.data.id)" v-has-button="'init:edit'">编辑</el-button>
</template>
</BasisTable>
</template>
<script>
import { useRouter } from "vue-router";
import{ reactive, provide } from "vue";
import { getDate } from "@/utils/common";
import { categoryHook } from "@/hook/infoHook";
// components
import BasisTable from "@c/table";
// 全局数据`
import globalData from "@/js/data";
export default {
name: 'InfoIndex',
components: { BasisTable },
props: {},
setup(props){
const search_config = reactive({
label_width: "100px",
form_button_group: [
{ label: "新增", type: "danger", callback: () => addInfo() },
{ label: "其他按钮", callback: () => {} }
],
form_button: {
reset_button: true
},
form_item: [
{
type: "cascader",
label: "类别",
prop: "category_id",
props: {
label: "category_name",
value: "id"
},
url: "category",
label_width: 80,
col: 6
},
{
type: "select",
label: "发布状态",
prop: "status",
options: globalData.whether,
col: 4
},
{
type: "keyword",
label: "关键字",
prop: "keyword",
options: [
{ label: "ID", value: "id" },
{ label: "标题", value: "title" }
],
col: 8
},
],
button_col: 6,
form_data: {
category_id: "",
status: ""
}
})
provide("search_config", search_config);
// router
const { push } = useRouter();
// hook
const { infoData: category_data, handlerGetCategory: getList } = categoryHook();
const data = reactive({
category: 0,
keyword_options: [
{ label: "ID", value: "id" },
{ label: "标题", value: "title" }
],
});
const request_data = reactive({
pageNumber: 1,
pageSize: 10,
category_id: [],
key: "",
keyword: ""
})
const table_config = reactive({
table_header: [
{ label: "标题", prop: "title", width: "500" },
{
label: "类别",
prop: "category_name",
width: "200",
type: "function",
callback: (row) => {
return `<a href="http://www.web-jshtml.cn" title="手把手撸码前端">${row.category_name}</a>`;
}
},
{
label: "日期",
prop: "createDate",
type: "function",
callback: (row) => {
return getDate({ value: row.createDate * 1000 });
}
},
{
label: "发布状态",
prop: "status",
type: "switch",
key_id: "id",
api_module: "info",
api_key: "info_status",
options: globalData.whether
},
{
label: "操作",
type: "slot",
slot_name: "operation",
width: "200",
delete_elem: true
}
],
config: {},
request: {
url: "info",
data: {
pageNumber: 1,
pageSize: 10,
},
delete_key: "id"
}
})
// 详情页
const handlerDetailed = (id) => {
push({
path: "/newsDetailed",
query: { id }
})
}
const addInfo = () => {
push({
path: "/newsDetailed"
})
}
const handlerOnload = (data) => {
console.log(data)
}
return {
data,
category_data,
request_data,
table_config,
handlerDetailed,
handlerOnload,
addInfo
}
}
}
</script>
<style lang="scss" scoped>
.width-160 { width: 160px; }
.width-100 { width: 100px; }
.width-180 { width: 180px; }
</style>

View File

@@ -0,0 +1,324 @@
<template>
<BasisTable
:columns="table_config.table_header"
:config="table_config.config"
:request="table_config.request"
>
<template v-slot:operation="slotData">
<el-button type="danger" @click="handlerMenu('edit', slotData.data.menu_id)" v-has-button="'menu:edit'">编辑</el-button>
<el-button type="danger" @click="handlerMenu('add_sub', slotData.data.menu_id)" v-has-button="'menu:add_sub'">添加子菜单</el-button>
</template>
</BasisTable>
<el-dialog :title="data.title" @closed="dislogClose" @open="dialogOpen" v-model="dialogVisible" width="30%" :close-on-click-modal="false" :close-on-press-escape="false">
<BasisForm
ref="basisFormRef"
label-width="100px"
:item="form_config.form_item"
:button="form_config.form_button"
:field="form_config.form_data"
:loading="form_config.form_loading"
@callback="handlerSubmit"
>
<template v-slot:menu_function>
<el-row :gutter="10">
<el-col :span="9">页面元素</el-col>
<el-col :span="9">标识符</el-col>
<el-col :span="4">操作</el-col>
</el-row>
<el-row :gutter="10" v-for="(item, index) in form_config.page_item" :key="item.id">
<el-col :span="9"><el-input v-model.trim="item.label" size="small" /></el-col>
<el-col :span="9"><el-input v-model.trim="item.value" size="small" /></el-col>
<el-col :span="4"><el-button size="small" @click="handlerDel(index)">删除</el-button></el-col>
</el-row>
<el-button type="primary" @click="handlerPush">添加功能</el-button>
</template>
</BasisForm>
</el-dialog>
</template>
<script>
import { useRouter } from "vue-router";
import{ reactive, provide, ref } from "vue";
// store
import { useStore } from "vuex";
// components
import BasisTable from "@c/table";
import BasisForm from "@c/form";
// 全局数据
import globalData from "@/js/data";
// API
import { MenuCreate, MenuDetailed, MenuUpdate } from "@/api/menu";
// utils
import { formatRequestData, formatTree } from "@/utils/format";
export default {
name: 'MenuIndex',
components: { BasisTable, BasisForm },
props: {},
setup(props){
const dialogVisible = ref(false);
// router
const { push } = useRouter();
// store
const store = useStore();
// 页面功能初始参数
const page_fun_json = { value: "", label: "" };
const data = reactive({
menu_handler_flag: "",
row_id: 0,
title: "",
title_item: {
add: "添加一级菜单",
edit: "编辑菜单",
add_sub: "添加子级菜单"
}
})
// 列表表格配置
const table_config = reactive({
table_header: [
{ label: "菜单名称", prop: "menu_name" },
{ label: "菜单路径", prop: "menu_path" },
{ label: "映射组件", prop: "menu_component" },
{ label: "重定向", prop: "menu_redirect" },
{
label: "是否隐藏",
prop: "menu_hidden",
type: "switch",
key_id: "menu_id",
api_module: "menu",
api_key: "hidden_status",
},
{
label: "是否禁用",
prop: "menu_disabled",
type: "switch",
key_id: "menu_id",
api_module: "menu",
api_key: "disabled_status",
},
{ label: "操作", type: "slot", slot_name: "operation", width: "280", delete_elem: true }
],
config: {
selection: false,
batch_delete: false,
pagination: false,
action_request: true,
row_key: "menu_id"
},
request: {
url: "menu",
data: {},
delete_key: "menu_id",
format_data: (data) => formatTree(data, "menu_id", "parent_id", "children", 0)
}
})
const search_config = reactive({
label_width: "70px",
form_button_group: [
{ label: "新增一级菜单", type: "danger", callback: () => handlerMenu('add') },
],
form_button: {
reset_button: true
},
form_item: [
{
type: "select",
label: "禁启用",
prop: "menu_disabled",
width: "100px",
options: globalData.whether
},
{
type: "keyword",
label: "关键字",
prop: "keyword",
options: [
{ label: "菜单名称", value: "menu_name" },
{ label: "菜单路径", value: "menu_path" },
{ label: "组件名称", value: "menu_component" }
]
},
],
form_data: {
menu_disabled: ""
}
})
provide("search_config", search_config);
const form_config = reactive({
form_item: [
{
type: "input",
label: "菜单名称",
prop: "menu_name",
width: "300px",
required: true
},
{
type: "input",
label: "菜单路径",
prop: "menu_path",
width: "300px",
required: true
},
{
type: "input",
label: "路由名称",
prop: "menu_router",
width: "300px",
required: true
},
{
type: "input",
label: "映射组件",
prop: "menu_component",
width: "300px",
required: true
},
{ type: "upload", label: "图标", prop: "menu_icon" },
{ type: "inputNumber", label: "排序", prop: "menu_sort", required: true },
{
type: "radio",
label: "是否禁用",
prop: "menu_disabled",
options: globalData.whether
},
{
type: "radio",
label: "是否隐藏",
prop: "menu_hidden",
options: globalData.whether
},
{
type: "radio",
label: "是否缓存",
prop: "menu_keep",
options: globalData.whether
},
{
type: "input",
label: "重定向",
prop: "menu_redirect",
width: "300px"
},
{
type: "slot",
label: "页面功能",
slot_name: "menu_function"
}
],
form_button: [
{ label: "确认提交", type: "danger", key: "submit" }
],
form_data: {
menu_name: "",
menu_path: "",
menu_router: "",
menu_component: "",
menu_sort: 0,
menu_disabled: "2",
menu_hidden: "2",
menu_keep: "2",
menu_redirect: "",
menu_icon: ""
},
form_loading: false,
page_item: [JSON.parse(JSON.stringify(page_fun_json))]
})
const handlerSubmit = (value) => {
if(data.menu_handler_flag === "edit" && data.row_id) {
handlerMenuEdit();
}
if(data.menu_handler_flag === "add" || data.menu_handler_flag === "add_sub") {
handlerMenuCreate();
}
}
const basisFormRef = ref(null);
const dislogClose = () => {
form_config.page_item = [JSON.parse(JSON.stringify(page_fun_json))];
data.row_id = "";
data.menu_handler_flag = "";
basisFormRef.value && basisFormRef.value.handlerFormReset();
dialogVisible.value = false;
}
const dialogOpen = () => {
if(data.menu_handler_flag === "edit" && data.row_id) {
handlerMenuDetailed();
}
}
const handlerPush = () => {
form_config.page_item.push(JSON.parse(JSON.stringify(page_fun_json)));
}
const handlerDel = (index) => {
form_config.page_item.splice(index, 1);
}
const formatPageItem = () => {
const data = Object.assign([], form_config.page_item);
const dataItem = data.filter(item => item.label && item.value);
return JSON.stringify(dataItem);
}
const handlerMenu = (type, id = "") => {
data.menu_handler_flag = type;
data.row_id = id;
dialogVisible.value = true;
// 更新标题
data.title = data.title_item[type];
}
const handlerMenuDetailed = () => {
form_config.form_loading = true;
MenuDetailed({menu_id: data.row_id}).then(response => {
form_config.form_loading = false;
// form表单赋值
form_config.form_data = formatRequestData(response.data, form_config.form_data);
// 页面功能选值还原
const pageItemInit = response.data.menu_fun;
pageItemInit && (form_config.page_item = JSON.parse(pageItemInit));
}).catch(error => {
form_config.form_loading = false;
})
}
const handlerMenuEdit = () => {
form_config.form_loading = true;
MenuUpdate({
...form_config.form_data,
menu_fun: formatPageItem(),
menu_id: data.row_id
}).then(response => {
form_config.form_loading = false;
dislogClose();
store.commit("app/SET_TABLE_REQUEST");
}).catch(error => {
form_config.form_loading = false;
})
}
const handlerMenuCreate = () => {
form_config.form_loading = true;
const request_data = {
...form_config.form_data,
menu_fun: formatPageItem()
}
if(data.menu_handler_flag === "add_sub") { request_data.parent_id = data.row_id; }
MenuCreate(request_data).then(response => {
form_config.form_loading = false;
dislogClose();
store.commit("app/SET_TABLE_REQUEST");
}).catch(error => {
form_config.form_loading = false;
})
}
return {
table_config,
dialogVisible,
form_config,
basisFormRef,
handlerSubmit,
dislogClose,
dialogOpen,
handlerDel,
handlerPush,
handlerMenu,
data
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,100 @@
<template>
<BasisTable :columns="table_config.table_header" :config="table_config.config" :request="table_config.request">
<template v-slot:operation="slotData">
<el-button type="danger" @click="handlerRole(slotData.data.role_id)">编辑</el-button>
</template>
</BasisTable>
<DialogRole v-model:flag="data.dialogFlag" v-model:row-id="data.row_id" />
</template>
<script>
import{ reactive, provide } from "vue";
// components
import BasisTable from "@c/table";
import DialogRole from "./components/dialogRole";
// 全局数据
import globalData from "@/js/data";
export default {
name: 'InfoIndex',
components: { BasisTable, DialogRole },
props: {},
setup(props){
const data = reactive({
dialogFlag: false,
row_id: ""
})
const table_config = reactive({
table_header: [
{ label: "角色名称", prop: "role_name" },
{
label: "是否禁用",
prop: "role_disabled",
type: "switch",
key_id: "role_id",
api_module: "role",
api_key: "status"
},
{
label: "操作",
type: "slot",
slot_name: "operation",
width: "200",
delete_elem: true
}
],
config: {
action_request: true,
has_button_delete: "role:delete",
has_button_batch_delete: "role:batch_delete"
},
request: {
url: "role",
data: {
pageNumber: 1,
pageSize: 10,
},
delete_key: "role_id"
}
})
const search_config = reactive({
label_width: "80px",
form_button_group: [
{ label: "添加角色", type: "danger", callback: () => handlerRole() },
],
form_button: {
reset_button: true
},
form_item: [
{
type: "input",
label: "角色名称",
prop: "role_name",
placeholder: "请输入角色名称"
},
{
type: "select",
label: "禁用状态",
prop: "role_disabled",
width: "100px",
options: globalData.whether
},
],
form_data: {
role_name: "",
role_disabled: ""
}
})
provide("search_config", search_config);
const handlerRole = (id = "") => {
data.row_id = id;
data.dialogFlag = true;
}
return {
table_config,
data,
handlerRole
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,115 @@
<template>
<BasisTable
:columns="table_config.table_header"
:config="table_config.config"
:request="table_config.request"
>
<template v-slot:operation="slotData">
<el-button type="danger" @click="handlerDialog(slotData.data.id)" v-has-button="'user:edit'">编辑</el-button>
<el-button type="danger" @click="handlerPassword(slotData.data.id)" v-has-button="'user:password'">修改密码</el-button>
</template>
</BasisTable>
<DialogUser v-model:flag="dialogFlag" v-model:row-id="row_id" />
<DialogPass v-model:flag="dialogPassFlag" v-model:row-id="row_id" title="修改密码" />
</template>
<script>
import { reactive, provide, toRefs } from "vue";
// components
import BasisTable from "@c/table";
import DialogUser from "./components/dialogUser";
import DialogPass from "./components/dialogPassword";
// 全局数据
import globalData from "@/js/data";
export default {
name: "SystemUser",
components: { BasisTable, DialogUser, DialogPass },
props: {},
setup(props){
const data = reactive({
dialogFlag: false,
dialogPassFlag: false,
row_id: ""
})
// 列表表格配置
const table_config = reactive({
table_header: [
{ label: "用户名", prop: "username" },
{ label: "真实姓名", prop: "truename" },
{ label: "角色类型", prop: "role_type" },
{
label: "帐号状态",
prop: "user_disabled",
type: "switch",
key_id: "id",
api_module: "user",
api_key: "status"
},
{ label: "创建时间", prop: "user_createtime" },
{ label: "操作", type: "slot", slot_name: "operation", width: "280", delete_elem: true }
],
config: {
action_request: true,
has_button_delete: "user:delete",
has_button_batch_delete: "user:batch_delete"
},
request: {
url: "user",
data: {
pageSize: 10,
pageNumber: 1
},
delete_key: "id"
}
})
// 搜索项配置
const search_config = reactive({
label_width: "70px",
form_button_group: [
{ label: "添加用户", type: "danger", callback: () => handlerDialog() },
],
form_button: {
reset_button: true
},
form_item: [
{
type: "select",
label: "禁启用",
prop: "user_disabled",
width: "100px",
options: globalData.whether
},
{
type: "keyword",
label: "关键字",
prop: "keyword",
options: [
{ label: "用户名", value: "username" },
{ label: "真实姓名", value: "truename" },
{ label: "角色类型", value: "role_type" }
]
},
],
form_data: {
user_disabled: ""
}
})
provide("search_config", search_config);
const handlerDialog = (id = '') => {
data.row_id = id;
data.dialogFlag = true;
}
const handlerPassword = (id) => {
data.row_id = id;
data.dialogPassFlag = true;
}
return {
table_config,
handlerDialog,
handlerPassword,
...toRefs(data)
}
}
}
</script>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,95 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="title"
:width="width"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="dialogClose"
@open="dialogOpen"
>
<BasisForm @callback="handlerSubmit" ref="basisFormRef" label-width="100px" :item="form_config.form_item" :button="form_config.form_button" :field="form_config.form_data" :loading="form_config.form_loading">
</BasisForm>
</el-dialog>
</template>
<script setup>
import { ref, watch, reactive, getCurrentInstance, defineProps, defineEmits } from "vue";
// components
import BasisForm from "@c/form";
// validate
import { checkPassword } from "@/utils/validate";
// hook
import { propsType, dialogHook } from "@/hook/dialogHook.js";
// sha1
import sha1 from "js-sha1";
// API
import { UpdatePass } from "@/api/user";
// store
import { useStore } from "vuex";
// Props对象
const props = defineProps({
...propsType,
rowId: {
type: [String, Number],
default: ""
}
})
const emit = defineEmits(["update:flag"])
// 变量
const dialogVisible = ref(props.flag);
const width = ref(props.width);
const title = ref(props.title);
const basisFormRef = ref(null);
// 获取实例上下文
const { proxy } = getCurrentInstance();
// dialog
const { close } = dialogHook(emit);
// store
const store = useStore();
// form表单配置
const form_config = reactive({
form_item: [
{
type: "input",
label: "密码",
prop: "password",
width: "300px",
value_type: "password",
required: true
}
],
form_button: [
{ label: "确认修改", type: "danger", key: "submit" }
],
form_data: {
password: "",
},
form_loading: false
})
const dialogClose = () => {
dialogVisible.value = false;
close(basisFormRef);
}
const dialogOpen = () => {}
watch(() => props.flag, (newValue, oldValue) => {
dialogVisible.value = newValue;
})
/** 表单提交 */
const handlerSubmit = () => {
if(!props.rowId) { return false; } // 不存在ID
form_config.form_loading = true; // 添加表单遮罩
UpdatePass({
password: sha1(form_config.form_data.password),
id: props.rowId
}).then(response => {
form_config.form_loading = false; // 清除表单遮罩
proxy.$message.success(response.message); // 成功弹窗提示
dialogClose(); // 关闭弹窗
}).catch(error => {
form_config.form_loading = false; // 清除表单遮罩
})
}
</script>
<style lang='scss' scoped></style>

View File

@@ -0,0 +1,204 @@
<template>
<el-dialog v-model="dialogVisible" :title="title" :width="width" :close-on-click-modal="false" :close-on-press-escape="false" @close="dialogClose" @open="dialogOpen">
<BasisForm ref="basisFormRef" label-width="100px"
:item="form_config.form_item"
:button="form_config.form_button"
:field="form_config.form_data"
:loading="form_config.form_loading"
@callback="handlerSubmit">
<template v-slot:permit>
<el-tree
ref="treeRef"
:data="datas.tree_data"
node-key="menu_id"
:props="{label: 'menu_name', class: customNodeClass}"
:expand-on-click-node="false"
show-checkbox
default-expand-all
/>
</template>
</BasisForm>
</el-dialog>
</template>
<script setup>
import { ref, reactive, defineProps, watch, defineEmits, nextTick } from "vue";
// store
import { useStore } from "vuex";
// components
import BasisForm from "@c/form";
// 全局数据
import globalData from "@/js/data";
// API
import { RoleCreate, RoleDetailed, RoleUpdate } from "@/api/role";
import { MenuListTree } from "@/api/menu";
// utils
import { formatRequestData } from "@/utils/format";
const store = useStore();
// props对象
const props = defineProps({
flag: {
type: Boolean,
default: false
},
width: {
type: String,
default: "30%"
},
title: {
type: String,
default: "消息"
},
rowId: {
type: [String, Number],
default: ""
}
})
// 变量
const dialogVisible = ref(props.flag);
const width = ref(props.width);
const title = ref(props.title);
const datas = reactive({
tree_data: []
})
const basisFormRef = ref(null);
const treeRef = ref(null);
// emit对象
const emit = defineEmits(["update:flag", "update:rowId"])
// 角色form表单配置
const form_config = reactive({
form_item: [
{ type: "input", label: "角色名称", prop: "role_name", required: true },
{ type: "input", label: "角色标识", prop: "role_value", required: true },
{
type: "radio",
label: "是否超管",
prop: "has_admin",
options: globalData.whether,
relation_hidden: [
['role_name', {"1":true, "0": false}],
['role_value', {"1":true, "0": false}]
]
},
{ type: "radio", label: "是否启用", prop: "role_disabled", options: globalData.whether },
{ type: "slot", label: "角色权限", prop: "role_permit", slot_name: "permit" }
],
form_button: [
{ label: "确认提交", type: "danger", key: "submit" }
],
form_data: { role_name: "", role_value: "", role_disabled: "1", has_admin: "0" },
form_loading: false,
form_hidden: {}
})
// 函数
const dialogOpen = async () => {
try {
await getMenuList();
}catch {
console.log("权限数据请求失败")
}
props.rowId && getDetailed();
title.value = props.rowId ? "编辑角色" : "添加角色";
}
const handlerSubmit = () => {
props.rowId ? handlerEdit() : handlerAdd();
}
/** 角色新增函数接口 */
const handlerAdd = () => {
const request_data = formatRequest();
form_config.form_loading = true;
RoleCreate(request_data).then(response => {
form_config.form_loading = false;
store.commit("app/SET_TABLE_REQUEST");
dialogClose();
}).catch(error => {
form_config.form_loading = false;
})
}
/** 角色编辑函数接口 */
const handlerEdit = () => {
const request_data = formatRequest();
form_config.form_loading = true;
RoleUpdate(request_data).then(response => {
form_config.form_loading = false;
store.commit("app/SET_TABLE_REQUEST");
dialogClose();
}).catch(error => {
form_config.form_loading = false;
})
}
/** 接口参数格式化 */
const formatRequest = () => {
const id = treeRef.value.getCheckedKeys().concat(treeRef.value.getHalfCheckedKeys());
const request_data = {
...form_config.form_data,
menu_id: id,
}
// 编辑状态
if(props.rowId) { request_data.role_id = props.rowId; }
return request_data;
}
const dialogClose = () => {
basisFormRef.value.handlerFormReset();
treeRef.value.setCheckedKeys([]);
dialogVisible.value = false;
emit("update:flag", false);
}
const getMenuList = () => {
if(datas.tree_data.length !== 0) { return false; }
return new Promise((resolve, reject) => {
MenuListTree().then(response => {
resolve()
datas.tree_data = response.data.data;
})
})
}
const getDetailed= () => {
form_config.form_loading = true;
RoleDetailed({role_id: props.rowId}).then(response => {
// 响应报文数据
const response_data = response.data;
// 表单数据赋值
form_config.form_data = formatRequestData(response_data, form_config.form_data);
// 菜单复选框赋值
nextTick(() => {
const menu_id = response_data.menu_id || [];
menu_id.length > 0 && menu_id.forEach(item => {
// 获取node节点
const node = treeRef.value.getNode(item);
// 判断node是否为子节点非半选状态
node.isLeaf && treeRef.value.setChecked(node, true)
});
})
form_config.form_loading = false;
}).catch(error => {
form_config.form_loading = false;
})
}
const customNodeClass = (data, node) => {
return `tree-level-${node.level}`
}
// 监听
watch(() => props.flag, (newValue, oldValue) => {
dialogVisible.value = newValue;
})
</script>
<style lang='scss' scoped>
:deep(.tree-level-2) {
margin-bottom: 8px;
> .el-tree-node__children {
display: flex;
flex-wrap: wrap;
}
}
:deep(.tree-level-3) {
width: 33.33333%;
}
</style>

View File

@@ -0,0 +1,193 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="title"
:width="width"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="dialogClose"
@open="dialogOpen"
>
<BasisForm ref="basisFormRef" @callback="handlerSubmit" label-width="100px" :item="form_config.form_item" :button="form_config.form_button" :field="form_config.form_data" :loading="form_config.form_loading" :hidden="form_config.form_hidden" />
</el-dialog>
</template>
<script setup>
import { ref, reactive, watch, defineProps, defineEmits, getCurrentInstance } from "vue";
// API
import { RoleListAll } from "@/api/role";
// components
import BasisForm from "@c/form";
// 全局数据
import globalData from "@/js/data";
// 验证
import { validate_email, validate_password } from "@/utils/validate";
// hook
import { propsType, dialogHook } from "@/hook/dialogHook.js";
// API
import { UserCreate, UserDetailed, UserUpdate } from "@/api/user";
// sha1
import sha1 from "js-sha1";
// vuex
import { useStore } from "vuex";
// store
const store = useStore();
// props 对象
const props = defineProps({
...propsType,
rowId: {
type: [String, Number],
default: ""
}
})
// emit 对象
const emit = defineEmits(["update:flag", "update:rowId"])
// dialoghook
const { close } = dialogHook(emit);
// 获取实例上下文
const { proxy } = getCurrentInstance();
// 变量
const dialogVisible = ref(props.flag);
const width = ref(props.width);
const title = ref(props.title);
const basisFormRef = ref(null);
const form_config = reactive({
form_item: [
{
type: "input",
value_type: "username",
label: "用户名",
prop: "username",
width: "300px",
required: true
},
{ type: "input", label: "真实姓名", prop: "truename" },
{
type: "input",
value_type: "password",
label: "密码",
prop: "password",
width: "300px",
required: true
},
{ type: "radio", label: "是否启用", prop: "user_disabled", options: globalData.whether, required: true },
{
type: "radio",
label: "角色类型",
prop: "role_type",
required: true,
key_label: "role_name",
key_value: "role_id",
callback: async (row) => {
let result = []
try {
result = await getRoleList();
} catch (error) {
console.log("角色数据获取失败")
}
row.options = result
}
}
],
form_button: [
{ label: "确认提交", type: "danger", key: "submit" }
],
form_data: { username: "", password: "", truename: "", role_type: "", user_disabled: "1" },
form_loading: false,
form_hidden: {}
})
/** dialog关闭 */
const dialogClose = () => {
close(basisFormRef);
emit("update:rowId", "");
}
/** dialog打开 */
const dialogOpen = async () => {
form_config.form_hidden.password = !!props.rowId;
props.rowId && getUserDetailed();
}
/** 监听 */
watch(() => props.flag, (newValue, oldValue) => {
dialogVisible.value = newValue;
})
// 获取角色列表
const getRoleList = () => {
return new Promise((resolve, reject) => {
RoleListAll().then(response => {
resolve(response.data)
})
})
}
/** 表单提交 */
const handlerSubmit = () => {
props.rowId ? handlerEdit() : handlerAdd();
}
const handlerAdd= () => {
// 表单加载遮罩
form_config.form_loading = true;
// 拷贝数据
const request_data = Object.assign({}, form_config.form_data);
// 密码加密
request_data.password = sha1(request_data.password);
// 调用创建用户接口
UserCreate(request_data).then(response => {
userResponse(response);
}).catch(error => {
// 清除表单遮罩
form_config.form_loading = false;
})
}
/** 修改用户 */
const handlerEdit = () => {
// 表单加载遮罩
form_config.form_loading = true;
// 拷贝数据
const request_data = Object.assign({}, form_config.form_data);
// 删除密码参数
delete request_data.password;
// 调用修改用户接口
UserUpdate({...request_data, id: props.rowId}).then(response => {
userResponse(response);
}).catch(error => {
// 清除表单遮罩
form_config.form_loading = false;
})
}
/** 获取用户详情 */
const getUserDetailed = () => {
form_config.form_loading = true; // 表单加载遮罩
UserDetailed({id: props.rowId}).then(response => {
form_config.form_loading = false; // 清除表单遮罩
form_config.form_data = response.data; // 表单赋值
}).catch(error => {
form_config.form_loading = false; // 清除表单遮罩
})
}
/** 接口响应结果 */
const userResponse = (params) => {
// 清除表单遮罩
form_config.form_loading = false;
// 获取报文
const response_data = params;
// 判断状态
if(!response_data.data.user) {
// 失败弹窗提示
proxy.$message.error(response_data.message);
return false;
}
// 成功弹窗提示
proxy.$message.success(response_data.message);
// 刷新列表
store.commit("app/SET_TABLE_REQUEST");
// 关闭弹窗
dialogClose();
}
</script>
<style lang='scss' scoped></style>

View File

@@ -0,0 +1,17 @@
<template>
<div class="">用户列表</div>
</template>
<script>
export default {
name: 'NewsIndex',
components: {},
props: {},
setup(props){
return {}
}
}
</script>
<style lang="scss" scoped>
</style>