Commit f4a77a56 authored by 李鹏 's avatar 李鹏

admin interface

parent 50614499
...@@ -12,7 +12,7 @@ module.exports = { ...@@ -12,7 +12,7 @@ module.exports = {
htmlWhitespaceSensitivity: "css", htmlWhitespaceSensitivity: "css",
insertPragma: false, insertPragma: false,
jsxSingleQuote: false, jsxSingleQuote: false,
printWidth: 120, // 如果属性过多需要换行,减少该值 printWidth: 100, // 如果属性过多需要换行,减少该值
proseWrap: "preserve", proseWrap: "preserve",
quoteProps: "as-needed", quoteProps: "as-needed",
requirePragma: false, requirePragma: false,
......
...@@ -1573,7 +1573,7 @@ border-radius:8px; ...@@ -1573,7 +1573,7 @@ border-radius:8px;
} }
.forget_psd { .forget_psd {
font-size: 14px; font-size: 14px;
color: #3759be; color: #3759be;
cursor: pointer; cursor: pointer;
} }
......
...@@ -50,9 +50,17 @@ ...@@ -50,9 +50,17 @@
</template> </template>
<script setup> <script setup>
import { watch, ref } from "vue"; import { watch, ref, nextTick } from "vue";
import { selectTableMixin } from "./hook/mixin-select-table"; import { selectTableMixin } from "./hook/mixin-select-table";
let { nowSelectData, allSelectData, selectData, initSelectTableData, runPage, dealSelectData } = selectTableMixin(); const {
nowSelectData,
allSelectData,
initAllSelectData,
selectData,
initSelectTableData,
runPage,
dealSelectData,
} = selectTableMixin();
const props = defineProps({ const props = defineProps({
height: { height: {
...@@ -71,9 +79,6 @@ const props = defineProps({ ...@@ -71,9 +79,6 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
// selectable: {
// type: Function,
// },
isIndex: { isIndex: {
type: Boolean, type: Boolean,
default: false, default: false,
...@@ -95,14 +100,30 @@ const props = defineProps({ ...@@ -95,14 +100,30 @@ const props = defineProps({
default: false, default: false,
}, // 多选框是否禁用 }, // 多选框是否禁用
canEditFlag: { canEditFlag: {
typr: Boolean, type: String,
default: "", default: "",
}, // 决定多选框是否禁用的字段 }, // 决定多选框是否禁用的字段
//初始表格选中数据
originSelectedData: {
type: Array,
default: () => [],
},
}); });
const table = ref(null); const table = ref(null);
const emit = defineEmits(["selectAc", "select"]); const emit = defineEmits(["selectAc", "select"]);
watch(
() => props.originSelectedData,
(val) => {
if (val.length) {
initAllSelectData(props.originSelectedData);
}
},
{
immediate: true,
}
);
watch( watch(
() => props.rows, () => props.rows,
(n, o) => { (n, o) => {
...@@ -116,6 +137,9 @@ watch( ...@@ -116,6 +137,9 @@ watch(
} }
}); });
} }
},
{
immediate: true,
} }
); );
...@@ -123,14 +147,19 @@ const toggleRowSelection = (row, flag = true) => { ...@@ -123,14 +147,19 @@ const toggleRowSelection = (row, flag = true) => {
table.value.toggleRowSelection(row, flag); table.value.toggleRowSelection(row, flag);
}; };
const selectAction = (selection) => { const selectAction = (selection) => {
emit("selectAc", { allLength: Object.keys(allSelectData).length + nowSelectData.length, selection }); nextTick(() => {
emit("selectAc", {
allLength: Object.keys(allSelectData.value).length + nowSelectData.value.length,
selection,
});
});
}; };
const clearSelection = () => { const clearSelection = () => {
table.value.clearSelection(); table.value.clearSelection();
emit("select", { allLength: Object.keys(allSelectData).length + nowSelectData.length, selection: [] }); emit("select", {
}; allLength: Object.keys(allSelectData.value).length + nowSelectData.value.length,
const setSelectedRow = (row) => { selection: [],
toggleRowSelection(row); });
}; };
const toggleRowArrSelection = (arr, flag = true) => { const toggleRowArrSelection = (arr, flag = true) => {
arr.forEach((e) => { arr.forEach((e) => {
...@@ -139,16 +168,22 @@ const toggleRowArrSelection = (arr, flag = true) => { ...@@ -139,16 +168,22 @@ const toggleRowArrSelection = (arr, flag = true) => {
}; };
const selectActionRow = (selection, row) => { const selectActionRow = (selection, row) => {
selectData(selection); selectData(selection);
emit("select", { allLength: Object.keys(allSelectData).length + nowSelectData.length, selection }); emit("select", {
allLength: Object.keys(allSelectData.value).length + nowSelectData.value.length,
selection,
});
}; };
const selectActionAll = (selection) => { const selectActionAll = (selection) => {
selectData(selection); selectData(selection);
emit("select", { allLength: Object.keys(allSelectData).length + nowSelectData.length, selection }); emit("select", {
allLength: Object.keys(allSelectData.value).length + nowSelectData.value.length,
selection,
});
}; };
const clearTable = () => { const clearTable = () => {
//清除选中数据,在页面状态更新时使用 //清除选中数据,在页面状态更新时使用
allSelectData = {}; allSelectData.value = {};
nowSelectData = []; nowSelectData.value = [];
clearSelection(); clearSelection();
}; };
const tableRowClassName = ({ row, rowIndex }) => { const tableRowClassName = ({ row, rowIndex }) => {
...@@ -172,5 +207,6 @@ const selectable = (row, index) => { ...@@ -172,5 +207,6 @@ const selectable = (row, index) => {
defineExpose({ defineExpose({
clearTable, clearTable,
toggleRowSelection, toggleRowSelection,
dealSelectData,
}); });
</script> </script>
import { reactive, toRefs,useAttrs } from 'vue' import { reactive, toRefs, useAttrs } from "vue";
export function selectTableMixin(){ export function selectTableMixin() {
const state = reactive({ const state = reactive({
nowSelectData:[], nowSelectData: [],
allSelectData:{} allSelectData: {},
}) });
const attrs = useAttrs()
// const nowSelectData = reactive([])
// const allSelectData = reactive({})
const selectData = (val)=>{ const attrs = useAttrs();
console.log(val); // const nowSelectData = reactive([])
state.nowSelectData = val // const allSelectData = reactive({})
console.log('allSelectData');
console.log(state.allSelectData);
console.log(Object.keys(state.allSelectData).length);
}
const initSelectTableData = (data)=>{ const selectData = (val) => {
return new Promise((reslove,reject)=>{ state.nowSelectData = val;
data.forEach(e => { };
if(state.allSelectData[e[attrs.rowKey||'id']]){ //当某些表格有原始的选中数据时,初始化allSelectData
delete state.allSelectData[e[attrs.rowKey||'id']] const initAllSelectData = (list) => {
state.nowSelectData.push(e) list.forEach((e) => {
} state.allSelectData[e[attrs.rowKey || "id"]] = e;
}); });
};
console.log(state.nowSelectData); const initSelectTableData = (data) => {
reslove(state.nowSelectData) return new Promise((reslove, reject) => {
}) data.forEach((e) => {
} if (state.allSelectData[e[attrs.rowKey || "id"]]) {
delete state.allSelectData[e[attrs.rowKey || "id"]];
const runPage=()=>{//翻页数据推进 state.nowSelectData.push(e);
state.nowSelectData.forEach(e => { }
state.allSelectData[e[attrs.rowKey||'id']] = e });
}); reslove(state.nowSelectData);
state.nowSelectData = [] });
} };
const clearTable=()=>{//清除选中数据,在页面状态更新时使用 const runPage = () => {
state.allSelectData={} //翻页数据推进
state.nowSelectData=[] state.nowSelectData.forEach((e) => {
clearSelection(); state.allSelectData[e[attrs.rowKey || "id"]] = e;
} });
state.nowSelectData = [];
};
const dealSelectData=()=>{//最后提交处理数据 // const clearTable = () => {
state.nowSelectData.forEach(e => { // //清除选中数据,在页面状态更新时使用
state.allSelectData[e[attrs.rowKey||'id']] = e // state.allSelectData = {};
}); // state.nowSelectData = [];
return state.allSelectData // clearSelection();
} // };
const { nowSelectData, allSelectData } = toRefs(state) const dealSelectData = () => {
//最后提交处理数据
const submitData = { ...state.allSelectData };
state.nowSelectData.forEach((e) => {
submitData[e[attrs.rowKey || "id"]] = e;
});
return submitData;
};
return{ const { nowSelectData, allSelectData } = toRefs(state);
nowSelectData,
allSelectData,
selectData,
initSelectTableData,
runPage,
clearTable,
dealSelectData
}
return {
nowSelectData,
allSelectData,
initAllSelectData,
selectData,
initSelectTableData,
runPage,
// clearTable,
dealSelectData,
};
} }
// export const selectTableMixin = { // export const selectTableMixin = {
...@@ -88,7 +91,7 @@ return{ ...@@ -88,7 +91,7 @@ return{
// this.nowSelectData.push(e) // this.nowSelectData.push(e)
// } // }
// }); // });
// console.log(this.nowSelectData); // console.log(this.nowSelectData);
// if(this.nowSelectData.length){ // if(this.nowSelectData.length){
// setTimeout(()=>{ // setTimeout(()=>{
...@@ -115,4 +118,4 @@ return{ ...@@ -115,4 +118,4 @@ return{
// return this.allSelectData // return this.allSelectData
// } // }
// }, // },
// } // }
\ No newline at end of file
<!-- 角色管理 -->
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<div class="form_content apaas_scroll_nor">
<el-form
ref="refForm"
label-position="left"
:model="formData"
:rules="rules"
label-width="82px">
<div class="top_content">
<el-form-item label="规则名称" prop="ruleName">
<el-input placeholder="请输入" maxlength="100" v-model="formData.ruleName"></el-input>
</el-form-item>
<el-form-item label="规则类型" prop="ruleType">
<el-select placeholder="请选择" style="width: 100%" v-model="formData.ruleType">
<el-option label="IP" :value="1"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="规则" prop="ruleDetail">
<el-input
placeholder="请输入"
rows="5"
maxlength="300"
show-word-limit
type="textarea"
v-model="formData.ruleDetail" />
<el-tooltip placement="top-start" effect="light">
<template #content>
<span>输入IP段,不可重复,例如:192.168.0.0/24</span><br />
<span
>输入IP地址,例如192.168.0.1(支持ipv4地址,配置多个IP时使用回车符分隔)</span
>
</template>
<div class="tip-image"></div>
</el-tooltip>
</el-form-item>
<el-form-item class="switch-item" label="是否启用" prop="state" required>
<bg-switch
:labels="['否', '是']"
:values="[0, 1]"
v-model="formData.state"></bg-switch>
</el-form-item>
</div>
<el-form-item class="userScope" label="用户范围" prop="userScope">
<el-button type="primary" @click="userMaintain"> 用户维护 </el-button>
<div class="table_content clearfix">
<bg-table
ref="bgTable"
:headers="detailHeaders"
:rows="tableRows"
height="550"
:stripe="true">
<template v-slot:isAdmin="{ row }">
<span>{{ userTypeConfig[row.isAdmin] }}</span>
</template>
</bg-table>
<bg-pagination
:page="pageConfig.page"
:size="pageConfig.limit"
:total="pageConfig.total"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</el-form-item>
</el-form>
<el-dialog
class="dialog_box_maintain"
title="用户维护"
v-model="dialogMaintain"
width="1062px">
<div class="content_detail">
<div class="form_filter">
<div class="left">
<span class="sleceted_tip"
>已选择<span class="num">{{ selectedNum }}</span
></span
>
<span class="clean" @click="cleanSelected">清空</span>
</div>
<div class="right">
<el-select
placeholder="全部类型"
v-model="dialogFilterData.isAdmin"
style="width: 200px; margin-left: 16px">
<el-option
v-for="option in userTypeList"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
<el-tree-select
style="width: 200px; margin-left: 16px"
placeholder="请选择所属组织"
v-model="dialogFilterData.organizationId"
:data="orgData"
:props="treeProps"
:render-after-expand="false"></el-tree-select>
<el-input
placeholder="请输入关键词"
v-model="dialogFilterData.search"
style="width: 200px; margin: 0 16px 0"
:prefix-icon="Search" />
<el-button type="primary" @click="dialogChangePage(1)">查询</el-button>
<el-button type="default" @click="resetFilter">重置</el-button>
</div>
</div>
<div class="table_content clearfix">
<bg-table
ref="dialogBgTable"
height="430"
select
rowKey="systemId"
:headers="detailHeaders"
:rows="dialogTableRows"
:stripe="true"
@selectAc="selectChange">
<template v-slot:isAdmin="{ row }">
<span>{{ userTypeConfig[row.isAdmin] }}</span>
</template>
</bg-table>
<bg-pagination
:page="dialogPageConfig.page"
:size="dialogPageConfig.limit"
:total="dialogPageConfig.total"
@change-page="dialogChangePage"
@change-size="dialogChangeSize">
</bg-pagination>
</div>
<div class="operate_btns" style="border-top: none">
<el-button @click="dialogMaintain = false"> 取消 </el-button>
<el-button type="primary" @click="save"> 保存 </el-button>
</div>
</div>
</el-dialog>
</div>
<div class="operate_btns">
<el-button type="primary" @click="submit"> 保存 </el-button>
</div>
</div>
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { reactive, toRefs, computed, ref, onBeforeMount, nextTick } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import axios from "../../../../../request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const router = useRouter();
const { getters } = useStore();
const userTypeConfig = computed(() => getters.getUserTypeConfig || {});
const userTypeList = computed(() =>
Object.keys(userTypeConfig.value).map((key) => ({
label: userTypeConfig.value[key],
value: +key,
}))
);
const dialogBgTable = ref(null);
const state = reactive({
//表单数据
formData: {
ruleName: "",
ruleType: "",
ruleDetail: "",
state: 0,
userScope: [],
},
//表单校验规则
rules: {
ruleName: [
{
required: true,
message: "请输入",
trigger: "blur",
},
],
ruleType: [
{
required: true,
message: "请选择",
trigger: "blur",
},
],
ruleDetail: [
{
required: true,
message: "请输入",
trigger: "blur",
},
],
userScope: [
{
required: true,
message: "请选择",
blur: "change",
},
],
},
dialogFilterData: {
isAdmin: "",
organizationId: "",
search: "",
},
pageConfig: {
page: 1,
limit: 10,
total: 0,
},
//弹框中表格分页配置项
dialogPageConfig: {
page: 1,
limit: 10,
total: 0,
},
//表格数据
tableRows: [],
//被选中的所有数据
selectedRows: {},
//弹框中表格数据
dialogTableRows: [],
//已选择数据条数
selectedNum: 0,
detailHeaders: [
{
label: "账号",
prop: "systemAccount",
// minWidth: 280,
},
{
label: "类型",
prop: "isAdmin",
// minWidth: 360,
},
{
label: "用户手机号",
prop: "phone",
// width: 200,
},
{
label: "所属组织",
prop: "name",
// width: 120,
},
],
orgData: [],
treeProps: {
label: "name",
children: "Child",
value: "organization_id",
},
//用户维护弹框
dialogMaintain: false,
});
const {
formData,
rules,
dialogFilterData,
pageConfig,
dialogPageConfig,
tableRows,
dialogTableRows,
selectedNum,
detailHeaders,
orgData,
treeProps,
dialogMaintain,
} = toRefs(state);
onBeforeMount(() => {
getOrgTree();
getTableList();
});
//用户维护
const userMaintain = () => {
state.dialogMaintain = true;
};
//获取所属组织级联数据
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
state.orgData = orgDataTemp;
} else {
ElMessage.error(res.data.data);
}
});
};
const changePage = (page) => {
state.pageConfig.page = page;
state.tableRows = state.selectedRows.slice(
(page - 1) * state.pageConfig.limit,
page * state.pageConfig.limit
);
};
const changeSize = (size) => {
state.pageConfig.limit = size;
changePage(1);
};
const dialogChangePage = (page) => {
state.dialogPageConfig.page = page;
getTableList();
};
const dialogChangeSize = (size) => {
state.dialogPageConfig.limit = size;
dialogChangePage(1);
};
//获取用户维护数据
const getTableList = () => {
const params = {
limit: state.dialogPageConfig.limit,
page: state.dialogPageConfig.page,
disp: 1,
...state.dialogFilterData,
};
axios.get("/apaas/system/v5/accessRule/listRuleUser", { params }).then((res) => {
if (res.data.code == 200) {
state.dialogTableRows = res.data.data || [];
state.dialogPageConfig.total = res.data.total || 0;
} else {
ElMessage.error(res.data.data);
}
});
};
//重置查询参数
const resetFilter = () => {
Object.keys(state.dialogFilterData).forEach((key) => {
state.dialogFilterData[key] = "";
});
dialogChangePage(1);
};
//用户维护弹框中清空
const cleanSelected = () => {
dialogBgTable.value.clearTable();
};
//用户维护选择项发生变化
const selectChange = (params) => {
state.selectedNum = params.allLength;
};
//保存
const save = () => {
state.dialogMaintain = false;
const res = dialogBgTable.value.dealSelectData();
state.selectedRows = Object.values(res);
state.formData.userScope = state.selectedRows.map((item) => ({
systemId: item.systemId,
}));
state.pageConfig.total = state.formData.userScope.length;
changePage(1);
};
//提交
const submit = () => {
axios.post("/apaas/system/v5/accessRule/addAccessRule", state.formData).then((res) => {
if (res.data.code == 200) {
ElMessage.success("添加成功");
router.push("/config/accessRule");
} else {
ElMessage.error(res.data.data);
}
});
};
</script>
<style lang="scss" scoped>
.page_container {
.main_container {
position: relative;
margin: 0 0 16px;
width: 100%;
height: calc(100% - 62px);
padding: 40px 0 70px;
overflow: auto;
background-color: #fff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
.form_content {
overflow: auto;
height: 100%;
padding-left: 40px;
.el-form {
::v-deep .el-form-item {
display: block;
margin-bottom: 24px;
width: 60%;
.el-form-item__label {
display: block;
margin-bottom: 6px;
height: 14px;
line-height: 14px;
}
&.switch-item {
display: flex;
align-items: center;
.el-form-item__label {
display: inline-flex;
margin-bottom: 0px;
}
.el-switch {
height: 24px;
}
}
&.userScope {
width: 100%;
margin-bottom: 16px;
.el-button {
width: 92px;
}
.el-form-item__label {
margin-bottom: 16px;
}
.el-form-item__content {
display: block;
}
.table_content {
padding-right: 40px;
margin-top: 16px;
}
}
}
}
}
::v-deep .dialog_box_maintain {
.el-dialog__body {
padding: 0 0 70px 0;
height: 630px;
}
.form_filter {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
height: 69px;
border-bottom: 1px solid #e6e9ef;
.left {
font-size: 0px;
.sleceted_tip {
margin: 0 24px 0;
vertical-align: middle;
font-size: 14px;
color: #404a62;
.num {
margin: 0 3px 0 3px;
font-weight: 600;
color: #202531;
}
}
.clean {
vertical-align: middle;
font-size: 14px;
color: #3759be;
cursor: pointer;
}
}
.right {
margin-right: 16px;
.el-button {
width: 64px;
&:last-child {
margin-left: 16px;
}
}
}
}
.table_content {
padding: 0 16px;
}
.operate_btns {
.el-button {
width: 64px;
&:first-child {
margin-right: 4px;
}
}
}
}
.operate_btns {
position: absolute;
bottom: 0;
width: 100%;
height: 70px;
text-align: right;
line-height: 68px;
border-top: solid 1px #e6e9ef;
.el-button {
width: 92px;
margin-right: 16px;
}
}
}
}
</style>
<!-- 角色管理 -->
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<div class="form_content apaas_scroll_nor">
<el-form
ref="refForm"
label-position="left"
:model="formData"
:rules="rules"
label-width="82px">
<div class="top_content">
<el-form-item label="规则名称" prop="ruleName">
<el-input placeholder="请输入" maxlength="100" v-model="formData.ruleName"></el-input>
</el-form-item>
<el-form-item label="规则类型" prop="ruleType">
<el-select placeholder="请选择" style="width: 100%" v-model="formData.ruleType">
<el-option label="IP" :value="1"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="规则" prop="ruleDetail">
<el-input
placeholder="请输入"
rows="5"
maxlength="300"
show-word-limit
type="textarea"
v-model="formData.ruleDetail" />
<el-tooltip placement="top-start" effect="light">
<template #content>
<span>输入IP段,不可重复,例如:192.168.0.0/24</span><br />
<span
>输入IP地址,例如192.168.0.1(支持ipv4地址,配置多个IP时使用回车符分隔)</span
>
</template>
<div class="tip-image"></div>
</el-tooltip>
</el-form-item>
<el-form-item class="switch-item" label="是否启用" prop="state" required>
<bg-switch
:labels="['否', '是']"
:values="[0, 1]"
v-model="formData.state"></bg-switch>
</el-form-item>
</div>
<el-form-item class="userScope" label="用户范围" prop="userScope">
<el-button type="primary" @click="userMaintain"> 用户维护 </el-button>
<div class="table_content clearfix">
<bg-table
ref="bgTable"
:headers="detailHeaders"
:rows="tableRows"
height="550"
:stripe="true">
<template v-slot:isAdmin="{ row }">
<span>{{ userTypeConfig[row.isAdmin] }}</span>
</template>
</bg-table>
<bg-pagination
:page="pageConfig.page"
:size="pageConfig.limit"
:total="pageConfig.total"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</el-form-item>
</el-form>
<el-dialog
class="dialog_box_maintain"
title="用户维护"
v-model="dialogMaintain"
width="1062px">
<div class="content_detail">
<div class="form_filter">
<div class="left">
<span class="sleceted_tip"
>已选择<span class="num">{{ selectedNum }}</span
></span
>
<span class="clean" @click="cleanSelected">清空</span>
</div>
<div class="right">
<el-select
placeholder="全部类型"
v-model="dialogFilterData.isAdmin"
style="width: 200px; margin-left: 16px">
<el-option
v-for="option in userTypeList"
:key="option.value"
:label="option.label"
:value="option.value">
</el-option>
</el-select>
<el-tree-select
style="width: 200px; margin-left: 16px"
placeholder="请选择所属组织"
v-model="dialogFilterData.organizationId"
:data="orgData"
:props="treeProps"
:render-after-expand="false"></el-tree-select>
<el-input
placeholder="请输入关键词"
v-model="dialogFilterData.search"
style="width: 200px; margin: 0 16px 0"
:prefix-icon="Search" />
<el-button type="primary" @click="dialogChangePage(1)">查询</el-button>
<el-button type="default" @click="resetFilter">重置</el-button>
</div>
</div>
<div class="table_content clearfix">
<bg-table
ref="dialogBgTable"
height="430"
select
rowKey="systemId"
:headers="detailHeaders"
:rows="dialogTableRows"
:originSelectedData="selectedRows"
:stripe="true"
@selectAc="selectChange">
<template v-slot:isAdmin="{ row }">
<span>{{ userTypeConfig[row.isAdmin] }}</span>
</template>
</bg-table>
<bg-pagination
:page="dialogPageConfig.page"
:size="dialogPageConfig.limit"
:total="dialogPageConfig.total"
@change-page="dialogChangePage"
@change-size="dialogChangeSize">
</bg-pagination>
</div>
<div class="operate_btns" style="border-top: none">
<el-button @click="dialogMaintain = false"> 取消 </el-button>
<el-button type="primary" @click="save"> 保存 </el-button>
</div>
</div>
</el-dialog>
</div>
<div class="operate_btns">
<el-button type="primary" @click="submit"> 保存 </el-button>
</div>
</div>
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { reactive, toRefs, computed, ref, onBeforeMount, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import axios from "../../../../../request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const route = useRoute();
const router = useRouter();
const { getters } = useStore();
const userTypeConfig = computed(() => getters.getUserTypeConfig || {});
const userTypeList = computed(() =>
Object.keys(userTypeConfig.value).map((key) => ({
label: userTypeConfig.value[key],
value: +key,
}))
);
const dialogBgTable = ref(null);
const state = reactive({
//表单数据
formData: {
ruleName: "",
ruleType: "",
ruleDetail: "",
state: 0,
userScope: [],
},
//表单校验规则
rules: {
ruleName: [
{
required: true,
message: "请输入",
trigger: "blur",
},
],
ruleType: [
{
required: true,
message: "请选择",
trigger: "blur",
},
],
ruleDetail: [
{
required: true,
message: "请输入",
trigger: "blur",
},
],
userScope: [
{
required: true,
message: "请选择",
blur: "change",
},
],
},
dialogFilterData: {
isAdmin: "",
organizationId: "",
search: "",
},
pageConfig: {
page: 1,
limit: 10,
total: 0,
},
//弹框中表格分页配置项
dialogPageConfig: {
page: 1,
limit: 10,
total: 0,
},
//表格数据
tableRows: [],
//被选中的所有数据
selectedRows: {},
//弹框中表格数据
dialogTableRows: [],
//已选择数据条数
selectedNum: 0,
detailHeaders: [
{
label: "账号",
prop: "systemAccount",
// minWidth: 280,
},
{
label: "类型",
prop: "isAdmin",
// minWidth: 360,
},
{
label: "用户手机号",
prop: "phone",
// width: 200,
},
{
label: "所属组织",
prop: "name",
// width: 120,
},
],
orgData: [],
treeProps: {
label: "name",
children: "Child",
value: "organization_id",
},
//用户维护弹框
dialogMaintain: false,
});
const {
formData,
rules,
dialogFilterData,
pageConfig,
dialogPageConfig,
tableRows,
selectedRows,
dialogTableRows,
selectedNum,
detailHeaders,
orgData,
treeProps,
dialogMaintain,
} = toRefs(state);
onBeforeMount(() => {
echoFormData();
getOrgTree();
getTableList();
});
//回显编辑数据
const echoFormData = () => {
const query = route.query;
getUserScopeList();
state.formData.ruleName = query.ruleName;
state.formData.state = +query.state;
state.formData.ruleType = +query.ruleType;
state.formData.ruleDetail = query.ruleDetail;
};
//用户维护
const userMaintain = () => {
state.dialogMaintain = true;
};
//获取所属组织级联数据
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
state.orgData = orgDataTemp;
} else {
ElMessage.error(res.data.data);
}
});
};
const changePage = (page) => {
state.pageConfig.page = page;
state.tableRows = state.selectedRows.slice(
(page - 1) * state.pageConfig.limit,
page * state.pageConfig.limit
);
};
const changeSize = (size) => {
state.pageConfig.limit = size;
changePage(1);
};
const dialogChangePage = (page) => {
state.dialogPageConfig.page = page;
getTableList();
};
const dialogChangeSize = (size) => {
state.dialogPageConfig.limit = size;
dialogChangePage(1);
};
//编辑时回显用户范围数据
const getUserScopeList = () => {
const params = {
limit: 10000,
page: 1,
id: route.query.id,
disp: 0,
};
axios.get("/apaas/system/v5/accessRule/listRuleUser", { params }).then((res) => {
if (res.data.code == 200) {
state.selectedRows = res.data.data || [];
state.pageConfig.total = state.selectedRows.length;
state.selectedNum = state.selectedRows.length;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
};
//获取用户维护数据
const getTableList = () => {
const params = {
limit: state.dialogPageConfig.limit,
page: state.dialogPageConfig.page,
disp: 1,
...state.dialogFilterData,
};
axios.get("/apaas/system/v5/accessRule/listRuleUser", { params }).then((res) => {
if (res.data.code == 200) {
state.dialogTableRows = res.data.data || [];
state.dialogPageConfig.total = res.data.total || 0;
} else {
ElMessage.error(res.data.data);
}
});
};
//重置查询参数
const resetFilter = () => {
Object.keys(state.dialogFilterData).forEach((key) => {
state.dialogFilterData[key] = "";
});
dialogChangePage(1);
};
//用户维护弹框中清空
const cleanSelected = () => {
dialogBgTable.value.clearTable();
};
//用户维护选择项发生变化
const selectChange = (params) => {
state.selectedNum = params.allLength;
};
//保存
const save = () => {
state.dialogMaintain = false;
const res = dialogBgTable.value.dealSelectData();
state.selectedRows = Object.values(res);
state.formData.userScope = state.selectedRows.map((item) => ({
systemId: item.systemId,
}));
state.pageConfig.total = state.formData.userScope.length;
changePage(1);
};
//提交
const submit = () => {
const params = {
ruleId: route.query.ruleId,
...state.formData,
};
axios.put("/apaas/system/v5/accessRule/updateAccessRule", params).then((res) => {
if (res.data.code == 200) {
ElMessage.success("更新成功");
router.push("/config/accessRule");
} else {
ElMessage.error(res.data.data);
}
});
};
</script>
<style lang="scss" scoped>
.page_container {
.main_container {
position: relative;
margin: 0 0 16px;
width: 100%;
height: calc(100% - 62px);
padding: 40px 0 70px;
overflow: auto;
background-color: #fff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
.form_content {
overflow: auto;
height: 100%;
padding-left: 40px;
.el-form {
::v-deep .el-form-item {
display: block;
margin-bottom: 24px;
width: 60%;
.el-form-item__label {
display: block;
margin-bottom: 6px;
height: 14px;
line-height: 14px;
}
&.switch-item {
display: flex;
align-items: center;
.el-form-item__label {
display: inline-flex;
margin-bottom: 0px;
}
.el-switch {
height: 24px;
}
}
&.userScope {
width: 100%;
margin-bottom: 16px;
.el-button {
width: 92px;
}
.el-form-item__label {
margin-bottom: 16px;
}
.el-form-item__content {
display: block;
}
.table_content {
padding-right: 40px;
margin-top: 16px;
}
}
}
}
}
::v-deep .dialog_box_maintain {
.el-dialog__body {
padding: 0 0 70px 0;
height: 630px;
}
.form_filter {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
height: 69px;
border-bottom: 1px solid #e6e9ef;
.left {
font-size: 0px;
.sleceted_tip {
margin: 0 24px 0;
vertical-align: middle;
font-size: 14px;
color: #404a62;
.num {
margin: 0 3px 0 3px;
font-weight: 600;
color: #202531;
}
}
.clean {
vertical-align: middle;
font-size: 14px;
color: #3759be;
cursor: pointer;
}
}
.right {
margin-right: 16px;
.el-button {
width: 64px;
&:last-child {
margin-left: 16px;
}
}
}
}
.table_content {
padding: 0 16px;
}
.operate_btns {
.el-button {
width: 64px;
&:first-child {
margin-right: 4px;
}
}
}
}
.operate_btns {
position: absolute;
bottom: 0;
width: 100%;
height: 70px;
text-align: right;
line-height: 68px;
border-top: solid 1px #e6e9ef;
.el-button {
width: 92px;
margin-right: 16px;
}
}
}
}
</style>
...@@ -2,15 +2,23 @@ ...@@ -2,15 +2,23 @@
<div class="page_container"> <div class="page_container">
<bg-breadcrumb></bg-breadcrumb> <bg-breadcrumb></bg-breadcrumb>
<div class="main_container"> <div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入规则名称或规则"> <bg-filter-group
@search="changeSearch"
v-model="filter.search"
placeholder="请输入规则名称或规则">
<template v-slot:left_action> <template v-slot:left_action>
<div class="apaas_button"> <div class="apaas_button">
<el-button type="primary" @click="addRule"> <el-button type="primary" @click="addRule">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon> <bg-icon
style="font-size: 12px; color: #fff; margin-right: 8px"
icon="#bg-ic-add"></bg-icon>
新增 新增
</el-button> </el-button>
<el-button @click="deleteBatch"> 批量删除 </el-button> <el-button @click="openDeleteDialog(2)"> 批量删除 </el-button>
<span class="sleceted_tip">已选<span class="num">{{selection.length}}</span></span> <span class="sleceted_tip"
>已选<span class="num">{{ selectedNum }}</span
></span
>
<span class="clean" @click="cleanSelected">清空</span> <span class="clean" @click="cleanSelected">清空</span>
</div> </div>
</template> </template>
...@@ -36,13 +44,22 @@ ...@@ -36,13 +44,22 @@
</template> </template>
</bg-filter-group> </bg-filter-group>
<div class="table_container"> <div class="table_container">
<bg-table ref="rulesTable" :headers="headers" :rows="tableRows" :stripe="true" select @selectAc="selectRows" canEdit <bg-table
canEditFlag="state"> ref="rulesTable"
:headers="headers"
:rows="tableRows"
:stripe="true"
select
@selectAc="selectRows"
canEdit
canEditFlag="state">
<template v-slot:rule_type="{ row }"> <template v-slot:rule_type="{ row }">
<span>{{ ["", "IP"][row.rule_type] }}</span> <span>{{ ["", "IP"][row.rule_type] }}</span>
</template> </template>
<template v-slot:num_user="{ row }"> <template v-slot:num_user="{ row }">
<span class="can_click_text under_line" @click="openUserDialog(row)">{{ row.num_user }}</span> <span class="can_click_text under_line" @click="openUserDialog(row)">{{
row.num_user
}}</span>
</template> </template>
<template v-slot:state="{ row }"> <template v-slot:state="{ row }">
<bg-switch <bg-switch
...@@ -58,7 +75,9 @@ ...@@ -58,7 +75,9 @@
<template v-slot:action="{ row }"> <template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :key="row.id"> <bg-table-btns2 :limit="3" :key="row.id">
<bg-table-btn @click="edit(row)">编辑</bg-table-btn> <bg-table-btn @click="edit(row)">编辑</bg-table-btn>
<bg-table-btn :disabled="row.state == 1" @click="deleteCurrent(row)">删除</bg-table-btn> <bg-table-btn :disabled="row.state == 1" @click="openDeleteDialog(1, row)"
>删除</bg-table-btn
>
</bg-table-btns2> </bg-table-btns2>
</template> </template>
</bg-table> </bg-table>
...@@ -76,7 +95,10 @@ ...@@ -76,7 +95,10 @@
<div class="content_detail"> <div class="content_detail">
<div class="form_filter"> <div class="form_filter">
<div class="left"> <div class="left">
<el-select v-model="userFilter.isAdmin" placeholder="请选择" style="width: 200px; margin-left: 16px"> <el-select
v-model="userFilter.isAdmin"
placeholder="请选择"
style="width: 200px; margin-left: 16px">
<el-option <el-option
v-for="(item, index) in userTypeList" v-for="(item, index) in userTypeList"
:key="'pushOptions' + index" :key="'pushOptions' + index"
...@@ -116,7 +138,12 @@ ...@@ -116,7 +138,12 @@
</div> </div>
<div class="table_content"> <div class="table_content">
<bg-table ref="bgUserTable" :headers="userHeaders" :rows="userTableRows" height="430" :stripe="true"> <bg-table
ref="bgUserTable"
:headers="userHeaders"
:rows="userTableRows"
height="430"
:stripe="true">
<template v-slot:isAdmin="{ row }"> <template v-slot:isAdmin="{ row }">
<span>{{ ["", "业务系统用户", "组织管理员", "平台用户"][row.isAdmin] }}</span> <span>{{ ["", "业务系统用户", "组织管理员", "平台用户"][row.isAdmin] }}</span>
</template> </template>
...@@ -131,11 +158,26 @@ ...@@ -131,11 +158,26 @@
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog
class="dialog_box"
:title="deleteDialogConfig.title"
v-model="dialogDelete"
width="400px">
<div style="text-align: center">
{{ deleteDialogConfig.tips }}
</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="dialogDelete = false">取 消</el-button>
<el-button type="primary" @click="confimDelete">确 定</el-button>
</div>
</template>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, toRefs, computed, onBeforeMount ,ref} from "vue"; import { reactive, toRefs, computed, onBeforeMount, ref } from "vue";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
...@@ -146,7 +188,7 @@ import { dateStringTransform } from "@/services/helper.js"; ...@@ -146,7 +188,7 @@ import { dateStringTransform } from "@/services/helper.js";
const router = useRouter(); const router = useRouter();
const rulesTable = ref(null) const rulesTable = ref(null);
const state = reactive({ const state = reactive({
filter: { filter: {
search: "", search: "",
...@@ -189,6 +231,7 @@ const state = reactive({ ...@@ -189,6 +231,7 @@ const state = reactive({
], ],
tableRows: [], tableRows: [],
tableTotal: 0, tableTotal: 0,
selectedNum: 0,
actionRow: {}, actionRow: {},
dialogDetail: false, dialogDetail: false,
userFilter: { userFilter: {
...@@ -239,6 +282,12 @@ const state = reactive({ ...@@ -239,6 +282,12 @@ const state = reactive({
userTableRows: [], userTableRows: [],
userTableTotal: 0, userTableTotal: 0,
selection: [], selection: [],
dialogDelete: false,
deleteDialogConfig: {
title: "删除",
ruleId: [],
tips: "确定要删除当前行数据吗?",
},
}); });
const getOrgList = () => { const getOrgList = () => {
...@@ -295,43 +344,46 @@ const getTableRows = () => { ...@@ -295,43 +344,46 @@ const getTableRows = () => {
}; // 获取表格数据 }; // 获取表格数据
const selectRows = (data) => { const selectRows = (data) => {
state.selectedNum = data.allLength;
state.selection = data.selection; state.selection = data.selection;
} };
// 新增规则跳转
const addRule = () => { const addRule = () => {
// 新增规则跳转 router.push("/config/accessRule/add");
}; //新增 };
const deleteBatch = () => {
console.log(state.selection)
}; //批量删除
const cleanSelected = () => { const cleanSelected = () => {
rulesTable.value.clearTable(); rulesTable.value.clearTable();
}; //清空 }; //清空
// 改变规则状态
const stateChange = (row) => { const stateChange = (row) => {
axios.put(`/apaas/system/v5/accessRule/updateState?id=${row.id}&state=${row.state}`).then((res) => { axios
if (res.data.code == 200) { .put(`/apaas/system/v5/accessRule/updateState?id=${row.id}&state=${row.state}`)
ElMessage.success(res.data.msg); .then((res) => {
changePage(1); if (res.data.code == 200) {
} else { ElMessage.success(res.data.msg);
ElMessage.error(res.data.data); changePage(1);
row.state = row.state == 0 ? 1 : 0; } else {
} ElMessage.error(res.data.data);
}); row.state = row.state == 0 ? 1 : 0;
}; // 改变规则状态 }
});
};
// 打开用户弹窗
const openUserDialog = (row) => { const openUserDialog = (row) => {
state.dialogDetail = true; state.dialogDetail = true;
state.actionRow = row; state.actionRow = row;
clearAction(); clearAction();
}; // 打开用户弹窗 };
const searchUsers = () => { const searchUsers = () => {
changeUserPage(1); changeUserPage(1);
}; // 用户弹窗查询 }; // 用户弹窗查询
// 用户弹窗重置
const clearAction = () => { const clearAction = () => {
state.userFilter = { state.userFilter = {
page: 1, page: 1,
...@@ -342,18 +394,20 @@ const clearAction = () => { ...@@ -342,18 +394,20 @@ const clearAction = () => {
disp: 0, disp: 0,
}; };
changeUserPage(1); changeUserPage(1);
}; // 用户弹窗重置 };
// 用户详情改变分页
const changeUserPage = (page) => { const changeUserPage = (page) => {
state.userFilter.page = page; state.userFilter.page = page;
getUserTableRows(); getUserTableRows();
}; // 用户详情改变分页 };
const changeUserSize = (size) => { const changeUserSize = (size) => {
state.userFilter.limit = size; state.userFilter.limit = size;
changeUserPage(1); changeUserPage(1);
}; };
// 用户详情弹窗数据
const getUserTableRows = () => { const getUserTableRows = () => {
let params = { let params = {
...state.userFilter, ...state.userFilter,
...@@ -367,16 +421,60 @@ const getUserTableRows = () => { ...@@ -367,16 +421,60 @@ const getUserTableRows = () => {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
}); });
}; // 用户详情弹窗数据 };
const edit = (row) => { const edit = (row) => {
// state.dialogDetail = true; router.push({
// router.push(`/develop/account/add`); path: "/config/accessRule/edit",
query: {
id: row.id,
ruleId: row.rule_id,
ruleName: row.rule_name,
state: row.state,
ruleType: row.rule_type,
ruleDetail: row.rule_detail,
},
});
}; //编辑 }; //编辑
const deleteCurrent = (row) => { //打开删除弹窗
const openDeleteDialog = (type, row) => {
}; //删除 if (type === 2) {
const res = rulesTable.value.dealSelectData();
const list = Object.values(res);
if (list.length === 0) return ElMessage.warning("请选择要删除的数据");
state.dialogDelete = true;
const ruleId = list.map((item) => item.rule_id);
state.deleteDialogConfig = { title: "批量删除", ruleId, tips: "确定要删除所选数据吗?" };
return;
}
state.dialogDelete = true;
state.deleteDialogConfig = {
title: "删除",
ruleId: [row.rule_id],
tips: "确定要删除当前行数据吗?",
};
};
//确定删除
const confimDelete = () => {
axios
.delete("/apaas/system/v5/accessRule/delAccessRule", {
data: {
ruleId: state.deleteDialogConfig.ruleId,
},
})
.then((res) => {
if (res.data.code == 200) {
ElMessage.success("删除成功");
changePage(1);
} else {
ElMessage.error(res.data.data);
}
})
.finally(() => {
state.dialogDelete = false;
});
};
const { const {
filter, filter,
...@@ -384,6 +482,7 @@ const { ...@@ -384,6 +482,7 @@ const {
userHeaders, userHeaders,
tableRows, tableRows,
tableTotal, tableTotal,
selectedNum,
dialogDetail, dialogDetail,
userTableRows, userTableRows,
userTableTotal, userTableTotal,
...@@ -391,6 +490,8 @@ const { ...@@ -391,6 +490,8 @@ const {
userTypeList, userTypeList,
orgList, orgList,
selection, selection,
dialogDelete,
deleteDialogConfig,
} = toRefs(state); } = toRefs(state);
onBeforeMount(() => { onBeforeMount(() => {
......
...@@ -69,11 +69,9 @@ ...@@ -69,11 +69,9 @@
</template> </template>
<script setup> <script setup>
import { Search } from "@element-plus/icons-vue";
import { reactive, toRefs, ref, onBeforeMount, nextTick } from "vue"; import { reactive, toRefs, ref, onBeforeMount, nextTick } from "vue";
import axios from "../../../../request/http.js"; import axios from "../../../../request/http.js";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import { validateLink } from "@/services/rules.js"; import { validateLink } from "@/services/rules.js";
import store from "../../../../store"; import store from "../../../../store";
...@@ -116,39 +114,39 @@ const save = () => { ...@@ -116,39 +114,39 @@ const save = () => {
refForm.value.validate((valid) => { refForm.value.validate((valid) => {
if (valid) { if (valid) {
let params = { let params = {
...state.formData ...state.formData,
} };
params.logoUrl = JSON.stringify(params.logoUrl) params.logoUrl = JSON.stringify(params.logoUrl);
params.backgroundUrl = JSON.stringify(params.backgroundUrl) params.backgroundUrl = JSON.stringify(params.backgroundUrl);
axios.put(`/apaas/system/v5/login/updateLogin`,params).then(res => { axios.put(`/apaas/system/v5/login/updateLogin`, params).then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
ElMessage.success(res.data.msg) ElMessage.success(res.data.msg);
getLoginPageConfig() getLoginPageConfig();
}else { } else {
ElMessage.error(res.data.data) ElMessage.error(res.data.data);
} }
}) });
} else { } else {
ElMessage.error("请先将表单填写完整"); ElMessage.error("请先将表单填写完整");
} }
}); });
}; };
const getLoginPageConfig = () => { const getLoginPageConfig = () => {
axios.get(`/apaas/system/v5/login/loginDetail`).then(res => { axios.get(`/apaas/system/v5/login/loginDetail`).then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
let data = res.data.data let data = res.data.data;
store.commit("setSystemLogo", data.logoUrl); store.commit("setSystemLogo", data.logoUrl);
data.logoUrl = data.logoUrl ? JSON.parse(data.logoUrl) : [] data.logoUrl = data.logoUrl ? JSON.parse(data.logoUrl) : [];
data.backgroundUrl = data.backgroundUrl ? JSON.parse(data.backgroundUrl) : [] data.backgroundUrl = data.backgroundUrl ? JSON.parse(data.backgroundUrl) : [];
Object.assign(state.formData,data) Object.assign(state.formData, data);
}else { } else {
ElMessage.error(res.data.data) ElMessage.error(res.data.data);
} }
}) });
} };
onBeforeMount(() => { onBeforeMount(() => {
getLoginPageConfig() getLoginPageConfig();
}) });
const { formData, rules } = toRefs(state); const { formData, rules } = toRefs(state);
</script> </script>
......
...@@ -4,377 +4,140 @@ ...@@ -4,377 +4,140 @@
<div class="flex_row"> <div class="flex_row">
<div class="flex_left"> <div class="flex_left">
<div class="box"> <div class="box">
<el-date-picker style="width: 100%" type="date" placeholder="请选择日期" /> <el-date-picker
style="width: 100%"
type="date"
value-format="YYYY-MM-DD"
v-model="date"
placeholder="请选择日期" />
<div class="type_station bg-scroll"> <div class="type_station bg-scroll">
<div <div
class="type-box" class="type-box"
:class="{ 'current-type': nodeClassifyId == item.classify_id }" :class="{ 'current-type': selectedNodeContainer == item.value }"
@click="nodeClick(item)" @click="nodeClick(item)"
v-for="(item, index) in typeList" v-for="(item, index) in containerList"
:key="'type' + index + 200"> :key="index"
{{ item.classify_name }} :title="item.name">
{{ item.name }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="flex_right"> <div class="flex_right">
<div class="form-filter"> <div class="form-filter">
<el-form inline> <el-form :model="filterForm" inline>
<el-form-item label="级别" prop="force"> <el-form-item label="级别">
<el-select placeholder="全部" style="width: 160px"> <el-select placeholder="全部" style="width: 160px" v-model="filterForm.level">
<el-option label="选项1" value="1"> </el-option> <el-option label="info" value="1"> </el-option>
<el-option label="选项2" value="2"> </el-option> <el-option label="warning" value="2"> </el-option>
<el-option label="error" value="3"> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关键字" prop="force"> <el-form-item label="关键字">
<el-input placeholder="请输入" maxlength="100" style="width: 240px"></el-input> <el-input
placeholder="请输入"
maxlength="100"
style="width: 240px"
v-model="filterForm.search"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="operate_btns"> <div class="operate_btns">
<el-button type="primary"> 查询 </el-button> <el-button type="primary" @click="search"> 查询 </el-button>
<el-button type="default"> 重置 </el-button> <el-button type="default" @click="reset"> 重置 </el-button>
</div>
</div>
<div class="search-result">
<div class="item-container apaas_scroll">
<p v-for="(item, index) in logList" :key="index">{{ item }}</p>
</div> </div>
</div> </div>
<div class="search-result"></div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onBeforeMount, toRefs, computed, watch, nextTick } from "vue"; import { reactive, watch, onBeforeMount, toRefs } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import axios from "../../../../request/http.js"; import axios from "../../../../request/http.js";
import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const bgForm = ref(null);
const state = reactive({ const state = reactive({
bgForm, date: "",
typeList: [], // 分类数据 containerList: [], // 容器数据
typeKeyword: "", // 分类删选关键词 selectedNodeContainer: "",
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典 filterForm: {
nodeId: null, // 当前选中分类的id 用于请求列表 level: "",
timer: null, // 定时器
headers: [
{
label: "名称",
prop: "name",
},
{
label: "描述",
prop: "describe",
minWidth: 360,
},
{
label: "更新时间",
prop: "updated_time",
width: 220,
},
{
label: "是否启用",
prop: "state",
},
{
label: "操作",
prop: "action",
width: 176,
fixed: "right",
},
], // 表格数据表头
tableRows: [], // 表格数据
tableTotal: 0, // 表格数据条数
filter: {
state: "",
search: "", search: "",
page: 1,
limit: 10,
}, // 表格筛选项
stateOptions: [
{
name: "全部",
value: "",
},
{
name: "启用",
value: "1",
},
{
name: "禁用",
value: "0",
},
], // 启用禁用
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
},
rules: {
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
describe: [
{ required: true, message: "请输入描述", trigger: "blur" },
{ max: 200, message: "描述最大为200字", trigger: "blur" },
],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
}, },
logList: [],
}); });
watch(
() => state.date,
(val) => {
state.selectedNodeContainer = "";
getContainerList();
}
);
const nodeClick = (item) => { const nodeClick = (item) => {
state.nodeId = item.id; state.selectedNodeContainer = item.value;
state.nodeClassifyId = item.classify_id; reset();
state.filter = { };
state: "", // 获取容器列表
search: "", const getContainerList = () => {
page: 1,
limit: 10,
};
changePage(1);
}; // 切换字典分类
const getTypeList = () => {
let params = { let params = {
name: state.typeKeyword, date: state.date,
}; };
axios axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params }) .get("/apaas/system/v5/log/system/tree", { params })
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
state.typeList = res.data.data || []; state.containerList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null; state.selectedNodeContainer = state.containerList.length
state.nodeId = state.typeList[0].id || null; ? state.containerList[0].value
if (state.nodeId) { : "";
getTableRows(); state.selectedNodeContainer ? reset() : (state.logList = []);
}
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.error(err);
}); });
}; // 获取字典分类 };
//查询
const changeSearch = (val) => { const search = () => {
state.filter.search = val; let params = {
changePage(1); index: state.selectedNodeContainer,
}; // 表格关键字筛选 ...state.filterForm,
const filterAction = () => {
changePage(1);
}; // 查询按钮
const filterClear = () => {
state.filter = {
state: "",
search: "",
limit: 10,
page: 1,
};
changePage(1);
}; // 重置筛选项
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
axios
.get(`/apaas/system/v5/dictionary/list`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
state.tableRows = res.data.data || [];
state.tableTotal = res.data.total;
if (state.tableRows.length > 0) {
state.tableRows.forEach((e) => {
e.canMoveUp = true;
e.canMoveDown = true;
});
state.tableRows[0].canMoveUp = false;
state.tableRows[state.tableRows.length - 1].canMoveDown = false;
}
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取表格数据
const changeUseRow = (row) => {
axios.put(`/apaas/system/v5/dictionary/state?id=${row.id}&state=${row.state}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
changePage(1);
} else {
ElMessage.error(res.data.data);
row.state = row.state == 0 ? 1 : 0;
}
});
}; // 启用禁用
const changePage = (page) => {
state.filter.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
}; };
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
}; // 新增字典按钮
const edit_row = (row) => {
axios axios
.get(`/apaas/system/v5/dictionary/${row.id}`) .get("/apaas/system/v5/log/system/log", { params })
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
state.actionRow = res.data.data; state.logList = (res.data.data || []).map((item) => JSON.stringify(item));
state.formData = { state.logList = state.logList.concat(state.logList);
name: state.actionRow.name,
describe: state.actionRow.describe,
state: state.actionRow.state,
};
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.error(err);
});
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 2;
state.addDialog = true;
}; // 编辑按钮
const addConfirm = () => {
state.bgForm.validate((valid) => {
if (valid) {
if (state.addType == 1) {
// 新增
let params = {
classify_id: state.nodeClassifyId,
...state.formData,
};
axios.post(`/apaas/system/v5/dictionary/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.addDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
} else {
// 编辑
let params = {
id: state.actionRow.id,
...state.formData,
};
axios.put(`/apaas/system/v5/dictionary/update`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.addDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
}
}
});
}; // 确定新增/编辑
const delete_row = (row) => {
state.dialogDelete = true;
state.actionRow = row;
}; // 删除按钮
const deleteData = () => {
axios.delete(`/apaas/system/v5/dictionary/${state.actionRow.id}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.dialogDelete = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
}; // 确定删除
const moveRow = (row, type) => {
let index;
state.tableRows.forEach((e, i) => {
if (e.id == row.id) {
index = i;
}
});
let nextRow;
if (type == 1) {
// 上移
nextRow = state.tableRows[index - 1];
} else {
// 下移
nextRow = state.tableRows[index + 1];
}
let params = [
{
id: row.id,
sort: nextRow.sort,
},
{
id: nextRow.id,
sort: row.sort,
},
];
axios
.put(`/apaas/system/v5/dictionary/sort`, [...params])
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
changePage(1);
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
}); });
}; };
//重置
const reset = () => {
state.filterForm = {
level: "",
search: "",
};
search();
};
onBeforeMount(() => { onBeforeMount(() => {
getTypeList(); getContainerList();
}); });
const { typeList, typeKeyword, nodeClassifyId, headers, tableRows, tableTotal, filter, stateOptions } = toRefs(state); const { date, containerList, selectedNodeContainer, filterForm, logList } = toRefs(state);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -414,7 +177,10 @@ const { typeList, typeKeyword, nodeClassifyId, headers, tableRows, tableTotal, f ...@@ -414,7 +177,10 @@ const { typeList, typeKeyword, nodeClassifyId, headers, tableRows, tableTotal, f
margin-top: 16px; margin-top: 16px;
height: calc(100% - 50px); height: calc(100% - 50px);
.type-box { .type-box {
overflow: hidden;
text-overflow: ellipsis;
height: 32px; height: 32px;
white-space: nowrap;
line-height: 32px; line-height: 32px;
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
...@@ -459,9 +225,20 @@ const { typeList, typeKeyword, nodeClassifyId, headers, tableRows, tableTotal, f ...@@ -459,9 +225,20 @@ const { typeList, typeKeyword, nodeClassifyId, headers, tableRows, tableTotal, f
.search-result { .search-result {
width: 100%; width: 100%;
height: calc(100% - 84px); height: calc(100% - 84px);
padding: 15px 0;
color: #fff;
background-color: #1a1a1a; background-color: #1a1a1a;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.1); box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.1);
border-radius: 6px; border-radius: 6px;
.item-container {
overflow: auto;
padding: 0 15px;
height: 100%;
}
p {
word-wrap: break-word;
word-break: break-all;
}
} }
} }
} }
......
...@@ -2,15 +2,34 @@ ...@@ -2,15 +2,34 @@
<div class="page_container"> <div class="page_container">
<bg-breadcrumb></bg-breadcrumb> <bg-breadcrumb></bg-breadcrumb>
<div class="main_container"> <div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.keyword" placeholder="请输入账号、手机号和所属机构"> <bg-filter-group
@search="changeSearch"
v-model="filter.search"
placeholder="请输入账号、手机号和所属机构">
<template v-slot:left_action> <template v-slot:left_action>
<div class="apaas_button"> <div class="apaas_button">
<el-button type="primary" @click="addRule"> <el-button type="primary" @click="exportFile">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-file-send"></bg-icon> <bg-icon
style="font-size: 12px; color: #fff; margin-right: 8px"
icon="#bg-ic-file-send"></bg-icon>
导出 导出
</el-button> </el-button>
<el-button @click="deleteBatch"> 强制修改密码 </el-button> <el-popconfirm
<span class="sleceted_tip">已选<span class="num">3</span></span> class="force-modify-btn"
width="220"
icon-color="#ff9900"
title="确认修改密码吗?"
@confirm="forceModifyPwd">
<template #reference>
<el-button slot="reference" type="primary">
<span>强制修改密码</span>
</el-button>
</template>
</el-popconfirm>
<span class="sleceted_tip"
>已选<span class="num">{{ selectedNum }}</span
></span
>
<span class="clean" @click="cleanSelected">清空</span> <span class="clean" @click="cleanSelected">清空</span>
</div> </div>
</template> </template>
...@@ -19,11 +38,11 @@ ...@@ -19,11 +38,11 @@
<div class="left-filter filter_list"> <div class="left-filter filter_list">
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">用户类型</span> <span class="filter_title">用户类型</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.is_admin" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in userTypeList"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
...@@ -41,22 +60,22 @@ ...@@ -41,22 +60,22 @@
</div> </div>
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">活跃度</span> <span class="filter_title">活跃度</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.active" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in activeOptions"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">密码强度</span> <span class="filter_title">密码强度</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.pwd_level" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in pwdLevelList"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
...@@ -69,252 +88,165 @@ ...@@ -69,252 +88,165 @@
</template> </template>
</bg-filter-group> </bg-filter-group>
<div class="table_container"> <div class="table_container">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :stripe="true" select> <bg-table
<template v-slot:ability_name="{ row }"> ref="accountTable"
<span @click="goDetail(row)" class="can_click_text"> :headers="headers"
{{ row.ability_name }} :rows="tableRows"
<span v-if="row.include_mock_service" class="mock_tip"> mock </span> :stripe="true"
</span> select
</template> @selectAc="selectChange">
<template v-slot:ability_state="{ row }">
<span class="circle" :class="'bgc_' + row.ability_state"></span>
{{ ["待上架", "已上架", "已下架", "上架中", "下架中"][row.ability_state] }}
</template>
<template v-slot:start_use="{ row }">
<el-switch></el-switch>
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :key="row.id">
<bg-table-btn @click="edit(row)">编辑</bg-table-btn>
<bg-table-btn @click="deleteCurrent(row)">删除</bg-table-btn>
</bg-table-btns2>
</template>
</bg-table> </bg-table>
<bg-pagination <bg-pagination
:page="filter.page" :page="filter.page"
:size="filter.size" :size="filter.limit"
:total="tableTotal" :total="filter.total"
@change-page="changePage" @change-page="changePage"
@change-size="changeSize"> @change-size="changeSize">
</bg-pagination> </bg-pagination>
</div> </div>
</div> </div>
<el-dialog class="dialog_box_detail" title="用户详情" v-model="dialogDetail" width="1062px">
<div class="content_detail">
<div class="form_filter">
<div class="left">
<el-select placeholder="全部类型" style="width: 200px; margin-left: 16px">
<el-option label="选共享1" value="1"> </el-option>
<el-option label="选共享2" value="2"> </el-option>
</el-select>
<el-select placeholder="请选择所属组织" style="width: 200px; margin-left: 16px">
<el-option label="选共享1" value="1"> </el-option>
<el-option label="选共享2" value="2"> </el-option>
</el-select>
<el-input placeholder="请输入关键词" style="width: 200px; margin-left: 16px" :prefix-icon="Search" />
</div>
<div class="right">
<el-button type="primary" @click="cancelCache">查询</el-button>
<el-button type="default" @click="confirmCache">重置</el-button>
</div>
</div>
<div class="table_content">
<bg-table ref="bgTable" :headers="detailHeaders" :rows="tableRows" height="430" :stripe="true">
<template v-slot:ability_name="{ row }">
<span @click="goDetail(row)" class="can_click_text">
{{ row.ability_name }}
<span v-if="row.include_mock_service" class="mock_tip"> mock </span>
</span>
</template>
<template v-slot:ability_state="{ row }">
<span class="circle" :class="'bgc_' + row.ability_state"></span>
{{ ["待上架", "已上架", "已下架", "上架中", "下架中"][row.ability_state] }}
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :key="row.id">
<bg-table-btn @click="approve(row)">审批</bg-table-btn>
<bg-table-btn @click="approveDetail(row)">审批详情</bg-table-btn>
</bg-table-btns2>
</template>
</bg-table>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</el-dialog>
<el-dialog class="dialog_box" title="提示" v-model="cacheDialog" width="400px">
<div style="font-size: 16px; color: #404a62">你有未提交的服务,是否继续编辑该服务?</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="cancelCache">取 消</el-button>
<el-button type="primary" @click="confirmCache">确 定</el-button>
</div>
</template>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, toRefs, computed, onBeforeMount } from "vue"; import { reactive, toRefs, ref, computed, onBeforeMount } from "vue";
import { Search } from "@element-plus/icons-vue"; import { useStore } from "vuex";
import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import store from "@/store";
import axios from "@/request/http.js"; import axios from "@/request/http.js";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { downloadBlob } from "@/services/helper.js";
const router = useRouter(); const { getters } = useStore();
const userTypeList = computed(() => {
const temp = getters.getUserTypeConfig || {};
return Object.keys(temp).map((key) => ({
label: temp[key],
value: +key,
}));
});
const accountTable = ref(null);
const state = reactive({ const state = reactive({
filter: { filter: {
state: "", search: "",
keyword: "", is_admin: "",
page: 1,
size: 10,
abilityType: 0,
time: [], time: [],
active: 0,
pwd_level: "",
page: 1,
limit: 10,
total: 0,
}, },
stateOptions: [ activeOptions: [
{ { label: "全部", value: "" },
name: "全部", { label: "", value: 1 },
value: "", { label: "", value: 2 },
}, { label: "", value: 3 },
{ ],
name: "已上架", pwdLevelList: [
value: "1", { label: "全部", value: "" },
}, { label: "", value: 1 },
{ { label: "", value: 2 },
name: "已下架", { label: "", value: 3 },
value: "2",
},
{
name: "上架中",
value: "3",
},
{
name: "下架中",
value: "4",
},
{
name: "待上架",
value: "0",
},
], ],
headers: [ headers: [
{ {
label: "账号", label: "账号",
prop: "ability_name", prop: "system_account",
// minWidth: 280, // minWidth: 280,
}, },
{ {
label: "手机号", label: "手机号",
prop: "synopsis", prop: "contact_phone",
// minWidth: 360, // minWidth: 360,
}, },
{ {
label: "用户类型", label: "用户类型",
prop: "created_time", prop: "is_admin",
// width: 200, // width: 200,
}, },
{ {
label: "所属机构", label: "所属机构",
prop: "ability_state", prop: "name",
// width: 120, // width: 120,
}, },
{ {
label: "活跃度", label: "活跃度",
prop: "start_use", prop: "active",
// width: 120, // width: 120,
}, },
{ {
label: "密码强度", label: "密码强度",
prop: "ability_state", prop: "pwd_level",
width: 240, width: 240,
}, },
{ {
label: "密码使用时(天)", label: "密码使用时(天)",
prop: "ability_state", prop: "pwd_is_used",
width: 240, width: 240,
}, },
{ {
label: "创建时间", label: "创建时间",
prop: "ability_state",
width: 240,
},
],
detailHeaders: [
{
label: "账号",
prop: "ability_name",
// minWidth: 280,
},
{
label: "类型",
prop: "synopsis",
// minWidth: 360,
},
{
label: "用户手机号",
prop: "created_time", prop: "created_time",
// width: 200, width: 240,
},
{
label: "所属组织",
prop: "ability_state",
// width: 120,
}, },
], ],
tableRows: [], tableRows: [],
tableTotal: 0, //选中数量
selectedNum: 0,
actionRow: {}, actionRow: {},
dialogDetail: false, dialogDetail: false,
cacheDialog: false, cacheDialog: false,
}); });
const { filter, stateOptions, headers, detailHeaders, tableRows, tableTotal, dialogDetail, cacheDialog } = const { filter, activeOptions, pwdLevelList, headers, tableRows, selectedNum } = toRefs(state);
toRefs(state); //选择项发生变化
// 认证方案未确定,暂时使用假数据registerValid,后续更改 const selectChange = (params) => {
const registerValid = computed(() => { state.selectedNum = params.allLength;
return store.state.registerValid;
});
//新增
const addRule = () => {
router.push("/develop/menu/add");
}; };
//导出
//批量删除 const exportFile = () => {
const deleteBatch = () => {}; let params = { ...state.filter };
//清空 params.start_at = params.time ? params.time[0] || "" : "";
const cleanSelected = () => {}; params.end_at = params.time ? params.time[1] || "" : "";
const cancelCache = () => { delete params.time;
axios axios
.get(`/apaas/service/v5/ability/clear/cach?abilityType=0`) .get(`/apaas/system/v5/log/userAccountAudit/list/export`, {
params,
})
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.status === 200) {
state.cacheDialog = false; downloadBlob(res.data);
router.push("/ability-register/add");
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.statusText);
} }
})
.catch((err) => {
router.push("/ability-register/add");
}); });
}; // 取消按钮,清空缓存跳转注册页 };
const confirmCache = () => {
state.cacheDialog = false; //强制修改密码
router.push("/ability-register/add"); const forceModifyPwd = () => {
}; // 确定按钮,直接跳转注册页 const selectedObj = accountTable.value.dealSelectData();
const selectedRows = Object.values(selectedObj);
if (!selectedRows.length) return ElMessage.warning("请先选择修改项");
const ids = selectedRows.map((item) => item.id);
axios.post("/apaas/system/v5/user/resetpwd", { ids }).then((res) => {
if (res.data.code === 200) {
ElMessage.success(res.data.msg);
cleanSelected();
getTableRows();
} else {
ElMessage.error(res.data.data);
}
});
};
//清空
const cleanSelected = () => {
accountTable.value.clearTable();
};
const changeSearch = (val) => { const changeSearch = (val) => {
state.filter.keyword = val; state.filter.search = val;
changePage(1); changePage(1);
}; };
const changePage = (page) => { const changePage = (page) => {
...@@ -323,17 +255,17 @@ const changePage = (page) => { ...@@ -323,17 +255,17 @@ const changePage = (page) => {
}; };
const getTableRows = () => { const getTableRows = () => {
let params = { ...state.filter }; let params = { ...state.filter };
params.registerStartTime = params.time ? params.time[0] || "" : ""; params.start_at = params.time ? params.time[0] || "" : "";
params.registerEndTime = params.time ? params.time[1] || "" : ""; params.end_at = params.time ? params.time[1] || "" : "";
delete params.time; delete params.time;
axios axios
.get(`/apaas/service/v5/ability/list`, { .get(`/apaas/system/v5/log/userAccountAudit/list`, {
params, params,
}) })
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
state.tableRows = res.data.data || []; state.tableRows = res.data.data || [];
state.tableTotal = res.data.total; state.filter.total = res.data.total;
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
...@@ -343,38 +275,23 @@ const filterAction = () => { ...@@ -343,38 +275,23 @@ const filterAction = () => {
changePage(1); changePage(1);
}; };
const changeSize = (size) => { const changeSize = (size) => {
state.filter.size = size; state.filter.limit = size;
changePage(1); changePage(1);
}; };
const filterClear = () => { const filterClear = () => {
state.filter = { state.filter = {
state: "", search: "",
keyword: "", is_admin: "",
page: 1,
size: 10,
abilityType: 0,
time: [], time: [],
active: 0,
pwd_level: "",
page: 1,
limit: 10,
total: 0,
}; };
changePage(1); changePage(1);
}; };
//编辑
const edit = (row) => {
state.dialogDetail = true;
// router.push(`/develop/account/add`);
};
//删除
const deleteCurrent = (row) => {
router.push(`/develop/account/detail`);
};
const goDetail = (row) => {
router.push({
path: "/ability-manage/real-list/detail",
query: {
id: row.id,
},
});
};
onBeforeMount(() => { onBeforeMount(() => {
getTableRows(); getTableRows();
}); });
......
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content">
<bg-form-gap title="详情"></bg-form-gap>
<bg-detail-table2 class="detail_info" :list="instanceData.detailInfo"> </bg-detail-table2>
</div>
</div>
</template>
<script setup>
import { reactive, onBeforeMount } from "vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import { useRoute } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const route = useRoute();
const instanceData = reactive({
detailInfo: [
{
key: "system_account",
label: "账号",
value: "",
// slot: "approvalStatus",
},
{
key: "phone",
label: "手机号",
value: "",
},
{
key: "user_type",
label: "用户类型",
value: "",
},
{
key: "org_name",
label: "所属机构",
value: "",
},
{
key: "system_module",
label: "系统模块",
value: "",
},
{
key: "created_time",
label: "操作时间",
value: "",
},
{
key: "operate_type",
label: "操作类型",
value: "",
},
{
key: "req_method_str",
label: "请求方式",
value: "",
},
{
key: "operate_status_str",
label: "操作状态",
value: "",
},
{
key: "operate_ip",
label: "操作地址",
value: "",
},
{
key: "operate_addr",
label: "操作地点",
value: "",
width: "100%",
},
{
key: "req_url",
label: "请求地址",
value: "",
width: "100%",
},
{
key: "req_param",
label: "请求参数",
value: "",
},
{
key: "operate_method",
label: "操作方法",
value: "",
},
{
key: "res_fields",
label: "返回参数",
value: "",
},
],
});
onBeforeMount(() => {
getDetailInfo();
});
const getDetailInfo = () => {
axios
.get(`/apaas/system/v5/log/userBehavior/detail/${route.query.id}`)
.then((res) => {
if (res.data.code == 200) {
const result = res.data.data || {};
instanceData.detailInfo.forEach((item) => {
item.value = result[item.key];
});
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
ElMessage.error(err);
});
};
</script>
<style lang="scss" scoped>
.page_content {
position: relative;
padding: 24px 0 68px 24px;
.detail_info,
.approve_info {
margin-bottom: 24px;
width: 960px;
}
}
</style>
...@@ -2,15 +2,23 @@ ...@@ -2,15 +2,23 @@
<div class="page_container"> <div class="page_container">
<bg-breadcrumb></bg-breadcrumb> <bg-breadcrumb></bg-breadcrumb>
<div class="main_container"> <div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.keyword" placeholder="请输入账号、手机号和所属机构"> <bg-filter-group
@search="changeSearch"
v-model="filter.search"
placeholder="请输入账号、手机号和所属机构">
<template v-slot:left_action> <template v-slot:left_action>
<div class="apaas_button"> <div class="apaas_button">
<el-button type="primary" @click="addRule"> <el-button type="primary" @click="exportFile">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-file-send"></bg-icon> <bg-icon
style="font-size: 12px; color: #fff; margin-right: 8px"
icon="#bg-ic-file-send"></bg-icon>
导出 导出
</el-button> </el-button>
<el-button @click="deleteBatch"> 强制修改密码 </el-button> <el-button @click="deleteBatch"> 批量删除 </el-button>
<span class="sleceted_tip">已选<span class="num">3</span></span> <span class="sleceted_tip"
>已选<span class="num">{{ selectedNum }}</span
></span
>
<span class="clean" @click="cleanSelected">清空</span> <span class="clean" @click="cleanSelected">清空</span>
</div> </div>
</template> </template>
...@@ -19,17 +27,17 @@ ...@@ -19,17 +27,17 @@
<div class="left-filter filter_list"> <div class="left-filter filter_list">
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">用户类型</span> <span class="filter_title">用户类型</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.is_admin" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in userTypeList"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">上次访问时间</span> <span class="filter_title">操作时间</span>
<el-date-picker <el-date-picker
v-model="filter.time" v-model="filter.time"
type="daterange" type="daterange"
...@@ -40,23 +48,34 @@ ...@@ -40,23 +48,34 @@
style="width: 300px" /> style="width: 300px" />
</div> </div>
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">活跃度</span> <span class="filter_title">操作类型</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.operate_type" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in operateTypeList"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">密码强度</span> <span class="filter_title">请求方式</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-select v-model="filter.req_method" placeholder="请选择" style="width: 300px">
<el-option <el-option
v-for="(item, index) in stateOptions" v-for="(item, index) in reqMethodList"
:key="'pushOptions' + index" :key="index"
:label="item.name" :label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="filter_item">
<span class="filter_title">操作状态</span>
<el-select v-model="filter.operate_status" placeholder="请选择" style="width: 300px">
<el-option
v-for="(item, index) in operateStatusList"
:key="index"
:label="item.label"
:value="item.value"> :value="item.value">
</el-option> </el-option>
</el-select> </el-select>
...@@ -69,93 +88,45 @@ ...@@ -69,93 +88,45 @@
</template> </template>
</bg-filter-group> </bg-filter-group>
<div class="table_container"> <div class="table_container">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :stripe="true" select> <bg-table
<template v-slot:ability_name="{ row }"> ref="userTable"
<span @click="goDetail(row)" class="can_click_text"> :headers="headers"
{{ row.ability_name }} :rows="tableRows"
<span v-if="row.include_mock_service" class="mock_tip"> mock </span> :stripe="true"
</span> select
</template> @selectAc="selectChange">
<template v-slot:ability_state="{ row }"> <template v-slot:is_admin="{ row }">
<span class="circle" :class="'bgc_' + row.ability_state"></span> <span>{{ userTypeConfig[row.is_admin] }}</span>
{{ ["待上架", "已上架", "已下架", "上架中", "下架中"][row.ability_state] }}
</template>
<template v-slot:start_use="{ row }">
<el-switch></el-switch>
</template> </template>
<template v-slot:req_method="{ row }"
><span>{{ filterReqMethod(row.req_method) }}</span></template
>
<template v-slot:operate_status="{ row }">{{
filterOperateStatus(row.req_method)
}}</template>
<template v-slot:action="{ row }"> <template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :key="row.id"> <bg-table-btns2 :limit="3" :key="row.id">
<bg-table-btn @click="edit(row)">编辑</bg-table-btn> <bg-table-btn @click="goDetail(row)">详情</bg-table-btn>
<bg-table-btn @click="deleteCurrent(row)">删除</bg-table-btn> <bg-table-btn @click="deleteCurrent(row)">删除</bg-table-btn>
</bg-table-btns2> </bg-table-btns2>
</template> </template>
</bg-table> </bg-table>
<bg-pagination <bg-pagination
:page="filter.page" :page="filter.page"
:size="filter.size" :size="filter.limit"
:total="tableTotal" :total="filter.total"
@change-page="changePage" @change-page="changePage"
@change-size="changeSize"> @change-size="changeSize">
</bg-pagination> </bg-pagination>
</div> </div>
</div> </div>
<el-dialog class="dialog_box_detail" title="用户详情" v-model="dialogDetail" width="1062px"> <el-dialog class="dialog_box" title="提示" v-model="deleteDialog" width="400px">
<div class="content_detail"> <div style="font-size: 16px; color: #404a62">{{ deleteTips }}</div>
<div class="form_filter">
<div class="left">
<el-select placeholder="全部类型" style="width: 200px; margin-left: 16px">
<el-option label="选共享1" value="1"> </el-option>
<el-option label="选共享2" value="2"> </el-option>
</el-select>
<el-select placeholder="请选择所属组织" style="width: 200px; margin-left: 16px">
<el-option label="选共享1" value="1"> </el-option>
<el-option label="选共享2" value="2"> </el-option>
</el-select>
<el-input placeholder="请输入关键词" style="width: 200px; margin-left: 16px" :prefix-icon="Search" />
</div>
<div class="right">
<el-button type="primary" @click="cancelCache">查询</el-button>
<el-button type="default" @click="confirmCache">重置</el-button>
</div>
</div>
<div class="table_content">
<bg-table ref="bgTable" :headers="detailHeaders" :rows="tableRows" height="430" :stripe="true">
<template v-slot:ability_name="{ row }">
<span @click="goDetail(row)" class="can_click_text">
{{ row.ability_name }}
<span v-if="row.include_mock_service" class="mock_tip"> mock </span>
</span>
</template>
<template v-slot:ability_state="{ row }">
<span class="circle" :class="'bgc_' + row.ability_state"></span>
{{ ["待上架", "已上架", "已下架", "上架中", "下架中"][row.ability_state] }}
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :key="row.id">
<bg-table-btn @click="approve(row)">审批</bg-table-btn>
<bg-table-btn @click="approveDetail(row)">审批详情</bg-table-btn>
</bg-table-btns2>
</template>
</bg-table>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</el-dialog>
<el-dialog class="dialog_box" title="提示" v-model="cacheDialog" width="400px">
<div style="font-size: 16px; color: #404a62">你有未提交的服务,是否继续编辑该服务?</div>
<template v-slot:footer> <template v-slot:footer>
<div class="apaas_button"> <div class="apaas_button">
<el-button type="default" @click="cancelCache">取 消</el-button> <el-button type="default" @click="deleteDialog = false">取 消</el-button>
<el-button type="primary" @click="confirmCache">确 定</el-button> <el-button type="primary" @click="confirmDelete">确 定</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
...@@ -163,93 +134,94 @@ ...@@ -163,93 +134,94 @@
</template> </template>
<script setup> <script setup>
import { reactive, toRefs, computed, onBeforeMount } from "vue"; import { reactive, ref, toRefs, computed, onBeforeMount } from "vue";
import { Search } from "@element-plus/icons-vue"; import { useStore } from "vuex";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import store from "@/store";
import axios from "@/request/http.js"; import axios from "@/request/http.js";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { operateTypeList, reqMethodList } from "@/services/enumList.js";
import { downloadBlob } from "@/services/helper.js";
const { getters } = useStore();
const router = useRouter(); const router = useRouter();
const userTable = ref(null);
const userTypeConfig = computed(() => getters.getUserTypeConfig || {});
const userTypeList = computed(() => {
const temp = getters.getUserTypeConfig || {};
return Object.keys(temp).map((key) => ({
label: temp[key],
value: +key,
}));
});
const state = reactive({ const state = reactive({
filter: { filter: {
state: "", search: "",
keyword: "", is_admin: "",
page: 1,
size: 10,
abilityType: 0,
time: [], time: [],
operate_type: "",
req_method: "",
operate_status: "",
page: 1,
limit: 10,
total: 0,
}, },
stateOptions: [ operateStatusList: [
{ { label: "全部", value: "" },
name: "全部", { label: "成功", value: 1 },
value: "", { label: "失败", value: 2 },
},
{
name: "已上架",
value: "1",
},
{
name: "已下架",
value: "2",
},
{
name: "上架中",
value: "3",
},
{
name: "下架中",
value: "4",
},
{
name: "待上架",
value: "0",
},
], ],
headers: [ headers: [
{ {
label: "账号", label: "账号",
prop: "ability_name", prop: "system_account",
// minWidth: 280, // minWidth: 280,
}, },
{ {
label: "手机号", label: "用户类型",
prop: "synopsis", prop: "is_admin",
// minWidth: 360, // minWidth: 360,
}, },
{ {
label: "用户类型", label: "系统模块",
prop: "created_time", prop: "system_module",
// width: 200, // width: 200,
}, },
{ {
label: "所属机构", label: "操作类型",
prop: "ability_state", prop: "operate_type",
// width: 120, // width: 120,
}, },
{ {
label: "活跃度", label: "请求方式",
prop: "start_use", prop: "req_method",
// width: 120, // width: 120,
}, },
{ {
label: "密码强度", label: "操作状态",
prop: "ability_state", prop: "operate_status",
width: 240, // width: 240,
}, },
{ {
label: "密码使用时常(天)", label: "操作地点",
prop: "ability_state", prop: "operate_addr",
width: 240, // width: 240,
}, },
{ {
label: "创建时间", label: "操作时间",
prop: "ability_state", prop: "created_time",
width: 240, // width: 240,
},
{
label: "操作",
prop: "action",
width: 120,
}, },
], ],
//选中数量
selectedNum: 0,
detailHeaders: [ detailHeaders: [
{ {
label: "账号", label: "账号",
...@@ -274,47 +246,97 @@ const state = reactive({ ...@@ -274,47 +246,97 @@ const state = reactive({
], ],
tableRows: [], tableRows: [],
tableTotal: 0, tableTotal: 0,
//选中项
selectedRows: [],
actionRow: {}, actionRow: {},
dialogDetail: false, dialogDetail: false,
cacheDialog: false, deleteDialog: false,
deleteTips: "",
}); });
const { filter, stateOptions, headers, detailHeaders, tableRows, tableTotal, dialogDetail, cacheDialog } = const {
toRefs(state); filter,
// 认证方案未确定,暂时使用假数据registerValid,后续更改 operateStatusList,
const registerValid = computed(() => { headers,
return store.state.registerValid; selectedNum,
}); detailHeaders,
//新增 tableRows,
const addRule = () => { tableTotal,
router.push("/develop/menu/add"); dialogDetail,
deleteDialog,
deleteTips,
} = toRefs(state);
//导出
const exportFile = () => {
let params = { ...state.filter };
params.start_at = params.time ? params.time[0] || "" : "";
params.end_at = params.time ? params.time[1] || "" : "";
delete params.time;
axios
.get(`/apaas/system/v5/log/userBehavior/list/export`, {
params,
})
.then((res) => {
if (res.status === 200) {
downloadBlob(res.data);
} else {
ElMessage.error(res.statusText);
}
});
};
//请求方式过滤器
const filterReqMethod = (value) => {
const findItem = reqMethodList.find((item) => item.value === value);
return (findItem || {}).label;
};
//操作状态过滤器
const filterOperateStatus = (value) => {
const findItem = operateTypeList.find((item) => item.value === value);
return (findItem || {}).label;
};
//选择项发生变化
const selectChange = (params) => {
state.selectedNum = params.allLength;
}; };
//批量删除 //批量删除
const deleteBatch = () => {}; const deleteBatch = () => {
//清空 state.selectedRows = [];
const cleanSelected = () => {}; const selectedObj = userTable.value.dealSelectData();
const cancelCache = () => { state.selectedRows = Object.values(selectedObj);
if (!state.selectedRows.length) return ElMessage.warning("请先选择删除项");
state.deleteTips = "确定要删除选中项吗?";
state.deleteDialog = true;
};
//删除当前行
const deleteCurrent = (row) => {
state.selectedRows = [row];
state.deleteTips = "确定要删除当前行吗?";
state.deleteDialog = true;
};
//确定删除
const confirmDelete = () => {
const ids = state.selectedRows.map((item) => item.id);
axios axios
.get(`/apaas/service/v5/ability/clear/cach?abilityType=0`) .delete("/apaas/system/v5/log/userBehavior/delete", { data: { ids: ids } })
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.data.code === 200) {
state.cacheDialog = false; ElMessage.success(res.data.msg);
router.push("/ability-register/add"); cleanSelected();
getTableRows();
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
}) })
.catch((err) => { .finally(() => {
router.push("/ability-register/add"); state.deleteDialog = false;
}); });
}; // 取消按钮,清空缓存跳转注册页 };
const confirmCache = () => { //清空
state.cacheDialog = false; const cleanSelected = () => {
router.push("/ability-register/add"); userTable.value.clearTable();
}; // 确定按钮,直接跳转注册页 };
const changeSearch = (val) => { const changeSearch = (val) => {
state.filter.keyword = val; state.filter.search = val;
changePage(1); changePage(1);
}; };
const changePage = (page) => { const changePage = (page) => {
...@@ -323,17 +345,17 @@ const changePage = (page) => { ...@@ -323,17 +345,17 @@ const changePage = (page) => {
}; };
const getTableRows = () => { const getTableRows = () => {
let params = { ...state.filter }; let params = { ...state.filter };
params.registerStartTime = params.time ? params.time[0] || "" : ""; params.start_at = params.time ? params.time[0] || "" : "";
params.registerEndTime = params.time ? params.time[1] || "" : ""; params.end_at = params.time ? params.time[1] || "" : "";
delete params.time; delete params.time;
axios axios
.get(`/apaas/service/v5/ability/list`, { .get(`/apaas/system/v5/log/userBehavior/list`, {
params, params,
}) })
.then((res) => { .then((res) => {
if (res.data.code == 200) { if (res.data.code == 200) {
state.tableRows = res.data.data || []; state.tableRows = res.data.data || [];
state.tableTotal = res.data.total; state.filter.total = res.data.total;
} else { } else {
ElMessage.error(res.data.data); ElMessage.error(res.data.data);
} }
...@@ -343,33 +365,27 @@ const filterAction = () => { ...@@ -343,33 +365,27 @@ const filterAction = () => {
changePage(1); changePage(1);
}; };
const changeSize = (size) => { const changeSize = (size) => {
state.filter.size = size; state.filter.limit = size;
changePage(1); changePage(1);
}; };
const filterClear = () => { const filterClear = () => {
state.filter = { state.filter = {
state: "", search: "",
keyword: "", is_admin: "",
page: 1,
size: 10,
abilityType: 0,
time: [], time: [],
operate_type: "",
req_method: "",
operate_status: "",
page: 1,
limit: 10,
total: 0,
}; };
changePage(1); changePage(1);
}; };
//编辑
const edit = (row) => {
state.dialogDetail = true;
// router.push(`/develop/account/add`);
};
//删除
const deleteCurrent = (row) => {
router.push(`/develop/account/detail`);
};
const goDetail = (row) => { const goDetail = (row) => {
router.push({ router.push({
path: "/ability-manage/real-list/detail", path: "/log/userBehavior/detail",
query: { query: {
id: row.id, id: row.id,
}, },
......
//操作类型
export const operateTypeList = [
{ label: "全部", value: "" },
{
label: "新建",
value: "新建",
},
{
label: "编辑",
value: "编辑",
},
{
label: "上移",
value: "上移",
},
{
label: "下移",
value: "下移",
},
{
label: "导入",
value: "导入",
},
{
label: "导出",
value: "导出",
},
{
label: "删除",
value: "删除",
},
{
label: "批量启用",
value: "批量启用",
},
{
label: "批量禁用",
value: "批量禁用",
},
{
label: "批量删除",
value: "批量删除",
},
{
label: "分配角色",
value: "分配角色",
},
{
label: "默认角色管理",
value: "默认角色管理",
},
{
label: "分配用户",
value: "分配用户",
},
{
label: "置顶/取消置顶",
value: "置顶/取消置顶",
},
{
label: "预览",
value: "预览",
},
{
label: "发布",
value: "发布",
},
{
label: "重置",
value: "重置",
},
{
label: "对接记录",
value: "对接记录",
},
{
label: "置顶",
value: "置顶",
},
{
label: "强制修改密码",
value: "强制修改密码",
},
{
label: "清空",
value: "清空",
},
{
label: "详情",
value: "详情",
},
{
label: "移出",
value: "移出",
},
{
label: "查看",
value: "查看",
},
];
export const reqMethodList = [
{ label: "全部", value: "" },
{
label: "HEAD",
value: 88,
},
{
label: "PUT",
value: 89,
},
{
label: "DELETE",
value: 90,
},
{
label: "CONNECT",
value: 91,
},
{
label: "OPTIONS",
value: 92,
},
{
label: "TRACE",
value: 93,
},
{
label: "POST",
value: 87,
},
{
label: "GET",
value: 86,
},
];
import router from '@/router' import router from "@/router";
var GetProperty = function (obj, prop) { var GetProperty = function (obj, prop) {
if (!obj) return null; if (!obj) return null;
let res = obj; let res = obj;
if (prop) { if (prop) {
let props = prop.split('.'); let props = prop.split(".");
for (let i = 0; i < props.length; i++) { for (let i = 0; i < props.length; i++) {
res = res[props[i]]; res = res[props[i]];
if (typeof res == "undefined" || res == null) { if (typeof res == "undefined" || res == null) {
...@@ -14,7 +13,7 @@ var GetProperty = function (obj, prop) { ...@@ -14,7 +13,7 @@ var GetProperty = function (obj, prop) {
} }
} }
return res; return res;
} };
var dateFormat = function (fmt, timestamp) { var dateFormat = function (fmt, timestamp) {
let date = new Date(timestamp); let date = new Date(timestamp);
...@@ -25,17 +24,17 @@ var dateFormat = function (fmt, timestamp) { ...@@ -25,17 +24,17 @@ var dateFormat = function (fmt, timestamp) {
"d+": date.getDate().toString(), // 日 "d+": date.getDate().toString(), // 日
"H+": date.getHours().toString(), // 时 "H+": date.getHours().toString(), // 时
"M+": date.getMinutes().toString(), // 分 "M+": date.getMinutes().toString(), // 分
"S+": date.getSeconds().toString() // 秒 "S+": date.getSeconds().toString(), // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串 // 有其他格式化字符需求可以继续添加,必须转化成字符串
}; };
for (let k in opt) { for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt); ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) { if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0"));
}; }
}; }
return fmt; return fmt;
} };
var dateStringTransform = function (date) { var dateStringTransform = function (date) {
/* /*
...@@ -45,8 +44,8 @@ var dateStringTransform = function (date) { ...@@ -45,8 +44,8 @@ var dateStringTransform = function (date) {
if (String(date).indexOf("T") != -1) { if (String(date).indexOf("T") != -1) {
let arr = date.split("T"); let arr = date.split("T");
let t = arr[1]; let t = arr[1];
let tarr = t.split('.000'); let tarr = t.split(".000");
let marr = tarr[0].split(':'); let marr = tarr[0].split(":");
let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]); let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]);
let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]); let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]);
let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]); let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]);
...@@ -55,7 +54,7 @@ var dateStringTransform = function (date) { ...@@ -55,7 +54,7 @@ var dateStringTransform = function (date) {
} else { } else {
return date; return date;
} }
} };
var dateStringTransformChat = function (date) { var dateStringTransformChat = function (date) {
/* /*
...@@ -65,27 +64,27 @@ var dateStringTransformChat = function (date) { ...@@ -65,27 +64,27 @@ var dateStringTransformChat = function (date) {
if (String(date).indexOf("T") != -1) { if (String(date).indexOf("T") != -1) {
let arr = date.split("T"); let arr = date.split("T");
let t = arr[1]; let t = arr[1];
let arr1 = arr[0].split("-") let arr1 = arr[0].split("-");
let tarr = t.split('.000'); let tarr = t.split(".000");
let marr = tarr[0].split(':'); let marr = tarr[0].split(":");
let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]); let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]);
let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]); let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]);
let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]); let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]);
let dd = arr1[1]+"-"+arr1[2] + " " + h + ":" + m; let dd = arr1[1] + "-" + arr1[2] + " " + h + ":" + m;
return dd; return dd;
} else if(date){ } else if (date) {
let arr = date.split(" "); let arr = date.split(" ");
let t = arr[1]; let t = arr[1];
let arr1 = arr[0].split("-") let arr1 = arr[0].split("-");
let tarr = t.split('.000'); let tarr = t.split(".000");
let marr = tarr[0].split(':'); let marr = tarr[0].split(":");
let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]); let h = parseInt(marr[0]) >= 10 ? parseInt(marr[0]) : "0" + parseInt(marr[0]);
let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]); let m = parseInt(marr[1]) >= 10 ? parseInt(marr[1]) : "0" + parseInt(marr[1]);
let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]); let s = parseInt(marr[2]) >= 10 ? parseInt(marr[2]) : "0" + parseInt(marr[2]);
let dd = arr1[1]+"-"+arr1[2] + " " + h + ":" + m; let dd = arr1[1] + "-" + arr1[2] + " " + h + ":" + m;
return dd; return dd;
} }
} };
var downloadFileFormat = function (fileUrl) { var downloadFileFormat = function (fileUrl) {
/* /*
...@@ -97,7 +96,7 @@ var downloadFileFormat = function (fileUrl) { ...@@ -97,7 +96,7 @@ var downloadFileFormat = function (fileUrl) {
} else { } else {
return ""; return "";
} }
} };
var downloadFileFormatNew = function (fileUrl) { var downloadFileFormatNew = function (fileUrl) {
/* /*
...@@ -105,18 +104,18 @@ var downloadFileFormatNew = function (fileUrl) { ...@@ -105,18 +104,18 @@ var downloadFileFormatNew = function (fileUrl) {
output: 1234.png output: 1234.png
*/ */
if (fileUrl != "") { if (fileUrl != "") {
var temp = fileUrl.split('/')[fileUrl.split('/').length-1] var temp = fileUrl.split("/")[fileUrl.split("/").length - 1];
var name = temp.split('_')[0] var name = temp.split("_")[0];
var type = temp.split('_')[temp.split('_').length-1].split('.')[1] var type = temp.split("_")[temp.split("_").length - 1].split(".")[1];
if(temp.indexOf('_')==-1){ if (temp.indexOf("_") == -1) {
return name return name;
}else{ } else {
return name+'.'+type return name + "." + type;
} }
} else { } else {
return ""; return "";
} }
} };
var numberFormat = function (num, decimals) { var numberFormat = function (num, decimals) {
/* /*
...@@ -133,7 +132,7 @@ var numberFormat = function (num, decimals) { ...@@ -133,7 +132,7 @@ var numberFormat = function (num, decimals) {
arr[1] = arr[1].toString() + "0"; arr[1] = arr[1].toString() + "0";
str += arr[1]; str += arr[1];
} else { } else {
str += arr[1].substr(0, 2) str += arr[1].substr(0, 2);
} }
} else { } else {
return mathNum; return mathNum;
...@@ -142,34 +141,34 @@ var numberFormat = function (num, decimals) { ...@@ -142,34 +141,34 @@ var numberFormat = function (num, decimals) {
} else { } else {
return num; return num;
} }
} };
var CreationDateDesc = function (timestamp) { var CreationDateDesc = function (timestamp) {
let date = new Date(timestamp); let date = new Date(timestamp);
return date.toLocaleDateString("zh-CN", { return date.toLocaleDateString("zh-CN", {
timeZone: "Asia/Shanghai" timeZone: "Asia/Shanghai",
}); });
} };
var join_str = function (arr,str,sp) { var join_str = function (arr, str, sp) {
let temp = '' let temp = "";
if(arr){ if (arr) {
if(arr.length){ if (arr.length) {
arr.forEach((e,idx) => { arr.forEach((e, idx) => {
if(idx==arr.length-1){ if (idx == arr.length - 1) {
temp = temp + e[str] temp = temp + e[str];
}else{ } else {
temp = temp + e[str] + sp temp = temp + e[str] + sp;
} }
}); });
return temp return temp;
}else{ } else {
return '' return "";
} }
}else{ } else {
return arr return arr;
} }
} };
var getQueryString = function (name, url) { var getQueryString = function (name, url) {
let search = url.substr(url.indexOf("?")); let search = url.substr(url.indexOf("?"));
...@@ -182,90 +181,108 @@ var getQueryString = function (name, url) { ...@@ -182,90 +181,108 @@ var getQueryString = function (name, url) {
} }
} }
return theRequest[name]; return theRequest[name];
} };
var timeForMatReduce = function(count) { var timeForMatReduce = function (count) {
// 拼接时间 // 拼接时间
let time1 = new Date() let time1 = new Date();
time1.setTime(time1.getTime() - (24 * 60 * 60 * 1000)) time1.setTime(time1.getTime() - 24 * 60 * 60 * 1000);
let Y1 = time1.getFullYear() let Y1 = time1.getFullYear();
let M1 = ((time1.getMonth() + 1) >= 10 ? (time1.getMonth() + 1) : '0' + (time1.getMonth() + 1)) let M1 = time1.getMonth() + 1 >= 10 ? time1.getMonth() + 1 : "0" + (time1.getMonth() + 1);
let D1 = (time1.getDate() >= 10 ? time1.getDate() : '0' + time1.getDate()) let D1 = time1.getDate() >= 10 ? time1.getDate() : "0" + time1.getDate();
let timer1 = Y1 + '-' + M1 + '-' + D1 // 当前时间 let timer1 = Y1 + "-" + M1 + "-" + D1; // 当前时间
let time2 = new Date() let time2 = new Date();
time2.setTime(time2.getTime() - (24 * 60 * 60 * 1000 * count)) time2.setTime(time2.getTime() - 24 * 60 * 60 * 1000 * count);
let Y2 = time2.getFullYear() let Y2 = time2.getFullYear();
let M2 = ((time2.getMonth() + 1) >= 10 ? (time2.getMonth() + 1) : '0' + (time2.getMonth() + 1)) let M2 = time2.getMonth() + 1 >= 10 ? time2.getMonth() + 1 : "0" + (time2.getMonth() + 1);
let D2 = (time2.getDate() >= 10 ? time2.getDate() : '0' + time2.getDate()) let D2 = time2.getDate() >= 10 ? time2.getDate() : "0" + time2.getDate();
let timer2 = Y2 + '-' + M2 + '-' + D2 // 之前的7天或者30天 let timer2 = Y2 + "-" + M2 + "-" + D2; // 之前的7天或者30天
return { return {
t1: timer1, t1: timer1,
t2: timer2 t2: timer2,
} };
} };
var timeForMatAdd = function(count) { var timeForMatAdd = function (count) {
// 拼接时间 // 拼接时间
let time1 = new Date() let time1 = new Date();
time1.setTime(time1.getTime() - (24 * 60 * 60 * 1000)) time1.setTime(time1.getTime() - 24 * 60 * 60 * 1000);
let Y1 = time1.getFullYear() let Y1 = time1.getFullYear();
let M1 = ((time1.getMonth() + 1) >= 10 ? (time1.getMonth() + 1) : '0' + (time1.getMonth() + 1)) let M1 = time1.getMonth() + 1 >= 10 ? time1.getMonth() + 1 : "0" + (time1.getMonth() + 1);
let D1 = (time1.getDate() >= 10 ? time1.getDate() : '0' + time1.getDate()) let D1 = time1.getDate() >= 10 ? time1.getDate() : "0" + time1.getDate();
let timer1 = Y1 + '-' + M1 + '-' + D1 // 当前时间 let timer1 = Y1 + "-" + M1 + "-" + D1; // 当前时间
let time2 = new Date() let time2 = new Date();
time2.setTime(time2.getTime() + (24 * 60 * 60 * 1000 * count)) time2.setTime(time2.getTime() + 24 * 60 * 60 * 1000 * count);
let Y2 = time2.getFullYear() let Y2 = time2.getFullYear();
let M2 = ((time2.getMonth() + 1) >= 10 ? (time2.getMonth() + 1) : '0' + (time2.getMonth() + 1)) let M2 = time2.getMonth() + 1 >= 10 ? time2.getMonth() + 1 : "0" + (time2.getMonth() + 1);
let D2 = (time2.getDate() >= 10 ? time2.getDate() : '0' + time2.getDate()) let D2 = time2.getDate() >= 10 ? time2.getDate() : "0" + time2.getDate();
let timer2 = Y2 + '-' + M2 + '-' + D2 // 之前的7天或者30天 let timer2 = Y2 + "-" + M2 + "-" + D2; // 之前的7天或者30天
return { return {
t1: timer1, t1: timer1,
t2: timer2 t2: timer2,
} };
} };
var useConsole = function(){ var useConsole = function () {
//改写console.log,防止打印数据泄露 //改写console.log,防止打印数据泄露
window.isDebug = false; // 控制是否屏蔽全局console.log 日志;isDebug设为false即可屏蔽 window.isDebug = false; // 控制是否屏蔽全局console.log 日志;isDebug设为false即可屏蔽
//前面做一道筛选,满足则正常打印 //前面做一道筛选,满足则正常打印
//不满足则改写console.log,可以通过window.isDebug改变打印状态 //不满足则改写console.log,可以通过window.isDebug改变打印状态
//方便线上环境进行查看 //方便线上环境进行查看
if (window.isDebug||process.env.NODE_ENV === 'development') { if (window.isDebug || process.env.NODE_ENV === "development") {
return return;
} }
console.log = (function (oldLogFunc) { console.log = (function (oldLogFunc) {
return function () { return function () {
if (window.isDebug||process.env.NODE_ENV === 'development') { if (window.isDebug || process.env.NODE_ENV === "development") {
oldLogFunc.apply(this, arguments); oldLogFunc.apply(this, arguments);
} }
} };
})(console.log); })(console.log);
} };
var getFirstChild = function(menuObj,path){ var getFirstChild = function (menuObj, path) {
let parentPath = menuObj[path].parentPath let parentPath = menuObj[path].parentPath;
if(parentPath){ if (parentPath) {
let temp = menuObj[parentPath].children||[] let temp = menuObj[parentPath].children || [];
for (let index = 0; index < temp.length; index++) { for (let index = 0; index < temp.length; index++) {
const e = temp[index]; const e = temp[index];
if(e.show){ if (e.show) {
pathToUrl(e.path) pathToUrl(e.path);
break break;
} }
} }
} }
} };
var getImageUrl = function(name) { var getImageUrl = function (name) {
return new URL(`../assets/imgs/${name}`, import.meta.url).href; return new URL(`../assets/imgs/${name}`, import.meta.url).href;
}; };
var pathToUrl = (path)=>{ var pathToUrl = (path) => {
if(path.includes('http')){ if (path.includes("http")) {
window.open(path,'_blank') window.open(path, "_blank");
}else{ } else {
router.push(path); router.push(path);
} }
} };
const downloadBlob = (blobData, fileName) => {
const blob = new Blob([blobData], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
});
const url = window.URL.createObjectURL(blob);
const aLink = document.createElement("a");
aLink.style.display = "none";
aLink.href = url;
//指定文件名,不指定就默认
if (fileName) aLink.setAttribute("download", fileName);
document.body.appendChild(aLink);
aLink.click();
/** 下载完成移除元素 */
document.body.removeChild(aLink);
/** 释放掉blob对象 */
window.URL.revokeObjectURL(url);
};
export { export {
GetProperty, GetProperty,
...@@ -283,4 +300,5 @@ export { ...@@ -283,4 +300,5 @@ export {
useConsole, useConsole,
getFirstChild, getFirstChild,
getImageUrl, getImageUrl,
} downloadBlob,
};
...@@ -14,11 +14,20 @@ const store = createStore({ ...@@ -14,11 +14,20 @@ const store = createStore({
msgUnreadNum: 0, msgUnreadNum: 0,
systemLogo: "", systemLogo: "",
whiteList: [], whiteList: [],
userTypeConfig: {
1: "业务系统账号",
2: "组织管理员账号",
3: "平台用户账号",
4: "超级管理员",
},
}, },
getters: { getters: {
count(state) { count(state) {
return state.userInfo; return state.userInfo;
}, },
getUserTypeConfig(state) {
return state.userTypeConfig;
},
}, },
mutations: { mutations: {
setUserInfo(state, info) { setUserInfo(state, info) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment