Commit 5715b4e7 authored by 张耀's avatar 张耀

Merge branch 'dev' into zy

parents c1620424 1cd8c8bf
......@@ -29,9 +29,11 @@ steps: # 定义流水线执行步骤,这些步骤将顺序执行
- name: build # 项目打包
image: registry.cn-qingdao.aliyuncs.com/wod/devops-node:16.16.0-slim
# 将宿主机中文件夹挂载到容器中,宿主机文件夹中的文件会被容器访问并修改,起到使用缓存的作用,避免每次运行都要重现下载依赖,提高运行速度
# 将宿主机中文件夹挂载到容器中,宿主机文件夹中的文件会被容器访问并修改,起到使用缓存的作用,避免每次运行都要重现下载依赖,提高运行速度
commands:
- yarn
# - npm install -g cnpm --registry=https://registry.npm.taobao.org
# - cnpm install
# - yarn
- export NODE_ENV=production
- yarn build
......@@ -51,12 +53,12 @@ steps: # 定义流水线执行步骤,这些步骤将顺序执行
- name: docker-amd64
image: registry.cn-qingdao.aliyuncs.com/wod/devops-docker:1.0
# 将宿主机的 docker和配置挂载到运行的 docker 容器中,那么在容器中运行 docker 命令时,等同于在宿主机中运行该docker命令
# 将宿主机的 docker和配置挂载到运行的 docker 容器中,那么在容器中运行 docker 命令时,等同于在宿主机中运行该docker命令
volumes:
- name: docker-sock
path: /var/run/docker.sock # 将下载依赖的目录挂载出来,防止重复下载
settings: # 当前设置
base: registry.cn-qingdao.aliyuncs.com/wod/nginx:1.19.5-amd64 # 基础镜像
base: registry.cn-qingdao.aliyuncs.com/wod/nginx:1.19.5-amd64 # 基础镜像
dockerfile: .beagle/dockerfile
repo: smart-operation/so-manage-ui # 生成镜像的 分组/名称
version: "v3.0.1" # 版本号
......@@ -80,7 +82,7 @@ steps: # 定义流水线执行步骤,这些步骤将顺序执行
from_secret: KUBERNETES_SERVER
KUBERNETES_TOKEN:
from_secret: KUBERNETES_TOKEN
- name: docker-arm64
image: registry.cn-qingdao.aliyuncs.com/wod/devops-docker:1.0
volumes:
......@@ -153,7 +155,6 @@ trigger:
branch:
- master
kind: pipeline
name: master
steps:
......@@ -195,7 +196,7 @@ steps:
- name: docker-sock
path: /var/run/docker.sock
pull: always
environment:
environment:
REGISTRY_USER:
from_secret: REGISTRY_USER
REGISTRY_PASSWORD:
......@@ -224,7 +225,7 @@ steps:
- name: harbor-arch
image: registry.cn-qingdao.aliyuncs.com/wod/devops-docker-manifest:1.0
settings:
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/mips64le
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/mips64le
template: hub.wodcloud.com/smart-operation/so-manage-ui:v3.0-ARCH
target: hub.wodcloud.com/smart-operation/so-manage-ui:v3.0
username:
......@@ -269,4 +270,4 @@ kind: secret
name: SECRET_KEY_MINIO
get:
name: SECRET_KEY_MINIO
path: devops-secrets
\ No newline at end of file
path: devops-secrets
......@@ -13,5 +13,6 @@
"editor.formatOnSave": true,
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
},
"vue.codeActions.enabled": false
}
......@@ -18,6 +18,7 @@
"element-plus": "^2.2.19",
"github-markdown-css": "^5.1.0",
"html2canvas": "^1.4.1",
"install": "^0.13.0",
"lodash": "^4.17.21",
"markdown-it": "^13.0.1",
"mavon-editor": "^3.0.1",
......@@ -36,4 +37,4 @@
"@vue/compiler-sfc": "^3.2.31",
"vite": "^3.0.0"
}
}
\ No newline at end of file
}
......@@ -143,9 +143,9 @@ const { content } = toRefs(states);
right: 0 !important;
}
/* 光标颜色 */
.vue-ace-editor :deep() .ace_cursor {
/* .vue-ace-editor :deep() .ace_cursor {
color: #fff;
}
} */
.vue-ace-editor-disable :deep() .ace_scrollbar-v {
width: 6px !important;
right: 2px;
......
......@@ -12,7 +12,7 @@
</template>
<script setup>
import { reactive, ref, onBeforeMount, toRefs, watch } from "vue";
import { reactive, ref, onBeforeMount, watch } from "vue";
const props = defineProps({
modelValue: {
type: [String, Number],
......
......@@ -178,4 +178,9 @@ const getRowInfo = (row, key) => {
$_prop_path: propPath,
};
};
defineExpose({
clearSelection,
getRowInfo,
});
</script>
<template>
<el-table
:height="height"
ref="table"
class="bg-table"
:data="rows"
......@@ -14,7 +13,7 @@
<template v-slot:empty>
<div class="empty_container">
<img src="../assets/imgs/img-no-data.png" alt="" />
<div class="text">暂无数据</div>
<div class="text">{{ emptyText }}</div>
</div>
</template>
<el-table-column v-if="paddingLeft > 10 && !border" :width="paddingLeft - 10"></el-table-column>
......@@ -57,10 +56,6 @@ const { nowSelectData, allSelectData, initAllSelectData, selectData, initSelectT
selectTableMixin();
const props = defineProps({
height: {
type: [Number, String],
default: "auto",
},
headers: {
type: Array,
require: true,
......@@ -81,6 +76,10 @@ const props = defineProps({
type: String,
default: "序号",
},
emptyText: {
type: String,
default: "暂无数据",
},
stripe: {
type: Boolean,
default: false,
......
......@@ -6,6 +6,8 @@
directory: 'file',
uniqueCode: false,
}"
:limit="limit"
:http-request="httpRequest"
:before-upload="handleBeforeUpload"
:on-exceed="handleExceed"
:on-success="handleSuccess"
......@@ -95,6 +97,9 @@ const props = defineProps({
type: String,
default: "",
},
httpRequest: {
type: Function,
},
limit: {
type: Number,
default: 9999,
......@@ -123,10 +128,6 @@ watch(
}
);
const handleBeforeUpload = (file) => {
if (state.fileList && state.fileList.length >= props.limit) {
ElMessage.error(`只允许上传${props.limit}个文件`);
return false;
}
let temp = file.name.split(".");
let type = temp[temp.length - 1].toLocaleLowerCase();
let fileTypesOk = props.fileTypes.indexOf(type) > -1 || props.fileTypes.length == 0;
......@@ -143,7 +144,7 @@ const handleBeforeUpload = (file) => {
return fileTypesOk && fileMaxSizeOk;
};
const handleExceed = (file, fileList) => {
console.log(file, fileList);
ElMessage.error(`只允许上传${props.limit}个文件`);
};
const handlePreview = (val) => {
let a = document.createElement("a"); // 生成一个a元素
......
<template>
<div>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
v-for="(item,index) in header"
:key="'header'+index"
prop="date"
:label="item.name"
:width="item.width">
<template v-slot:default="scope">
<span class="table-span" v-for="(it,idx) in item.value" :key="'it'+idx">
<el-input
v-if="it.type == 'input'"
v-show="it.show==undefined?true:typeof(it.show)=='function'?it.show(scope):it.show"
@change="changeData({...scope,type:it.value,check:it.check||null})"
v-model="scope.row[it.value]"
:style="{width:it.width}"
:placeholder="it.placeholder"
:disabled="it.disabled"
></el-input>
<el-select
v-if="it.type == 'select'"
v-show="it.show==undefined?true:typeof(it.show)=='function'?it.show(scope):it.show"
@change="changeData({...scope,type:it.value,check:it.check||null})"
:multiple="it.multiple || false"
v-model="scope.row[it.value]"
:style="{width:it.width}"
:disabled="it.disabled"
:placeholder="it.placeholder"
>
<el-option
v-for="(itx, idxm) in it.arr"
:key="idxm + 600"
:label="itx.label"
:value="itx.value"
:disabled="itx.disabled"
></el-option>
</el-select>
<span v-if="it.type == 'text'" v-show="it.show==undefined?true:typeof(it.show)=='function'?it.show(scope):it.show">{{it.value}}</span>
<span v-if="it.type == 'value'" v-show="it.show==undefined?true:typeof(it.show)=='function'?it.show(scope):it.show">{{scope.row[it.value]}}</span>
<span class="button" v-if="it.type == 'button'" v-show="it.show==undefined?true:typeof(it.show)=='function'?it.show(scope):it.show" @click="it.callback(scope)">{{it.value}}</span>
</span>
</template>
</el-table-column>
</el-table>
</div>
<div>
<el-table :data="tableData" style="width: 100%">
<el-table-column
v-for="(item, index) in header"
:key="'header' + index"
prop="date"
:label="item.name"
:width="item.width">
<template v-slot:default="scope">
<span class="table-span" v-for="(it, idx) in item.value" :key="'it' + idx">
<el-input
v-if="it.type == 'input'"
v-show="it.show == undefined ? true : typeof it.show == 'function' ? it.show(scope) : it.show"
@change="changeData({ ...scope, type: it.value, check: it.check || null })"
v-model="scope.row[it.value]"
:style="{ width: it.width }"
:placeholder="it.placeholder"
:disabled="it.disabled"></el-input>
<el-select
v-if="it.type == 'select'"
v-show="it.show == undefined ? true : typeof it.show == 'function' ? it.show(scope) : it.show"
@change="changeData({ ...scope, type: it.value, check: it.check || null })"
:multiple="it.multiple || false"
v-model="scope.row[it.value]"
:style="{ width: it.width }"
:disabled="it.disabled"
:placeholder="it.placeholder">
<el-option
v-for="(itx, idxm) in it.arr"
:key="idxm + 600"
:label="itx.label"
:value="itx.value"
:disabled="itx.disabled"></el-option>
</el-select>
<span
v-if="it.type == 'text'"
v-show="it.show == undefined ? true : typeof it.show == 'function' ? it.show(scope) : it.show"
>{{ it.value }}</span
>
<span
v-if="it.type == 'value'"
v-show="it.show == undefined ? true : typeof it.show == 'function' ? it.show(scope) : it.show"
>{{ scope.row[it.value] }}</span
>
<span
class="button"
v-if="it.type == 'button'"
v-show="it.show == undefined ? true : typeof it.show == 'function' ? it.show(scope) : it.show"
@click="it.callback(scope)"
>{{ it.value }}</span
>
</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
props: {
header:{
type:Array,
default:()=>[]
},
tableData:{
type:Array,
default:()=>[]
}
props: {
header: {
type: Array,
default: () => [],
},
components: {
},
data() {
return {
};
},
watch: {
},
computed: {
},
created() {
},
mounted() {
tableData: {
type: Array,
default: () => [],
},
methods: {
changeData(val){
this.$emit('change',val)
}
},
components: {},
data() {
return {};
},
watch: {},
computed: {},
created() {},
mounted() {},
methods: {
changeData(val) {
this.$emit("change", val);
},
},
};
</script>
<style scoped>
.table-span{
float: left;
margin-right: 10px;
line-height: 40px;
.table-span {
float: left;
margin-right: 10px;
line-height: 40px;
}
.button{
cursor: pointer;
color: #2b4695;
.button {
cursor: pointer;
color: #2b4695;
}
</style>
......@@ -120,9 +120,7 @@ const login = () => {
ElMessage.error(data.data);
}
})
.catch((error) => {
console.log(error);
});
.catch((error) => {});
};
const getUserInfo = () => {
return axios.get(`/v1/api/user/getUserInfo`);
......
......@@ -30,7 +30,7 @@ import store from "@/store";
import i18n from "./i18n/i18n.js";
import axios from "./request/http.js";
import api from "./request/api.js";
import config from "../package.json";
import { menuData } from "@/components/menu.js";
......@@ -61,6 +61,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
}
createVue.config.globalProperties.$axios = axios;
createVue.config.globalProperties.$api = api;
import menu from "./router/function.js";
......
......@@ -77,7 +77,7 @@ const treeProps = {
disabled: "disabled",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
orgDataTemp.shift();
......
......@@ -22,29 +22,19 @@
</span>
<span> 基本信息 </span>
</span>
<span class="can_click_text detail_btn" v-if="selectTreeDataType === 1" @click="toOrgDetail">
查看详情
<bg-icon style="font-size: 8px; color: #95a3ca; vertical-align: middle" icon="#bg-ic-arrow-right" />
</span>
</div>
<bg-info class="info_box" v-if="selectTreeDataType === 1" :data="baseInfo"></bg-info>
<bg-info class="info_box" v-if="selectTreeDataType === 2" :data="baseInfo2"></bg-info>
<bg-info class="info_box" :data="baseInfo"></bg-info>
</div>
<div class="main_container bgc_white">
<bg-filter-group @search="changeSearch" v-model="filter.key_word" placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="primary" @click="addAccount">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
{{ selectTreeDataType === 1 ? "新增组织管理员" : "新增平台用户" }}
</el-button>
<el-button @click="deleteBatch"> 批量删除 </el-button>
<el-button @click="resetPsd"> 重置密码 </el-button>
<span class="header_info"
>已选择<span style="color: #202531; font-weight: bold">{{ selected.length }}</span
></span
>
<span class="header_info can_click_text" @click="clearSelected">清空</span>
<div class="title">
<span class="icon_box">
<span class="step_icon">
<bg-icon icon="#bg-ic-file"></bg-icon>
</span>
<span> 用户列表 </span>
</span>
</div>
</template>
<template v-slot:filter_group>
......@@ -68,42 +58,9 @@
</template>
</bg-filter-group>
<div class="table_container apaas_scroll">
<bg-table
ref="dataTable"
:headers="headers"
:rows="tableRows"
:isIndex="true"
canEdit
canEditFlag="canSelect"
:stripe="true"
:select="true"
@selectAc="selectRows">
<template v-slot:system_account="{ row }">
<span @click="goDetail(row)" class="can_click_text">
{{ row.system_account }}
</span>
</template>
<template v-slot:state="{ row }">
<bg-switch
@click="stateChange(row)"
:labels="['否', '是']"
:values="[0, 1]"
v-model="row.state"
:disabled="row.is_admin == 4"></bg-switch>
</template>
<bg-table ref="dataTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true">
<template v-slot:action="{ row }">
<bg-table-btn :disabled="row.is_admin == 4" @click="editAccount(row)" class="can_click_text">
编辑
</bg-table-btn>
<bg-table-btn
:disabled="row.is_admin == 4 && userInfo.is_admin !== 4"
@click="editPsdAccount(row)"
class="can_click_text">
修改密码
</bg-table-btn>
<bg-table-btn :disabled="row.is_admin == 4" @click="deleteAccount(row)" class="can_click_text">
删除
</bg-table-btn>
<bg-table-btn @click="goDetail(row)" class="can_click_text"> 详情 </bg-table-btn>
</template>
</bg-table>
<div class="pagination_box">
......@@ -163,172 +120,49 @@
</span>
</template>
</el-dialog>
<el-dialog v-model="deleteRowFlag" title="删除" width="520px" :before-close="handleCloseRowDelete">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedRow.system_account }}</span
>做删除操作。
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseRowDelete">取消</el-button>
<el-button type="primary" @click="deleteRowConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="editFlag" title="修改密码" width="520px" :before-close="handleCloseEdit">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedRow.system_account }}</span
>做修改密码操作,修改后旧密码将无法登录。
</div>
<div>
<el-form
:label-position="'right'"
label-width="120px"
:model="passwordForm"
:rules="passwordFormRules"
ref="passwordRef"
style="max-width: 80%">
<el-form-item label="新密码" prop="password">
<el-input
v-model="passwordForm.password"
:type="password_eye ? 'text' : 'password'"
placeholder="请输入密码">
<template #suffix>
<bg-icon @click="password_eye = !password_eye" class="icon_eye" icon="#bg-ic-eye"></bg-icon>
</template>
</el-input>
</el-form-item>
<el-form-item label="确认新密码" prop="confirm_password">
<el-input
v-model="passwordForm.confirm_password"
:type="confirm_eye ? 'text' : 'password'"
placeholder="请确认新密码">
<template #suffix>
<bg-icon @click="confirm_eye = !confirm_eye" class="icon_eye" icon="#bg-ic-eye"></bg-icon>
</template>
</el-input>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseEdit">取消</el-button>
<el-button type="primary" @click="editConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="deleteFlag" title="删除" width="520px" :before-close="handleCloseDelete">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; mdeleteconfirmargin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedName.join("、") }}</span
>做删除操作。
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseDelete">取消</el-button>
<el-button type="primary" @click="deleteConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="resetFlag" title="重置密码" width="520px" :before-close="handleCloseReset">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedName.join("、") }}</span
>做重置密码操作。
</div>
<div>重置密码为123456,是否继续?</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseReset">取消</el-button>
<el-button type="primary" @click="resetConfirm">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { computed, onBeforeMount, nextTick, reactive, ref, toRefs } from "@vue/runtime-core";
import { onBeforeMount, nextTick, reactive, ref } from "@vue/runtime-core";
import { useRouter } from "vue-router";
import tree from "./tree.vue";
import directoryForm from "./directory-form.vue";
import orgForm from "./org-form.vue";
import CryptoJS from "crypto-js";
import { downloadFileFormatNew } from "@/services/helper";
import store from "@/store";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const dataTable = ref(null);
const toOrgDetail = () => {
router.push({
path: "/authority/organization/org-detail",
query: {
id: selectOrgNode.value.organization_id,
},
});
};
const baseInfo = reactive([
{
name: "组织类型",
value: "",
nameWidth: 130,
},
{
name: "组织代码",
value: "",
nameWidth: 130,
},
{
name: "组织名称",
value: "",
callback: toOrgDetail,
nameWidth: 130,
},
{
name: "创建时间",
value: "",
nameWidth: 130,
},
{
name: "组织管理员数量",
value: "",
nameWidth: 130,
},
{
name: "业务系统数量",
name: "组织代码",
value: "",
nameWidth: 130,
},
]);
const baseInfo2 = reactive([
{
name: "组织名称",
name: "组织描述",
value: "",
nameWidth: 130,
},
{
name: "组织代码",
name: "用户数量",
value: "",
nameWidth: 130,
},
{
name: "用户数",
name: "创建时间",
value: "",
nameWidth: 130,
full: true,
},
]);
const headers = reactive([
......@@ -352,11 +186,6 @@ const headers = reactive([
prop: "created_time",
minWidth: 200,
},
{
label: "是否启用",
prop: "state",
width: 80,
},
{
label: "操作",
prop: "action",
......@@ -393,57 +222,8 @@ const filter = reactive({
page: 1,
limit: 10,
});
const deleteFlag = ref(false);
const deleteRowFlag = ref(false);
const resetFlag = ref(false);
const selectedRow = ref({});
const selected = ref([]);
const selectedName = ref([]);
const editFlag = ref(false);
const password_eye = ref(false);
const confirm_eye = ref(false);
const passwordRef = ref(null);
const passwordForm = reactive({
password: "",
confirm_password: "",
});
const search = ref("");
const userInfo = computed(() => {
return store.state.userInfo;
});
const validatePass = (rule, value, callback) => {
if (value !== passwordForm.password) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
};
const passwordFormRules = reactive({
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, message: "密码长度不得低于8位", trigger: "blur" },
],
confirm_password: [
{ required: true, message: "请确认密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
});
const addAccount = () => {
if (selectTreeDataType.value === 1) {
router.push({
path: "/authority/organization/org-user",
query: {
orgId: selectOrgNode.value.organization_id,
},
});
} else {
router.push({
path: "/authority/organization/platform-user",
});
}
};
const search = ref("");
const changeSize = (size) => {
filter.limit = size;
......@@ -492,7 +272,7 @@ const getDirectoryFromData = (data) => {
name: data.name,
data_type: 0,
};
axios.post(`/apaas/system/v5/org/add`, params).then((res) => {
axios.post(`/v1/api/org/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(res.data.data.id);
......@@ -506,7 +286,7 @@ const getDirectoryFromData = (data) => {
name: data.name,
data_type: 0,
};
axios.put(`/apaas/system/v5/org/${actionTreeData.value.id}`, params).then((res) => {
axios.put(`/v1/api/org/${actionTreeData.value.id}`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id);
......@@ -536,11 +316,9 @@ const getOrgFormData = (data) => {
name: data.name,
organization_code: data.organization_code,
description: data.description,
attachment:
data.attachment && data.attachment.length > 0 ? data.attachment.map((item) => item.url).join(",") : "",
data_type: 1,
};
axios.post(`/apaas/system/v5/org/add`, params).then((res) => {
axios.post(`/v1/api/org/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(res.data.data.id);
......@@ -555,11 +333,9 @@ const getOrgFormData = (data) => {
name: data.name,
organization_code: data.organization_code,
description: data.description,
attachment:
data.attachment && data.attachment.length > 0 ? data.attachment.map((item) => item.url).join(",") : "",
data_type: 1,
};
axios.put(`/apaas/system/v5/org/${actionTreeData.value.id}`, params).then((res) => {
axios.put(`/v1/api/org/${actionTreeData.value.id}`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id);
......@@ -577,7 +353,7 @@ const handleCloseDelNode = () => {
//删除目录/组织
const confirmDelNode = () => {
axios.delete(`/apaas/system/v5/org/${actionTreeData.value.id}`).then((res) => {
axios.delete(`/v1/api/org/${actionTreeData.value.id}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id === selectTreeData.value.id ? null : selectTreeData.value.id);
......@@ -589,7 +365,7 @@ const confirmDelNode = () => {
};
const moveOrg = (params) => {
axios.put(`/apaas/system/v5/org/sort`, params).then((res) => {
axios.put(`/v1/api/org/sort`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(selectTreeData.value.id);
......@@ -615,9 +391,6 @@ const treeAction = (data) => {
level: data.data.value.p_organization_id ? false : true,
organization_code: data.data.value.organization_code,
description: data.data.value.description,
attachment: data.data.value.attachment.split(",").map((i) => {
return { name: downloadFileFormatNew(i), url: i };
}),
});
} else if (data.action === "create") {
orgFormRef.value.setForm({ p_organization_id: data.data.value.organization_id });
......@@ -662,39 +435,23 @@ const getTableRows = () => {
let params = {
...filter,
organization_id: selectTreeData.value.organization_id,
data_type: selectTreeData.value.data_type,
};
axios
.get(`/apaas/system/v5/org/detail`, {
.get(`/v1/api/org/detail`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
tableRows.value = (res.data.data.org_users.data || []).map((item) => {
tableRows.value = ((res.data.data && res.data.data.org_users.data) || []).map((item) => {
item.system_role = item.system_role ? item.system_role.join("") : "-";
return item;
});
tableRows.value.forEach((e) => {
if (e.is_admin == 4 && userInfo.value.is_admin != 4) {
e.canSelect = 1;
} else {
e.canSelect = 0;
}
});
tableTotal.value = res.data.data.org_users.total;
if (params.data_type === 1) {
baseInfo[0].value = res.data.data.org_info.organization_type;
baseInfo[1].value = res.data.data.org_info.organization_code;
baseInfo[2].value = res.data.data.org_info.name;
baseInfo[3].value = res.data.data.org_info.created_time;
baseInfo[4].value = res.data.data.org_info.org_admin_number;
baseInfo[5].value = res.data.data.org_info.business_system_number;
} else {
baseInfo2[0].value = res.data.data.org_info.name;
baseInfo2[1].value = res.data.data.org_info.organization_code;
baseInfo2[2].value = res.data.data.org_info.platform_users_number;
}
console.log(baseInfo);
tableTotal.value = (res.data.data && res.data.data.org_users.total) || 0;
baseInfo[0].value = (res.data.data && res.data.data.org_info.name) || "";
baseInfo[1].value = (res.data.data && res.data.data.org_info.organization_code) || "";
baseInfo[2].value = (res.data.data && res.data.data.org_info.description) || "";
baseInfo[3].value = (res.data.data && res.data.data.org_info.platform_users_number) || "";
baseInfo[4].value = (res.data.data && res.data.data.org_info.created_time) || "";
} else {
ElMessage.error(res.data.data);
}
......@@ -713,157 +470,6 @@ const goDetail = (params) => {
},
});
};
const stateChange = (row) => {
if (row.is_admin == 4) {
return;
}
const state = row.state.toString();
axios.post(`/apaas/system/v5/user/state/${row.id}/${state}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
row.state = row.state == 0 ? 1 : 0;
}
});
};
const editPsdAccount = (data) => {
selectedRow.value = data;
editFlag.value = true;
};
const handleCloseEdit = () => {
if (!passwordRef) return;
passwordRef.value.resetFields();
editFlag.value = false;
};
const editConfirm = () => {
if (!passwordRef) return;
passwordRef.value.validate((valid, fields) => {
if (valid) {
axios
.post(`/apaas/system/v5/user/editpwd`, {
id: selectedRow.value.id,
password: CryptoJS.AES.encrypt(passwordForm.password, "swuE9cmCZQwrkYRV").toString(),
})
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
} else {
ElMessage.error(res.data.data);
}
handleCloseEdit();
});
}
});
};
const deleteAccount = (data) => {
if (data.state === 0) {
selectedRow.value = data;
deleteRowFlag.value = true;
} else {
ElMessage.error("当前状态已启用,不可删除!");
}
};
const handleCloseRowDelete = () => {
deleteRowFlag.value = false;
};
const deleteRowConfirm = () => {
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: [selectedRow.value.id] } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseRowDelete();
});
};
const editAccount = (data) => {
if (selectTreeDataType.value === 1) {
router.push({
path: "/authority/organization/org-user/edit",
query: {
id: data.id,
orgId: selectOrgNode.value.organization_id,
},
});
} else {
router.push({
path: "/authority/organization/platform-user/edit",
query: {
id: data.id,
},
});
}
};
const handleCloseDelete = () => {
deleteFlag.value = false;
};
const deleteConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: ids } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseDelete();
});
};
const deleteBatch = () => {
if (selectedName.value.length > 0) {
deleteFlag.value = true;
} else {
ElMessage.error("请先选择需要操作的数据!");
}
};
const handleCloseReset = () => {
resetFlag.value = false;
};
const resetPsd = () => {
if (selectedName.value.length > 0) {
resetFlag.value = true;
} else {
ElMessage.error("请先选择需要操作的数据!");
}
};
const resetConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.post(`/apaas/system/v5/user/resetpwd`, { ids: ids }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseReset();
});
};
const selectRows = (data) => {
selected.value = data.selection;
selectedName.value = data.selection.map((item) => item.system_account);
};
const clearSelected = () => {
dataTable.value.clearTable();
};
onBeforeMount(() => {});
</script>
......
......@@ -149,7 +149,7 @@ const formatFile = (url) => {
const getDetail = () => {
axios
.get(`/apaas/system/v5/org/detail?organization_id=${route.query.id}&key_word=&state=&limit=&page=&data_type=1`)
.get(`/v1/api/org/detail?organization_id=${route.query.id}&key_word=&state=&limit=&page=&data_type=1`)
.then((res) => {
if (res.data.code == 200) {
const detail = res.data.data.org_info;
......
......@@ -22,16 +22,6 @@
<el-form-item label="组织介绍" prop="description">
<el-input type="textarea" :rows="3" v-model="orgForm.description" maxlength="300" show-word-limit />
</el-form-item>
<el-form-item label="组织附件" prop="logo">
<bg-upload
v-model="orgForm.attachment"
customTips
:limit="3"
:fileTypes="['zip', 'rar', 'doc', 'docx', 'xlsx', 'xls', 'png', 'jpg']"
:otherInfo="'最多可上传三个附件,可上传zip,rar,doc,docx,xlsx,xls,png,jpg,可上传营业执照和相关协议文件等'">
<span>将文件拖到此处,或 点击上传</span>
</bg-upload>
</el-form-item>
</el-form>
</template>
......@@ -51,7 +41,6 @@ const orgForm = reactive({
name: "",
organization_code: "",
description: "",
attachment: [],
});
const checkCode = (rule, value, callback) => {
......@@ -115,7 +104,7 @@ const treeProps = {
disabled: "disabled",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
orgDataTemp.shift();
......
......@@ -198,7 +198,7 @@ const treeProps = {
value: "organization_id",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
orgData.value = res.data.data || [];
} else {
......
......@@ -211,7 +211,7 @@ const cancel = () => {
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
orgId.value = res.data.data[0].organization_id;
} else {
......
......@@ -20,10 +20,7 @@
@click.stop="showAction($event, data, node)">
<bg-icon class="tree-more" icon="#bg-ic-s-more"></bg-icon>
</span>
<span
v-else
class="tree-action-box"
@click.stop="showAction($event, data, node)">
<span v-else class="tree-action-box" @click.stop="showAction($event, data, node)">
<bg-icon class="tree-more" icon="#bg-ic-s-more"></bg-icon>
</span>
</div>
......@@ -141,8 +138,8 @@
</template>
<script setup>
import { reactive, toRefs, ref, computed, onBeforeMount, onBeforeUnmount, watch, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ref, onBeforeMount, onBeforeUnmount, nextTick } from "vue";
import { useRoute } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const route = useRoute();
......@@ -174,10 +171,9 @@ const defaultProps = {
};
const getOrgTree = (data) => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
orgData.value = res.data.data || [];
console.log(route.query.id);
if (route.query.id) {
searchItem(orgData.value, route.query.id);
data = selectNodeObj.value;
......
......@@ -18,14 +18,6 @@
:autosize="{ minRows: 5 }"
:disabled="rowType != 0"></el-input>
</el-form-item>
<el-form-item label="数据权限" prop="data_purview">
<el-radio-group v-model="formData.data_purview" :disabled="rowType != 0">
<el-radio :label="3">全平台所有</el-radio>
<el-radio :label="2">本组织所有</el-radio>
<el-radio :label="1">仅自己</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单功能权限" prop="permission_arr">
<bg-permission
:values="formData.permission_arr"
......@@ -76,14 +68,11 @@ const roleState = reactive({
formData: {
role_name: "",
role_desc: "",
data_purview: 3,
state: 1,
permission_arr: [],
}, // 表单项
rules: {
role_name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
data_purview: [{ required: true, message: "请选择数据权限", trigger: "change" }],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
permission_arr: [{ required: true, type: "array", validator: checkMenuLength, trigger: "change" }],
}, // 表单校验规则
......@@ -97,7 +86,7 @@ const roleState = reactive({
rowType: 0,
});
const getMenuTree = () => {
axios.get(`/apaas/system/v5/menu/tree`).then((res) => {
axios.get(`/v1/api/menu/tree`).then((res) => {
if (res.data.code == 200) {
roleState.permissionData = res.data.data || [];
} else {
......@@ -111,9 +100,9 @@ const changeMenu = (val) => {
}; // 修改选中的菜单
const getRoleDetail = () => {
axios.get(`/apaas/system/v5/role/detail/${route.query.id}`).then((res) => {
axios.get(`/v1/api/role/detail/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
let { role_name, role_desc, data_purview, state, menus } = res.data.data;
let { role_name, role_desc, state, menus } = res.data.data;
roleState.rowType = res.data.data.role_type;
let permission_arr = [];
if (menus && menus.length > 0) {
......@@ -124,11 +113,9 @@ const getRoleDetail = () => {
roleState.formData = {
role_name,
role_desc,
data_purview,
state,
permission_arr: [...permission_arr],
};
console.log(roleState.formData.permission_arr);
} else {
ElMessage.error(res.data.data);
}
......@@ -142,15 +129,14 @@ const saveRole = () => {
role_name: roleState.formData.role_name,
role_desc: roleState.formData.role_desc,
state: roleState.formData.state,
data_purview: roleState.formData.data_purview,
menu_ids: [...roleState.formData.permission_arr],
};
if (!route.query.id) {
// 新增
axios.put(`/apaas/system/v5/role/create`, params).then((res) => {
axios.put(`/v1/api/role/create`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
router.push("/system/role");
router.push("/authority/role");
} else {
ElMessage.error(res.data.data);
}
......@@ -158,10 +144,10 @@ const saveRole = () => {
} else {
// 编辑
params.id = +route.query.id;
axios.post(`/apaas/system/v5/role/update`, params).then((res) => {
axios.post(`/v1/api/role/update`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
router.push("/system/role");
router.push("/authority/role");
} else {
ElMessage.error(res.data.data);
}
......@@ -171,7 +157,7 @@ const saveRole = () => {
});
}; // 新增或编辑角色的保存
const goList = () => {
router.push("/system/role");
router.push("/authority/role");
};
onBeforeMount(() => {
......
......@@ -69,7 +69,7 @@
delete_row(row);
}
"
:disabled="row.state == 1 || row.role_type == 1">
:disabled="row.state == 1 || row.role_type == 1 || row.role_type == 2 || row.user_count > 0">
删除
</bg-table-btn>
</template>
......@@ -105,14 +105,6 @@
<span class="can_click_text" @click="clearUserSelection">清空</span>
</div>
<div class="right">
<el-select v-model="userFilter.is_admin" placeholder="请选择" style="width: 200px">
<el-option
v-for="(item, index) in userTypeList"
:key="'pushOptions' + index"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<el-cascader
v-model="userFilter.organization_id"
:options="orgList"
......@@ -127,7 +119,7 @@
}"
:clearable="true"
collapse-tags
style="width: 200px">
style="width: 200px; margin-right: 30px">
<template #default="{ data }">
<span>{{ data.name }}</span>
</template>
......@@ -135,9 +127,9 @@
<el-input
v-model.trim="userFilter.search"
placeholder="请输入内容"
style="width: 200px"
style="width: 200px; margin-right: 30px"
:prefix-icon="Search" />
<el-button type="primary" @click="searchAction">查询</el-button>
<el-button style="margin-right: 15px" type="primary" @click="searchAction">查询</el-button>
<el-button type="default" @click="clearAction">重置</el-button>
</div>
</div>
......@@ -236,26 +228,11 @@ const state = reactive({
});
const userState = reactive({
userFilter: {
is_admin: "",
organization_id: "",
search: "",
limit: 10,
page: 1,
},
userTypeList: [
{
name: "全部类型",
value: "",
},
{
name: "组织管理员账号",
value: 2,
},
{
name: "平台用户账号",
value: 3,
},
],
orgList: [],
userHeaders: [
{
......@@ -280,10 +257,10 @@ const userState = reactive({
userSelection: [],
distributeDialog: false, // 分配用户弹窗
});
// 获取角色列表
const getRoleRows = () => {
let params = { ...state.filter };
console.log(params);
axios.get(`/apaas/system/v5/role/list`, { params }).then((res) => {
axios.get(`/v1/api/role/list`, { params }).then((res) => {
if (res.data.code == 200) {
state.tableRows = res.data.data || [];
state.tableTotal = res.data.total;
......@@ -291,12 +268,11 @@ const getRoleRows = () => {
ElMessage.error(res.data.data);
}
});
}; // 获取角色列表
};
//获取组织树
const getOrgList = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
console.log(res.data.data);
userState.orgList = res.data.data || [];
} else {
ElMessage.error(res.data.data);
......@@ -319,10 +295,11 @@ const changeSearch = (val) => {
}; // 表格关键字筛选
const changeUseRow = (row) => {
//内置角色不能删除和编辑
if (row.role_type == 1 || row.role_type == 2) {
return;
}
axios.post(`/apaas/system/v5/role/state/${row.id}/${row.state}`).then((res) => {
axios.post(`/v1/api/role/state/${row.id}/${row.state}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
changePage(1);
......@@ -370,10 +347,9 @@ const getUserList = () => {
page: userState.userFilter.page,
search: userState.userFilter.search,
organization_id: userState.userFilter.organization_id,
is_admin: userState.userFilter.is_admin,
role_id: state.actionRow.id,
};
axios.get(`/apaas/system/v5/role/allotment/list`, { params }).then((res) => {
axios.get(`/v1/api/role/allotment/list`, { params }).then((res) => {
if (res.data.code == 200) {
console.log(res.data.data);
userState.userRows = res.data.data || [];
......@@ -381,7 +357,6 @@ const getUserList = () => {
nextTick(() => {
userState.userRows.forEach((e) => {
if (e.is_bind == 1) {
console.log(userTable);
userTable.value.toggleRowSelection(e, true);
}
});
......@@ -402,13 +377,11 @@ const changeUserSize = (val) => {
};
const searchAction = () => {
console.log(userState.userFilter);
changeUserPage(1);
};
const clearAction = (type) => {
userState.userFilter = {
is_admin: "",
organization_id: "",
search: "",
limit: 10,
......@@ -420,7 +393,6 @@ const clearAction = (type) => {
};
const clearUserSelection = () => {
console.log(userTable.value);
userTable.value.clearTable();
};
......@@ -437,7 +409,7 @@ const distribute = () => {
id: state.actionRow.id,
user_ids: user_ids,
};
axios.post(`/apaas/system/v5/role/allotment/user`, params).then((res) => {
axios.post(`/v1/api/role/allotment/user`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
userState.distributeDialog = false;
......@@ -475,7 +447,7 @@ const deleteData = () => {
let params = {
ids: [...ids],
};
axios.delete(`/apaas/system/v5/role/delete`, { data: { ids: [...ids] } }).then((res) => {
axios.delete(`/v1/api/role/delete`, { data: { ids: [...ids] } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.delDialog = false;
......@@ -492,8 +464,7 @@ onBeforeMount(() => {
const { filter, headers, tableRows, tableTotal, delDialog, selection } = toRefs(state);
const { userFilter, userTypeList, orgList, userHeaders, userRows, total, userSelection, distributeDialog } =
toRefs(userState);
const { userFilter, orgList, userHeaders, userRows, total, userSelection, distributeDialog } = toRefs(userState);
</script>
<style lang="scss" scoped>
......@@ -569,7 +540,7 @@ const { userFilter, userTypeList, orgList, userHeaders, userRows, total, userSel
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
justify-content: flex-end;
.el-button {
margin: 0;
width: 64px;
......
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="contactForm"
:rules="contactFormRules"
ref="contactRef"
style="max-width: 66%">
<el-form-item label="联系人姓名" prop="contact_name">
<el-input v-model="contactForm.contact_name" />
</el-form-item>
<el-form-item label="联系人手机号" prop="contact_phone">
<el-input v-model="contactForm.contact_phone" />
</el-form-item>
<el-form-item label="联系人邮箱" prop="contact_email">
<el-input v-model="contactForm.contact_email" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="3" v-model="contactForm.remark" show-word-limit maxlength="300" />
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue";
const contactForm = reactive({
contact_name: "",
contact_phone: "",
contact_email: "",
remark: "",
});
const props = defineProps({
formType: {
type: Boolean,
default: false, //false 新增 true 编辑
},
id: {
type: String,
default: "",
},
});
const checkPhone = (rule, value, callback) => {
var phone_ruler = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/;
setTimeout(() => {
if (!phone_ruler.test(value) && value.length !== 0) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
});
};
const checkName = (rule, value, callback) => {
var reg = /^[a-zA-Z0-9\u4e00-\u9fa5]+$/;
if (!reg.test(value)) {
callback(new Error("只能输入字母、数字和汉字"));
} else {
callback();
}
};
const contactFormRules = reactive({
contact_name: [
{ required: true, message: "请输入联系人姓名", trigger: "blur" },
{ max: 50, message: "联系人姓名最大长度为50个字符", trigger: "blur" },
{ validator: checkName, trigger: "blur" },
],
contact_phone: [
{ required: true, message: "请输入联系人手机号", trigger: "blur" },
{ validator: checkPhone, trigger: "blur" },
],
contact_email: [
{ type: "email", message: "请输入正确的邮箱", trigger: "blur" },
{ max: 100, message: "邮箱最大长度为100个字符", trigger: "blur" },
],
});
const contactRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!contactRef) return;
await contactRef.value.validate((valid, fields) => {
if (valid) {
emit("action", contactForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!contactRef) return;
contactRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(contactForm, data);
};
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
......@@ -3,88 +3,17 @@
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content flex_cloumn">
<div class="content_top apaas_scroll">
<div class="content_process">
<div>
<el-steps :active="step">
<el-step title="" :class="{ process_complete: step > 1 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 0"
><bg-icon class="step_icon" icon="#bg-ic-file"></bg-icon
></span>
<span class="circle" v-else></span>
业务系统信息
</span>
</template>
</el-step>
<el-step title="" :class="{ process_complete: step > 2 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 1"
><bg-icon class="step_icon" icon="#bg-ic-file-staff"></bg-icon
></span>
<span class="circle" v-else></span>
联系人信息
</span>
</template>
</el-step>
<el-step title="">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 2"
><bg-icon class="step_icon" icon="#bg-ic-file-success"></bg-icon
></span>
<span class="circle" v-else></span>
完成
</span>
</template>
</el-step>
</el-steps>
</div>
</div>
<div class="content_main">
<systemForm
v-show="step === 1"
ref="systemFormRef"
:form-type="route.query.id ? true : false"
:id="route.query.id"
@action="getSystemFormData"></systemForm>
<contactForm
v-show="step === 2"
ref="contactFormRef"
:id="route.query.id"
@action="getContactFormData"></contactForm>
<div class="process_end" v-show="step === 3">
<div>
<div>
<img v-if="successFlag" src="@/assets/imgs/img_data-complete.png" alt="" />
<img v-else src="@/assets/imgs/img_data-fail.png" alt="" />
</div>
<div class="font_bold">
{{
route.query.id
? successFlag
? "业务系统编辑成功"
: "业务系统编辑失败"
: successFlag
? "业务系统新增成功"
: "业务系统新增失败"
}}
</div>
<el-button @click="cancel">返回列表</el-button>
<el-button v-if="!route.query.id" type="primary" @click="continueCreate">继续创建</el-button>
</div>
</div>
</div>
</div>
<div class="content_bottom" v-if="step !== 3">
<div v-show="step === 1">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="nextStep">下一步</el-button>
</div>
<div v-show="step === 2">
<div class="content_bottom">
<div>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="previousStep">上一步</el-button>
<el-button type="primary" @click="submit">保存</el-button>
</div>
</div>
......@@ -95,17 +24,14 @@
<script setup>
import { useRoute, useRouter } from "vue-router";
import systemForm from "./system-form.vue";
import contactForm from "./contact-form.vue";
import { reactive, ref, onBeforeUnmount, onMounted } from "vue";
import CryptoJS from "crypto-js";
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 step = ref(1);
const systemFormRef = ref(null);
const contactFormRef = ref(null);
//业务系统表单
const formData = reactive({
organization_id: "",
business_code: "",
......@@ -120,82 +46,51 @@ const formData = reactive({
access_address: "",
develop_id: "",
state: 1,
});
contact_name: "",
contact_phone: "",
contact_email: "",
remark: "",
}); //业务系统表单+联系人表单
const successFlag = ref(false);
// 下一步
const nextStep = () => {
systemFormRef.value.submitForm();
};
//业务系统表单检验触发事件 data为null 校验失败
const getSystemFormData = (data) => {
if (data) {
Object.assign(formData, data);
step.value = 2;
} else {
}
};
//联系人表单检验触发事件 data为null 校验失败
const getContactFormData = (data) => {
if (data) {
Object.assign(formData, data);
if (route.query.id) {
console.log(formData);
let params = {
...formData,
id: parseInt(route.query.id),
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
};
axios.post(`/apaas/system/v5/user/update`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
} else {
let params = {
...formData,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
password: CryptoJS.AES.encrypt(formData.password, "swuE9cmCZQwrkYRV").toString(),
};
axios.put(`/apaas/system/v5/user/create`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
}
}
};
//上一步
const previousStep = () => {
step.value--;
};
//提交表单
const submit = () => {
contactFormRef.value.submitForm();
};
//继续创建 清空表单
const continueCreate = () => {
systemFormRef.value.clearForm();
contactFormRef.value.clearForm();
step.value = 1;
successFlag.value = false;
if (route.query.id) {
let params = {
...formData,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
};
axios.put(`/v1/api/user/${route.query.id}`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
cancel();
} else {
ElMessage.error(res.data.data);
}
});
} else {
let params = {
...formData,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
password: CryptoJS.AES.encrypt(formData.password, "swuE9cmCZQwrkYRV").toString(),
};
axios.put(`/v1/api/user/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
cancel();
} else {
ElMessage.error(res.data.data);
}
});
}
};
//取消
const cancel = () => {
// router.go(-1);
router.push({
path: "/develop/account",
path: "/authority/user",
query: {
id: formData.organization_id,
},
......@@ -203,7 +98,7 @@ const cancel = () => {
};
const getDetail = () => {
axios.get(`/apaas/system/v5/user/detail/${route.query.id}`).then((res) => {
axios.get(`/v1/api/user/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
const form = res.data.data;
systemFormRef.value.setForm({
......@@ -221,13 +116,6 @@ const getDetail = () => {
appid: form.app_id,
appsecret: form.app_secret,
});
contactFormRef.value.setForm({
contact_name: form.contact_name,
contact_phone: form.contact_phone,
contact_email: form.contact_email,
remark: form.remark,
});
} else {
ElMessage.error(res.data.data);
}
......
......@@ -14,7 +14,7 @@
:data="orgData"
:props="defaultProps"
@node-click="handleNodeClick"
node-key="id"
node-key="organization_id"
:highlight-current="true"
:filter-node-method="filterNode"
:default-expand-all="true">
......@@ -276,7 +276,7 @@ const route = useRoute();
const getTableRows = () => {
let params = { ...filter, organization_id: selectNode.value };
axios
.get(`/apaas/system/v5/user/list`, {
.get(`/v1/api/org/detail`, {
params,
})
.then((res) => {
......@@ -297,7 +297,7 @@ const addAccount = (params) => {
const handleNodeClick = (data) => {
if (data.data_type == 1) {
selectNode.value = data.id;
selectNode.value = data.organization_id;
changePage(1);
} else {
nextTick(() => {
......@@ -321,18 +321,19 @@ const defaultProps = {
class: customNodeClass,
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
axios.get(`/v1/api/org/tree`).then((res) => {
if (res.data.code == 200) {
orgData.value = res.data.data || [];
orgData.value.shift();
// orgData.value.shift();
const orgList = searchOrg(orgData.value);
if (route.query.id) {
searchItem(orgData.value, route.query.id);
console.log("orgList", orgList);
if (route.query.organization_id) {
searchItem(orgData.value, route.query.organization_id);
} else {
selectNode.value = orgList.length > 0 ? orgList[0].id : "";
selectNode.value = orgList.length > 0 ? orgList[0].organization_id : "";
}
nextTick(() => {
if (route.query.id) {
if (route.query.organization_id) {
treeRef.value.setCurrentNode(selectNodeObj.value);
} else {
if (orgList.length > 0) {
......@@ -346,14 +347,14 @@ const getOrgTree = () => {
}
});
};
const searchItem = (data, id) => {
const searchItem = (data, organization_id) => {
data.forEach((e) => {
if (e.organization_id == id) {
if (e.organization_id == organization_id) {
selectNodeObj.value = e;
selectNode.value = e.id;
selectNode.value = e.organization_id;
} else {
if (e.Child) {
searchItem(e.Child, id);
searchItem(e.Child, organization_id);
}
}
});
......@@ -361,7 +362,7 @@ const searchItem = (data, id) => {
const searchOrg = (data) => {
const arr = [];
data.forEach((item) => {
if (item.data_type === 1) {
if (item.data_type > 0) {
arr.push(item);
return;
} else {
......@@ -385,8 +386,11 @@ const filterNode = (value, data) => {
};
const stateChange = (row) => {
const state = row.state.toString();
axios.post(`/apaas/system/v5/user/state/${row.id}/${state}`).then((res) => {
const params = {
id: row.id,
state: row.state == 1 ? 0 : 1,
};
axios.post(`/v1/api/user/updateState`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
......@@ -449,7 +453,7 @@ const handleCloseRowDelete = () => {
const deleteConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: ids } }).then((res) => {
axios.delete(`/v1/api/user/del`, { data: { ids: ids } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
......@@ -461,7 +465,7 @@ const deleteConfirm = () => {
};
const deleteRowConfirm = () => {
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: [selectedRow.value.id] } }).then((res) => {
axios.delete(`/v1/api/user/del`, { data: { ids: [selectedRow.value.id] } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
......@@ -494,7 +498,7 @@ const resetPsd = () => {
const resetConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.post(`/apaas/system/v5/user/resetpwd`, { ids: ids }).then((res) => {
axios.post(`/v1/api/user/resetPwd`, { ids: ids }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
......@@ -522,7 +526,7 @@ const editConfirm = () => {
passwordRef.value.validate((valid, fields) => {
if (valid) {
axios
.post(`/apaas/system/v5/user/editpwd`, {
.post(`/v1/api/user/updatePwd`, {
id: selectedRow.value.id,
password: CryptoJS.AES.encrypt(passwordForm.password, "swuE9cmCZQwrkYRV").toString(),
})
......
<template>
<div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<div class="content_main bg-scroll">
<el-form
label-position="top"
label-width="100px"
ref="ruleFormRef"
:model="formData"
:rules="formRules"
style="max-width: 70%">
<el-form-item label="主机分组名称" prop="host_name">
<el-input
:disabled="route.query.id"
clearable
v-model="formData.host_name"
maxlength="20"
placeholder="请输入主机分组名称"
show-word-limit />
</el-form-item>
</el-form>
<bg-inner-tabs v-model="currentTab" :data="tabOptions"></bg-inner-tabs>
<listTable v-show="currentTab == 0" ref="listTableRef" :initTableData="initTableData"></listTable>
<div class="upload_container" v-show="currentTab == 1">
<div class="upload_top">
<div class="required-item">上传文件</div>
<div>
模版下载:<span class="file" @click="downloadFile(`/主机IP模板.xlsx`)"
>IP主机模板<bg-icon icon="#bg-ic-to-bottom"></bg-icon
></span>
</div>
</div>
<bg-upload
:httpRequest="httpRequest"
style="width: 360px"
v-model="attachment"
customTips
:limit="1"
:fileTypes="['xlsx', 'xls']">
<span>将文件拖到此处,或 点击上传</span><br />
<span>支持上传一个后缀为.xlsx或.xls的文件,文件大小不超过20M,最多解析1000个IP</span>
</bg-upload>
</div>
</div>
<div class="content_foot apaas_button">
<el-button type="default" @click="back"> 取消 </el-button>
<el-button type="primary" @click="save"> 保存 </el-button>
</div>
</div>
<checkStatusDialog v-model="checkStatusVisible" :enter="1" :checkStatusData="checkStatusData"></checkStatusDialog>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import listTable from "../components/list-table.vue";
import checkStatusDialog from "../components/check-status-dialog.vue";
import { downloadFileFormat } from "@/services/helper.js";
const { proxy } = getCurrentInstance();
const { $api } = proxy;
const router = useRouter();
const route = useRoute();
const formData = reactive({
host_name: "",
});
const formRules = reactive({
host_name: [{ required: true, message: "主机分组名称不能为空", trigger: "blur" }],
});
const attachment = ref([]);
const downloadFile = (data) => {
const a = document.createElement("a"); // 创建a标签
a.setAttribute("download", ""); // download属性
a.setAttribute("href", data); // href链接
a.click(); // 自执行点击事件
};
const currentTab = ref(0);
const tabOptions = ref(["列表维护", "文件上传"]);
const ruleFormRef = ref();
const listTableRef = ref();
const checkStatusVisible = ref(false);
const checkStatusData = ref({});
const save = () => {
ruleFormRef.value.validate((valid) => {
if (currentTab.value == 0) {
let { flag, list } = listTableRef.value.getData();
if (flag && valid) {
checkStatusData.value = {
detection_type: 2,
host_manage_list: list,
host_name: formData.host_name,
};
checkStatusVisible.value = true;
}
} else {
if (attachment.value.length == 0) {
return ElMessage.error("请上传文件");
}
checkStatusData.value = {
detection_type: 3,
file_name: attachment.value[0].url.split("/").at(-1),
host_file_url: attachment.value[0].url,
host_name: formData.host_name,
};
if (valid) {
checkStatusVisible.value = true;
}
}
});
};
const back = () => {
router.back();
};
const initTableData = ref([]);
const getHostManageDetail = () => {
$api.autoMaintenance.getHostManageDetail(route.query.id).then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
formData.host_name = data.host_name;
initTableData.value = data.host_list || [];
if (data.host_file_url) {
currentTab.value = 1;
attachment.value = [
{
name: downloadFileFormat(data.host_file_url),
url: data.host_file_url,
},
];
}
} else {
ElMessage.error(res.data.data);
}
});
};
const httpRequest = (file) => {
let formData = new FormData();
formData.append("upload_file", file.file);
$api.autoMaintenance.uploadHostManageFile(formData).then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
file.onSuccess({
data,
});
} else {
ElMessage.error(res.data.data);
}
});
};
onMounted(() => {
if (route.query.id) {
getHostManageDetail();
}
});
</script>
<style lang="scss" scoped>
.main_container {
.content_main {
padding: 30px;
height: 0;
flex: auto;
overflow: auto;
}
.content_foot {
border-top: 1px solid #e6e9ef;
padding: 16px 16px 0 16px;
display: flex;
justify-content: flex-end;
}
.upload_container {
width: 360px;
.upload_top {
margin: 16px 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
color: #404a62;
.file {
color: #3759be;
cursor: pointer;
}
}
}
.required-item::before {
content: "*";
color: #d75138;
margin-right: 4px;
}
}
</style>
<template>
<el-dialog
class="dialog_box check_status_dialog"
title="连接状态检测"
v-model="dialogVisible"
width="1024px"
@closed="resetDialog">
<div class="main">
<div class="title" v-if="props.enter == 0">主机分组名称:{{ props.checkStatusData.host_name }}</div>
<div class="loading-container">
<span class="icon_box" :class="{ ic_animation: stateValue == 0 }"
><bg-icon :class="getClassName(stateValue)" :icon="getIcon(stateValue)"
/></span>
<span>{{ getText(stateValue) }}</span>
</div>
<div class="table-container">
<div class="table-top">
<span>异常状态列表</span>
<el-button type="primary" @click="exportFile" :disabled="stateValue == 0 || tableTotal == 0">
导出
</el-button>
</div>
<div class="status-lists">
<div class="table">
<bg-table
:empty-text="'无异常数据'"
:height="300"
ref="taskTable"
:headers="taskHeaders"
:rows="taskRows"
:isIndex="true"
:stripe="true">
<template v-slot:voucher_type="{ row }">
{{ row.voucher_type == 0 ? "密码验证" : "密钥验证" }}
</template>
</bg-table>
</div>
<bg-pagination
v-if="taskRows.length > 0"
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="dialogVisible = false">{{ props.enter == 0 ? "关闭" : "取消" }}</el-button>
<el-button :disabled="stateValue != 1" v-if="props.enter != 0" type="primary" @click="save"
>剔除异常数据并保存</el-button
>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, ref, onBeforeMount, getCurrentInstance, computed, watch, nextTick, watchEffect } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
const { $api } = proxy;
const router = useRouter();
const route = useRoute();
const props = defineProps({
modelValue: {
type: Boolean,
},
checkStatusData: {
type: Object,
},
// 0:列表页 1:详情页
enter: {
type: Number,
},
});
const emit = defineEmits(["update:modelValue"]);
const dialogVisible = computed({
get() {
if (props.modelValue) {
postHostManageState();
}
return props.modelValue;
},
set(value) {
emit("update:modelValue", value);
},
});
const stateUUID = ref("");
const postHostManageState = () => {
const formData = new FormData();
formData.append("detection_type", props.checkStatusData.detection_type);
switch (props.checkStatusData.detection_type) {
case 1:
formData.append("id", props.checkStatusData.id);
break;
case 2:
formData.append("host_manage_list", JSON.stringify(props.checkStatusData.host_manage_list));
break;
case 3:
formData.append("file_name", props.checkStatusData.file_name);
break;
}
$api.autoMaintenance.postHostManageState(formData).then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
stateUUID.value = data;
stateValue.value = 1;
getTableRows();
} else {
stateValue.value = 2;
ElMessage.error(res.data.data);
}
});
};
const exportFile = () => {
let params = {
detection_type: props.enter == 0 ? 1 : 0,
};
switch (params.detection_type) {
case 1:
params.id = props.checkStatusData.id;
break;
case 0:
params.uuid = stateUUID.value;
break;
}
ElMessage.success("开始导出");
let url = `/v1/api/automated_mainten/host_manage/export?`;
const paramsArray = [];
for (const [key, value] of Object.entries(params)) {
paramsArray.push(`${key}=${value}`);
}
url += paramsArray.join("&");
const a = document.createElement("a");
const event = new MouseEvent("click");
a.href = url;
a.dispatchEvent(event);
};
const stateValue = ref(0);
const getIcon = (stateValue = 0) => {
const icons = ["#bg-ic-s-circle-restart", "#bg-ic-s-circle-check", "#bg-ic-s-circle-close"];
return icons[stateValue];
};
const getClassName = (stateValue = 0) => {
const classNames = ["pending", "success", "error"];
return classNames[stateValue];
};
const getText = (stateValue = 0) => {
const text = ["状态检测中", "状态检测完成", "状态检测失败"];
return text[stateValue];
};
const taskHeaders = [
{
prop: "ip",
label: "IP",
},
{
prop: "port",
label: "端口",
},
{
prop: "voucher_type",
label: "凭证类型",
},
{
prop: "user_name",
label: "用户名",
},
{
prop: "password",
label: "密码",
},
];
const taskRows = ref([]);
const filter = ref({
page: 1,
size: 10,
});
const tableTotal = ref(0);
const changePage = (page) => {
filter.value.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
filter.value.size = size;
changePage(1);
}; // 改变每页条数
const getTableRows = () => {
let params = {
detection_type: props.enter == 0 ? 1 : 2,
};
switch (params.detection_type) {
case 1:
params.id = props.checkStatusData.id;
params.page = filter.value.page;
params.page_size = filter.value.size;
break;
case 2:
params.uuid = stateUUID.value;
params.page = filter.value.page;
params.page_size = filter.value.size;
break;
}
$api.autoMaintenance.getHostManageIPExceptionList(params).then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
taskRows.value = data;
tableTotal.value = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
};
const save = () => {
let data = {
uuid: stateUUID.value,
};
if (props.checkStatusData.detection_type == 3) {
data.host_file_url = props.checkStatusData.host_file_url;
}
if (route.query.id) {
// 编辑
data.id = Number(route.query.id);
$api.autoMaintenance.putHostManageEdit(data).then((res) => {
if (res.data.code == 200) {
ElMessage.success("保存成功");
router.back();
} else {
ElMessage.error(res.data.data);
}
});
} else {
// 新增
data.host_name = props.checkStatusData.host_name;
$api.autoMaintenance.postHostManageAdd(data).then((res) => {
if (res.data.code == 200) {
ElMessage.success("保存成功");
router.back();
} else {
ElMessage.error(res.data.data);
}
});
}
};
const resetDialog = () => {
stateValue.value = 0;
taskRows.value = [];
tableTotal.value = 0;
filter.value.page = 1;
filter.value.size = 10;
};
</script>
<style lang="scss" scoped>
.dialog_box {
.main {
.title {
text-align: left;
margin-bottom: 10px;
font-weight: bold;
font-size: 16px;
}
.loading-container {
margin: auto;
text-align: center;
width: 200px;
background-color: #eaedf5;
border-radius: 4px;
font-size: 14px;
color: #404a62;
padding: 10px 0;
.icon_box {
margin-right: 8px;
display: inline-block;
}
.pending {
font-size: 14px;
color: #3759be;
}
.success {
font-size: 14px;
color: #429e8a;
}
.error {
font-size: 14px;
color: #d75138;
}
.ic_animation {
animation: loading-rotate 1.5s linear infinite;
}
@keyframes loading-rotate {
100% {
transform: rotate(360deg);
}
}
}
.table-container {
.table-top {
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0;
font-weight: bold;
font-size: 16px;
}
.status-lists {
margin-top: 16px;
overflow: hidden;
padding-bottom: 10px;
}
}
}
}
</style>
<style lang="scss">
.check_status_dialog {
.el-dialog__footer {
border-top: 1px solid #e6e9ef;
}
.bg-table .el-table__empty-block {
height: unset !important;
.empty_container {
height: unset;
padding-top: 46px;
}
}
}
</style>
<template>
<el-form style="margin: 16px 0" ref="ruleFormRef" class="rule-form" :model="tableRows">
<bg-table-pro
class="input-table"
:headers="headers"
:data="tableRows"
ref="inputTable"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
row-key="id"
default-expand-all
:border="true"
:stripe="false">
<template #ip="{ row }">
<el-form-item
:rules="{
required: true,
message: 'IP不能为空',
trigger: 'blur',
}"
style="width: 100%"
:prop="`${row.$row_path}.ip`">
<el-input clearable placeholder="请输入IP" v-model="row.ip" />
</el-form-item>
</template>
<template #port="{ row }">
<el-form-item style="width: 100%">
<el-input clearable placeholder="请输入端口号" v-model="row.port" />
</el-form-item>
</template>
<template #voucher_type="{ row }">
<el-form-item
:rules="{
required: true,
message: '凭证类型不能为空',
trigger: 'change',
}"
style="width: 100%"
:prop="`${row.$row_path}.voucher_type`">
<el-select @change="(val) => changeType(val, row)" v-model="row.voucher_type" placeholder="请选择凭证类型">
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</template>
<template #user_name="{ row }">
<el-form-item
:rules="{
required: true,
message: '用户名不能为空',
trigger: 'blur',
}"
style="width: 100%"
:prop="`${row.$row_path}.user_name`">
<el-input clearable placeholder="请输入用户名" v-model="row.user_name" />
</el-form-item>
</template>
<template #password="{ row }">
<el-form-item
v-if="row.voucher_type != 1"
:rules="{
required: true,
message: '密码不能为空',
trigger: 'blur',
}"
style="width: 100%"
:prop="`${row.$row_path}.password`">
<el-input clearable placeholder="请输入密码" v-model="row.password" />
</el-form-item>
<el-form-item v-else required style="width: 100%">
<el-input disabled />
</el-form-item>
</template>
<template #action="{ row }">
<bg-table-btn
:click="
() => {
addInputConf(row);
}
"
:disabled="tableRows.length == 5">
新增
</bg-table-btn>
<bg-table-btn
:click="
() => {
removeInputConf(row);
}
"
:disabled="tableRows.length == 1">
删除
</bg-table-btn>
</template>
</bg-table-pro>
</el-form>
</template>
<script setup>
import { ref, reactive, toRefs, watch } from "vue";
import { v4 as uuidv4 } from "uuid";
const props = defineProps({
initTableData: {
default: () => {
return [];
},
},
});
const ruleFormRef = ref(null);
const inputTable = ref(null);
const headers = reactive([
{
label: "IP(IP之间用英文逗号分隔)",
required: true,
prop: "ip",
width: 300,
},
{
label: "端口号(不填写,默认为22)",
prop: "port",
},
{
label: "凭证类型",
required: true,
prop: "voucher_type",
},
{
label: "用户名",
required: true,
prop: "user_name",
},
{
label: "密码",
required: true,
prop: "password",
},
{
label: "操作",
prop: "action",
width: 120,
},
]);
const typeOptions = [
{
value: 0,
label: "密码验证",
},
{
value: 1,
label: "密钥验证",
},
];
const state = reactive({
inputTable,
tableRows: [],
});
const { tableRows } = toRefs(state);
const addInputConf = (row) => {
let tempRow = createRow();
if (row) {
let { index, rows } = getInputRowInfo(row);
rows.splice(index + 1, 0, tempRow);
} else {
state.tableRows = [tempRow];
}
updateInputConfRows();
}; //增加
const updateInputConfRows = () => {
let recursionItems = (items, parentType, parentPath) => {
for (let i = 0; i < items.length; i++) {
let item = items[i];
item.$parent_type = parentType;
item.$row_path = `${parentPath}[${i}]`;
if (item.children && item.children.length) {
let basePath = `${item.$row_path}.children.`;
recursionItems(item.children, item.paramType, basePath);
}
}
};
recursionItems(state.tableRows, "", "");
clearValidate();
}; // 更新 $parent_type 和 $row_path 字段
const clearValidate = () => {
ruleFormRef.value && ruleFormRef.value.clearValidate();
};
const createRow = () => {
return {
id: uuidv4(),
ip: "",
port: "22",
voucher_type: "",
user_name: "",
password: "",
};
};
const getInputRowInfo = (row) => {
return state.inputTable && state.inputTable.getRowInfo(row, `id`);
}; //获取当前行的数据信息
const removeInputConf = (row) => {
let { index, rows } = getInputRowInfo(row);
rows.splice(index, 1);
if (rows.length === 0) {
rows.push(createRow());
}
updateInputConfRows();
}; // 删除
const initTable = () => {
if (props.initTableData && props.initTableData.length >= 1) {
state.tableRows = props.initTableData;
updateInputConfRows();
} else {
addInputConf();
}
};
const changeType = (val, row) => {
if (val == 2) {
row.password = "";
}
};
const getData = () => {
ruleFormRef.value && ruleFormRef.value.validate((valid) => {});
let flag = true;
let list = state.tableRows.map((item) => {
if (
item.ip == "" ||
item.voucher_type === "" ||
item.user_name == "" ||
(item.voucher_type === 0 && item.password == "")
) {
flag = false;
}
return {
ip: item.ip,
port: item.port,
voucher_type: item.voucher_type,
user_name: item.user_name,
password: item.password,
};
});
return {
list,
flag,
};
};
watch(
() => {
return props.initTableData;
},
() => {
initTable();
},
{
immediate: true,
}
);
defineExpose({
getData,
clearValidate,
});
</script>
<style lang="scss" scoped>
.rule-form {
::v-deep(.bg-table .el-form-item .el-form-item__error) {
bottom: -13px;
}
}
</style>
<template>
<div class="my-business-detail">
<div class="breadcrumb">
<bg-breadcrumb />
</div>
<div class="content bg-scroll">
<div class="go-back">
<goBack />
</div>
<gap-title :hasLine="true" title="基本信息"></gap-title>
<div class="info">
<Info :labelData="labelData" :valueData="basicInfo"> </Info>
</div>
<gap-title :hasLine="true" title="主机列表"></gap-title>
<div class="info">
<div class="host-lists">
<bg-table border ref="hostTable" :headers="hostHeaders" :rows="hostRows" height="100%" :isIndex="true">
</bg-table>
</div>
<div style="margin-top: 10px" v-if="fileUrl">
<a download :href="fileUrl">{{ downloadFileFormat(fileUrl) }}</a>
</div>
</div>
<gap-title :hasLine="true" title="任务列表"></gap-title>
<div class="info">
<div class="task-lists">
<div class="table">
<bg-table ref="taskTable" :headers="taskHeaders" :rows="taskRows" :isIndex="true" :stripe="true">
</bg-table>
</div>
<!-- <bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination> -->
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from "vue";
import { useRouter, useRoute } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import Info from "@/components/warn-detail/info.vue";
import gapTitle from "@/components/gap-title.vue";
import goBack from "@/components/go-back/index.vue";
import { downloadFileFormat } from "@/services/helper.js";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
const { $api } = proxy;
const router = useRouter();
const route = useRoute();
const labelData = [
[
{
label: "主机分组名称",
prop: "host_name",
},
],
[
{
label: "任务数量",
prop: "task_cnt",
},
{
label: "IP数量",
prop: "ip_cnt",
},
],
[
{
label: "创建人",
prop: "create_user",
},
{
label: "创建时间",
prop: "create_time",
},
],
];
const basicInfo = ref({
host_name: "",
task_cnt: "",
ip_cnt: "",
create_user: "",
create_time: "",
});
const hostHeaders = [
{
prop: "ip",
label: "IP",
},
{
prop: "port",
label: "端口",
},
];
const hostRows = ref([,]);
const taskHeaders = [
{
prop: "task_name",
label: "任务名称",
},
{
prop: "exec_cnt",
label: "执行次数",
},
{
prop: "task_desc",
label: "描述",
},
];
const taskRows = ref([]);
const filter = ref({
page: 1,
size: 10,
});
const tableTotal = ref(0);
const changePage = (page) => {
filter.value.page = page;
getTableRows();
}; // 改变页码
const changeSize = (size) => {
filter.value.size = size;
changePage(1);
}; // 改变每页条数
const getTableRows = () => {};
const fileUrl = ref("");
const downloadFile = (url) => {
if (url) {
const a = document.createElement("a"); // 创建a标签
a.setAttribute("download", ""); // download属性
a.setAttribute("href", url); // href链接
a.click(); // 自执行点击事件
}
};
const getHostManageDetail = () => {
$api.autoMaintenance.getHostManageDetail(route.query.id).then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
// 基本信息
basicInfo.value.host_name = data.host_name;
basicInfo.value.task_cnt = data.task_cnt;
basicInfo.value.ip_cnt = data.ip_cnt;
basicInfo.value.create_user = data.create_user;
basicInfo.value.create_time = data.create_time.split("+")[0].replace("T", " ").replace("Z", " ");
// 主机列表
hostRows.value = data.host_list || [];
fileUrl.value = data.host_file_url;
// 任务列表
taskRows.value = data.task_list || [];
} else {
ElMessage.error(res.data.data);
}
});
};
onMounted(() => {
getHostManageDetail();
});
</script>
<style lang="scss" scoped>
.my-business-detail {
width: 100%;
height: 100%;
padding: 0 24px 16px;
.breadcrumb {
width: 100%;
height: 46px;
}
.content {
width: 100%;
height: calc(100% - 46px);
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
padding: 24px;
.go-back {
margin-bottom: 24px;
}
:deep(.gap-title) {
margin-bottom: 16px;
}
.info,
.feedback-info {
max-width: 1072px;
width: 100%;
padding: 0 8px 0;
&:not(:last-child) {
padding-bottom: 24px;
}
.status {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 8px;
$statusObj: (
finish: #48ad97,
close: #9e9e9e,
info: #3759be,
);
@each $status, $color in $statusObj {
&-#{$status} {
background-color: $color;
}
}
}
.status-body {
display: flex;
align-items: center;
}
.host-lists {
margin-top: 16px;
}
.task-lists {
margin-top: 16px;
overflow: hidden;
padding-bottom: 10px;
}
}
}
}
</style>
......@@ -5,7 +5,7 @@
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="primary" @click="register">
<el-button type="primary" @click="add">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新增
</el-button>
......@@ -22,8 +22,8 @@
<span class="filter_title">创建时间</span>
<el-date-picker
v-model="filter.time"
type="daterange"
value-format="yyyy-MM-DD"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期" />
......@@ -45,136 +45,72 @@
:isIndex="true"
:select="true"
:stripe="true">
<template v-slot:name="{ row }">
<span class="can_click_text" @click="getChildren(row)">
{{ row.name }}
<template v-slot:host_name="{ row }">
<span class="can_click_text" @click="goToDetail(row)">
{{ row.host_name }}
</span>
</template>
<template v-slot:ipNumber="{ row }">
<span> {{ row.name }}/{{ row.name }} </span>
<template v-slot:ip_number="{ row }">
<span> {{ row.ip_cnt_err }}/{{ row.ip_cnt }} </span>
</template>
<template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
<template v-slot:create_time="{ row }">
{{ row.create_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :tableData="tableRows">
<bg-table-btn @click="editRow(row)">编辑</bg-table-btn>
<bg-table-btn @click="checkRow(row)">状态检测</bg-table-btn>
<bg-table-btn @click="exportRow(row, 1)">导出异常</bg-table-btn>
<bg-table-btn @click="deleteRow(row, 2)">删除</bg-table-btn>
<bg-table-btn :disabled="row.ip_cnt_err == 0" @click="exportRow(row)">导出异常</bg-table-btn>
<bg-table-btn @click="deleteRow(row)">删除</bg-table-btn>
</bg-table-btns2>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:size="filter.page_size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
<!-- 新增/编辑弹窗 -->
<!-- <el-dialog
class="dialog_box"
:title="addType == 1 ? '新增' : '编辑'"
v-model="addDialog"
width="758px">
<el-form ref="bgForm" :model="formData" :rules="rules" label-width="80px" class="bg_form">
<el-form-item label="名称" prop="name">
<el-input
v-model.trim="formData.name"
show-word-limit
:maxlength="
nodeClassifyId == 'eb9c7d70-c123-42b7-8e61-dde1b022b669'
? 6
: nodeClassifyId == 'efd9ec3b-7f18-49e2-9d88-bcca022243bb'
? 4
: nodeClassifyId == '949a1138-4995-464e-97a9-424d097eb271'
? 2
: 20
"
placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="描述" prop="describe">
<el-input
v-model="formData.describe"
type="textarea"
:autosize="{ minRows: 5 }"
show-word-limit
maxlength="200"
resize="vertical"
placeholder="请输入描述"></el-input>
</el-form-item>
<el-form-item label="是否启用" prop="state" style="margin-bottom: 0px">
<el-switch
class="bg-switch-ele"
v-model="formData.state"
:active-value="1"
:inactive-value="0"
inline-prompt
active-text="是"
inactive-text="否" />
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="addDialog = false">取 消</el-button>
<el-button type="primary" @click="addConfirm">保 存</el-button>
</div>
</template>
</el-dialog> -->
<!-- 删除弹窗 -->
<!-- <el-dialog
class="dialog_box"
title="提示"
v-model="dialogDelete"
width="400px"
:before-close="
() => {
dialogDelete = false;
}
">
<div>确定要删除此字典值吗?</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="dialogDelete = false">取 消</el-button>
<el-button type="primary" @click="deleteData">确 定</el-button>
</div>
</template>
</el-dialog> -->
<checkStatusDialog v-model="checkStatusVisible" :enter="0" :checkStatusData="checkStatusData"></checkStatusDialog>
</div>
</template>
<script setup>
import { reactive, ref, onBeforeMount, toRefs, computed, watch, nextTick, watchEffect } from "vue";
import { reactive, ref, onBeforeMount, toRefs, getCurrentInstance, watch } from "vue";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { Search } from "@element-plus/icons-vue";
import { useRouter, useRoute } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const bgForm = ref(null);
import checkStatusDialog from "./components/check-status-dialog.vue";
const { proxy } = getCurrentInstance();
const { $api } = proxy;
const router = useRouter();
const route = useRoute();
const dataTable = ref(null);
const headers = [
{
label: "主机分组名称",
prop: "name",
prop: "host_name",
},
{
label: "IP数量(异常/全部)",
prop: "ipNumber",
prop: "ip_number",
},
{
label: "任务数量",
prop: "workTimes",
prop: "task_cnt",
},
{
label: "创建人",
prop: "person",
prop: "create_user",
},
{
label: "创建时间",
prop: "updated_time",
prop: "create_time",
width: 220,
},
{
......@@ -186,12 +122,6 @@ const headers = [
];
const state = reactive({
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数
......@@ -199,41 +129,8 @@ const state = reactive({
time: "",
search: "",
page: 1,
limit: 10,
page_size: 10,
}, // 表格筛选项
stateOptions: [
{
name: "全部",
value: "",
},
{
name: "启用",
value: "1",
},
{
name: "禁用",
value: "0",
},
], // 启用禁用
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
p_dict_id: "",
},
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" }],
},
fatherRow: null,
});
const selectRows = (data) => {
......@@ -244,39 +141,93 @@ const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const deleteAllTips = () => {
if (state.selected.length == 0) {
return ElMessage.warning("请选择数据");
}
let data = {
id: state.selected.map((item) => {
return item.id;
}),
};
$api.autoMaintenance.deleteHostManage(data).then((res) => {
if (res.data.code == 200) {
ElMessage.success("删除成功");
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
};
const dictLevel = ref(1);
const exportRow = (row) => {
let params = {
detection_type: 1,
id: row.id,
};
ElMessage.success("开始导出");
let url = `/v1/api/automated_mainten/host_manage/export?`;
const paramsArray = [];
for (const [key, value] of Object.entries(params)) {
paramsArray.push(`${key}=${value}`);
}
url += paramsArray.join("&");
const getChildren = (row) => {
dictLevel.value = 2;
state.tableRows = row.children || [];
state.tableTotal = row.total_children;
state.fatherRow = row;
const a = document.createElement("a");
const event = new MouseEvent("click");
a.href = url;
a.dispatchEvent(event);
};
const deleteRow = (row) => {
let data = {
id: [row.id],
};
$api.autoMaintenance.deleteHostManage(data).then((res) => {
if (res.data.code == 200) {
ElMessage.success("删除成功");
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
};
const getTypeList = () => {
let params = {
name: state.typeKeyword,
const editRow = (row) => {
router.push({
path: "/auto-maintenance/host-manage/edit",
query: {
id: row.id,
},
});
};
const checkStatusVisible = ref(false);
const checkStatusData = ref({});
const checkRow = (row) => {
checkStatusData.value = {
host_name: row.host_name,
detection_type: 1,
id: row.id,
};
axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params })
.then((res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null;
state.nodeId = state.typeList[0].id || null;
if (state.nodeId) {
getTableRows();
}
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
}; // 获取字典分类
checkStatusVisible.value = true;
};
watch(
() => checkStatusVisible.value,
(val) => {
if (!val) {
getTableRows();
}
}
);
const goToDetail = (row) => {
router.push({
path: "/auto-maintenance/host-manage/detail",
query: {
id: row.id,
},
});
};
const changeSearch = (val) => {
state.filter.search = val;
......@@ -291,7 +242,7 @@ const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page_size: 10,
page: 1,
};
changePage(1);
......@@ -299,70 +250,40 @@ const filterClear = () => {
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) {
let data = res.data.data || [];
if (dictLevel.value == 1) {
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
let row = data.filter((e) => {
return e.dict_id == state.fatherRow.dict_id;
});
state.tableRows = row[0].children;
state.tableTotal = row[0].total_children;
}
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);
}
});
if (params.time) {
params.create_date_from = params.time[0];
params.create_date_to = params.time[1];
}
delete params.time;
$api.autoMaintenance.getHostManageList(params).then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取表格数据
const changePage = (page) => {
state.filter.page = page;
clearSelected();
getTableRows();
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
state.filter.page_size = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
p_dict_id: state.fatherRow ? state.fatherRow.dict_id : "",
};
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
const add = () => {
router.push("/auto-maintenance/host-manage/add");
}; // 新增字典按钮
onBeforeMount(() => {
getTypeList();
getTableRows();
});
const { tableRows, tableTotal, filter } = toRefs(state);
......@@ -371,7 +292,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
......@@ -400,9 +320,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
......
......@@ -5,20 +5,29 @@
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入关键字"> </bg-filter-group>
<div class="table_container">
<div class="table bg-scroll">
<bg-table ref="dataTable" :headers="headers" :rows="tableRows" :stripe="true">
<template v-slot:name="{ row }">
<span class="can_click_text" @click="getChildren(row)">
{{ row.name }}
<bg-table :headers="headers" :rows="tableRows" :stripe="true">
<template v-slot:task_name="{ row }">
<span class="can_click_text" @click="gotoPage(row)">
{{ row.task_name }}
</span>
</template>
<template v-slot:state="{ row }">
<span> 执行中 </span>
<span>
<bg-icon
:style="{
color: ['#2b4695', '#429e8a', '#d75138'][row.state],
}"
:icon="
['#bg-ic-s-circle-restart', '#bg-ic-s-circle-check', '#bg-ic-s-circle-close'][row.state]
"></bg-icon>
{{ ["执行中", "成功", "失败"][row.state] }}
</span>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:size="filter.page_size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
......@@ -39,8 +48,6 @@ import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const router = useRouter();
const route = useRoute();
const bgForm = ref(null);
const dataTable = ref(null);
const headers = [
{
label: "状态",
......@@ -48,92 +55,34 @@ const headers = [
},
{
label: "任务名称",
prop: "name",
prop: "task_name",
},
{
label: "执行耗时",
prop: "workTime",
label: "执行耗时(s)",
prop: "exec_time",
},
{
label: "操作人",
prop: "person",
prop: "create_user",
},
];
const state = reactive({
bgForm,
typeList: [], // 分类数据
typeKeyword: "", // 分类删选关键词
nodeClassifyId: null, // 当前选中分类的uuid 用于新增字典
nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器
tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数
filter: {
time: "",
search: "",
page: 1,
limit: 10,
page_size: 10,
}, // 表格筛选项
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
addType: 0, //
addDialog: false,
formData: {
name: "",
describe: "",
state: 1,
p_dict_id: "",
},
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" }],
},
fatherRow: null,
});
const selectRows = (data) => {
state.selected = data.selection;
};
const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const getChildren = (row) => {
router.push(`/auto-maintenance/task-history/list`);
const gotoPage = (row) => {
router.push(`/auto-maintenance/task-history/list?id=${row.task_id}`);
};
const getTypeList = () => {
let params = {
name: state.typeKeyword,
};
axios
.get(`/apaas/system/v5/dictionary/classify/list`, { params })
.then((res) => {
if (res.data.code == 200) {
state.typeList = res.data.data || [];
state.nodeClassifyId = state.typeList[0].classify_id || null;
state.nodeId = state.typeList[0].id || null;
if (state.nodeId) {
getTableRows();
}
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
}; // 获取字典分类
const changeSearch = (val) => {
state.filter.search = val;
changePage(1);
......@@ -145,9 +94,8 @@ const filterAction = () => {
const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page_size: 10,
page: 1,
};
changePage(1);
......@@ -155,9 +103,8 @@ const filterClear = () => {
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
axios
.get(`/apaas/system/v5/dictionary/list`, {
.get(`/v1/api/automated_mainten/task_history/list`, {
params,
})
.then((res) => {
......@@ -177,32 +124,12 @@ const changePage = (page) => {
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
state.filter.page_size = size;
changePage(1);
}; // 改变每页条数
const register = () => {
state.formData = {
name: "",
describe: "",
state: 1,
p_dict_id: state.fatherRow ? state.fatherRow.dict_id : "",
};
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 1;
state.addDialog = true;
}; // 新增字典按钮
onBeforeMount(() => {
getTypeList();
getTableRows();
});
const { tableRows, tableTotal, filter } = toRefs(state);
......@@ -211,7 +138,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
......@@ -240,9 +166,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
......
......@@ -17,19 +17,31 @@
<div class="table_container">
<div class="table bg-scroll">
<bg-table ref="dataTable" :headers="headers" :rows="tableRows" :stripe="true">
<template v-slot:desc="{ row }">
<template v-slot:exec_start_time="{ row }">
<span>{{ dateStringTransform(row.exec_start_time) }}</span>
</template>
<template v-slot:exec_desc="{ row }">
<span class="can_click_text" @click="gotoPage(`/auto-maintenance/task-history/list/record?id=${row.id}`)">
{{ row.desc }}
{{ row.exec_desc }}
</span>
</template>
<template v-slot:state="{ row }">
<span> 执行中 </span>
<span>
<bg-icon
:style="{
color: ['#2b4695', '#429e8a', '#d75138'][row.state],
}"
:icon="
['#bg-ic-s-circle-restart', '#bg-ic-s-circle-check', '#bg-ic-s-circle-close'][row.state]
"></bg-icon>
{{ ["执行中", "成功", "失败"][row.state] }}
</span>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:size="filter.page_size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
......@@ -46,6 +58,7 @@ import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import { dateStringTransform, downloadFile } from "@/services/helper.js";
const router = useRouter();
const route = useRoute();
......@@ -58,19 +71,19 @@ const headers = [
},
{
label: "执行说明",
prop: "desc",
prop: "exec_desc",
},
{
label: "执行开始时间",
prop: "begin",
prop: "exec_start_time",
},
{
label: "执行耗时",
prop: "workTime",
label: "执行耗时(s)",
prop: "exec_time",
},
{
label: "操作人",
prop: "person",
prop: "create_user",
},
];
......@@ -85,7 +98,7 @@ const state = reactive({
filter: {
search: "",
page: 1,
limit: 10,
page_size: 10,
}, // 表格筛选项
actionRow: null, // 当前操作的数据
});
......@@ -100,10 +113,12 @@ const changeSearch = (val) => {
}; // 表格关键字筛选
const getTableRows = () => {
let params = { ...state.filter };
params.id = state.nodeId;
let params = {
...state.filter,
task_id: route.query.id,
};
axios
.get(`/apaas/system/v5/dictionary/list`, {
.get(`/v1/api/automated_mainten/task_history/task_info_list`, {
params,
})
.then((res) => {
......@@ -123,11 +138,13 @@ const changePage = (page) => {
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
state.filter.page_size = size;
changePage(1);
}; // 改变每页条数
onBeforeMount(() => {});
onBeforeMount(() => {
getTableRows();
});
const { tableRows, tableTotal, filter } = toRefs(state);
</script>
......@@ -135,7 +152,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
......@@ -163,10 +179,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
.table_container {
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
......
......@@ -7,7 +7,7 @@
执行ping命令 / 执行说明1
</div>
<div class="middle-container">
<finish-use :state="true" height="calc(100vh - 330px)" time="00:00:11"></finish-use>
<finish-use :state="true" height="calc(100vh - 330px)" :codes="state.logArr" :time="state.time"></finish-use>
</div>
<div class="bottom-container">
<el-button class="use-script" type="primary" @click="router.go(-1)"> 重新执行 </el-button>
......@@ -22,10 +22,29 @@ import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import finishUse from "@/page/main/auto-maintenance/task-manage/add/finish-use.vue";
import axios from "@/request/http.js";
import { secondeToHour } from "@/services/helper.js";
const router = useRouter();
const route = useRoute();
const state = reactive({ data: 1 });
const { data } = toRefs(state);
const state = reactive({
time: "",
logArr: [],
});
const getLog = () => {
axios.get(`/v1/api/automated_mainten/task_history/task_exec_log?id=${route.query.id}`).then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
state.time = secondeToHour(data.exec_time);
state.logArr = data.exec_log.split("\n");
}
});
};
onBeforeMount(() => {
getLog();
});
</script>
<style lang="scss" scoped>
......
......@@ -2,7 +2,12 @@
<div>
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-position="top" label-width="120px">
<el-form-item label="任务名称" prop="name">
<el-input v-model="state.ruleForm.name" maxlength="20" placeholder="请输入任务名称" show-word-limit />
<el-input
v-model="state.ruleForm.name"
maxlength="20"
:disabled="props.isEdit"
placeholder="请输入任务名称"
show-word-limit />
</el-form-item>
<el-form-item label="任务描述" prop="desc">
<el-input
......@@ -31,6 +36,10 @@ const props = defineProps({
type: Object,
default: () => {},
},
isEdit: {
type: Boolean,
default: false,
},
});
const ruleFormRef = ref(null);
......
......@@ -13,9 +13,9 @@
</div>
<div class="log-bg bg-scroll" :style="{ height: props.height }">
<div class="log-box">
<div v-for="(item, i) in stateData.codes" :key="i" class="codes-box">
<span class="codes-num">{{ item.pos + 1 }}</span>
<span class="codes-out" v-html="item.out"></span>
<div v-for="(item, i) in props.codes" :key="i" class="codes-box">
<span class="codes-num">{{ i + 1 }}</span>
<span class="codes-out" v-html="item"></span>
</div>
</div>
</div>
......@@ -26,6 +26,8 @@
import { reactive, ref, onBeforeMount, toRefs } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import axios from "@/request/http.js";
const router = useRouter();
const route = useRoute();
......@@ -47,119 +49,6 @@ const props = defineProps({
default: "",
},
});
const stateData = reactive({
codes: [
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
{
pos: 0,
out: "SSH password:",
},
{
pos: 1,
out: "[WARNING]: Platform darwin on host 192.168.1.199 is using the discovered Pythoninterpreter at /usr/bin/python3, but future installation of another Pythoninterpreter could change ",
},
{
pos: 2,
out: "the meaning of that path. See",
},
{
pos: 3,
out: "https://docs.ansible.com/ansible-",
},
],
});
</script>
<style lang="scss" scoped>
......
......@@ -2,11 +2,11 @@
<div class="step-container">
<div class="step-base">
<img src="@/assets/imgs/img_data-complete.png" />
<p class="tips" v-if="props.state">新增成功</p>
<p class="tips" v-else>新增失败</p>
<p class="tips" v-if="props.state">{{ ["新增", "编辑", "复制"][props.finishType] }}成功</p>
<p class="tips" v-else>{{ ["新增", "编辑", "复制"][props.finishType] }}失败</p>
<div class="apaas_button btns" v-if="props.state">
<el-button type="default" @click="goToList"> 返回列表 </el-button>
<el-button type="primary" @click="goStepOne"> 继续新增 </el-button>
<el-button type="primary" @click="goStepOne"> {{ props.finishType == 1 ? "重新提交" : "继续新增" }} </el-button>
</div>
</div>
</div>
......@@ -24,6 +24,10 @@ const props = defineProps({
type: Boolean,
default: true,
},
finishType: {
type: Number,
default: 0,
},
});
const emit = defineEmits(["clear"]);
......
......@@ -42,10 +42,28 @@
<div
class="content_main log_content_nor"
:style="step == 3 && state.isSave ? { height: 'calc(100vh - 234px)' } : {}">
<base-info v-show="step == 1" :data="state.data" ref="baseInfoRef"></base-info>
<use-content v-show="step == 2" :data="state.data" ref="useContentRef"></use-content>
<finish v-show="step == 3 && state.isSave" :state="true" @clear="clearData"></finish>
<finish-use v-show="step == 3 && !state.isSave" :state="true" time="00:00:11"></finish-use>
<base-info
v-show="step == 1"
v-if="state.loadComponents"
:isEdit="state.pageType == 1"
:data="state.data"
ref="baseInfoRef"></base-info>
<use-content
v-show="step == 2"
v-if="state.loadComponents"
:data="state.data"
ref="useContentRef"></use-content>
<finish
v-show="step == 3 && state.isSave"
:state="state.status"
:finishType="state.pageType"
v-if="state.loadComponents"
@clear="clearData"></finish>
<finish-use
v-show="step == 3 && !state.isSave"
v-if="state.loadComponents"
:state="state.status"
time="00:00:11"></finish-use>
</div>
<div class="content_foot apaas_button" v-if="step == 1 || step == 2 || (step == 3 && !state.isSave)">
<el-button type="default" v-if="step == 1 || step == 2" @click="cancel"> 取消 </el-button>
......@@ -104,6 +122,9 @@ const state = reactive({
useData: ["yaml", "json"],
useText: "",
isSave: true,
status: true,
pageType: 0, //0新增,1编辑,2复制
loadComponents: false, //控制子组件的加载
});
const cancel = () => {
......@@ -131,11 +152,55 @@ const saveTask = async () => {
.save()
.then(() => {
step.value = 3;
//todo:掉接口保存,并获取状态
if (state.pageType == 0 || state.pageType == 2) {
postTask();
} else if (state.pageType == 1) {
editTask();
}
})
.catch(() => {});
};
const editTask = () => {
axios
.put(`/v1/api/automated_mainten/task_manage/edit`, {
task_name: state.data.name,
task_desc: state.data.desc,
yaml_desc: state.data.useText,
yaml_url: JSON.stringify(state.data.doc_file),
host_group_id: state.data.pcName,
})
.then((res) => {
if (res.data.code == 200) {
state.status = true;
ElMessage.success("保存成功");
} else {
state.status = false;
ElMessage.error(res.data.msg);
}
});
};
const postTask = () => {
axios
.post(`/v1/api/automated_mainten/task_manage/add`, {
task_name: state.data.name,
task_desc: state.data.desc,
yaml_desc: state.data.useText,
yaml_url: JSON.stringify(state.data.doc_file),
host_group_id: state.data.pcName,
})
.then((res) => {
if (res.data.code == 200) {
state.status = true;
ElMessage.success("保存成功");
} else {
state.status = false;
ElMessage.error(res.data.msg);
}
});
};
const useScript = async () => {
//填写完成才可以进行执行
await useContentRef.value
......@@ -167,9 +232,53 @@ const clearData = () => {
useContentRef.value.clear();
state.data = {};
step.value = 1;
state.loadComponents = false;
init();
};
onBeforeMount(() => {});
const getDetails = () => {
axios
.get(`/v1/api/automated_mainten/task_manage/details`, {
params: {
id: route.query.id,
},
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
state.data = {
name: data.task_name,
desc: data.task_desc,
useText: data.yaml_desc,
doc_file: data.yaml_url ? JSON.parse(data.yaml_url) : [],
pcName: data.host_group_id,
};
//复制,名字置空
if (state.pageType == 2) {
state.data.name = "";
}
state.loadComponents = true;
}
});
};
const init = () => {
if (route.path.indexOf("edit") > -1) {
state.pageType = 1;
} else if (route.path.indexOf("copy") > -1) {
state.pageType = 2;
}
if (state.pageType !== 0) {
getDetails();
} else {
state.loadComponents = true;
}
};
onBeforeMount(() => {
state.loadComponents = false;
init();
});
</script>
<style scoped>
......
......@@ -17,9 +17,9 @@
<el-form ref="pcFormRef" :model="state.ruleForm" :rules="state.rules" label-position="top" label-width="120px">
<el-form-item label="主机分组名称" prop="pcName" style="width: 1100px">
<el-select v-model="state.ruleForm.pcName" style="width: 1020px" clearable placeholder="请选择">
<el-option v-for="item in state.options" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in state.options" :key="item.id" :label="item.host_name" :value="item.id" />
</el-select>
<span class="add-pc can_click_text">去创建</span>
<span class="add-pc can_click_text" @click="gotoPage(`/auto-maintenance/host-manage/add`)">去创建</span>
</el-form-item>
</el-form>
</div>
......@@ -28,6 +28,7 @@
<script setup>
import { reactive, ref, onBeforeMount, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const router = useRouter();
const route = useRoute();
......@@ -52,14 +53,13 @@ const state = reactive({
rules: {
pcName: [{ required: true, message: "请选择主机分组", trigger: "change" }],
},
options: [
{
label: "12",
value: "qwqw",
},
],
options: [],
});
const gotoPage = (url) => {
router.push(url);
};
const save = () => {
return new Promise((resolve, reject) => {
pcFormRef.value.validate((valid, fields) => {
......@@ -67,7 +67,9 @@ const save = () => {
props.data.pcName = state.ruleForm.pcName;
if (state.useType == 0) {
props.data.useText = state.useText;
props.data.doc_file = [];
} else {
props.data.useText = "";
props.data.doc_file = state.doc_file;
}
resolve();
......@@ -86,17 +88,26 @@ const clear = () => {
state.useType = 0;
};
const getPC = () => {
axios.get(`/v1/api/automated_mainten/host_manage/list`).then((res) => {
if (res.data.code == 200) {
state.options = res.data.data || [];
}
});
};
onMounted(() => {
if (
(props.data && props.data.useText == "" && props.data.doc_file.length == 0) ||
(!props.data.useText && !props.data.doc_file)
) {
state.useType = 0;
} else if (props.data && props.data.useText !== "") {
} else if (props.data && props.data.useText == "") {
state.useType = 1;
} else if (props.data && props.data.doc_file.length == 0) {
state.useType = 0;
}
getPC();
});
defineExpose({
......
......@@ -3,19 +3,15 @@
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<bg-form-gap title="基本信息"></bg-form-gap>
<bg-detail-table2 style="width: 1076px" :list="state.baseInfo">
<template #status>
<span> <i class="use"></i> 启用 </span>
</template>
</bg-detail-table2>
<bg-detail-table2 style="width: 1076px; margin-bottom: 20px" :list="state.baseInfo"> </bg-detail-table2>
<bg-form-gap title="执行脚本"></bg-form-gap>
<div style="height: 260px; margin-bottom: 20px; width: 1076px">
<bg-code-editor v-model="state.useText"></bg-code-editor>
<div v-if="state.docFile.length == 0" style="height: 260px; margin-bottom: 20px; width: 1076px">
<bg-code-editor :disabled="true" v-model="state.useText"></bg-code-editor>
</div>
<div class="file-box">
<bg-icon icon="#bg-ic-c-file-data"></bg-icon>&nbsp;&nbsp; 文件.yml
<el-button type="primary" @click="downloadFile(url)"
<div class="file-box" v-for="(item, index) in state.docFile">
<bg-icon icon="#bg-ic-c-file-data"></bg-icon>&nbsp;&nbsp; {{ item.name }}
<el-button type="primary" @click="download(item.url, item.name)"
><bg-icon icon="#bg-ic-to-bottom"></bg-icon>&nbsp;&nbsp;下载</el-button
>
</div>
......@@ -38,9 +34,20 @@
<bg-table style="width: 1076px" :headers="state.historyHeaders" :rows="state.historyTableRows" :stripe="true">
<template v-slot:state="{ row }">
<span>
{{ row.state }}
<bg-icon
:style="{
color: ['#2b4695', '#429e8a', '#d75138'][row.state],
}"
:icon="
['#bg-ic-s-circle-restart', '#bg-ic-s-circle-check', '#bg-ic-s-circle-close'][row.state]
"></bg-icon>
{{ ["执行中", "成功", "失败"][row.state] }}
</span>
</template>
<template v-slot:exec_start_time="{ row }">
<span>{{ dateStringTransform(row.exec_start_time) }}</span>
</template>
</bg-table>
<div style="width: 1076px" v-if="state.tableTotal > 10">
<bg-pagination
......@@ -60,45 +67,43 @@ import { reactive, ref, onBeforeMount, toRefs } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
import axios from "@/request/http.js";
import { dateStringTransform, downloadFile } from "@/services/helper.js";
const router = useRouter();
const route = useRoute();
const state = reactive({
baseInfo: [
{
label: "预警规则名称",
value: "服务中断推送规则1",
label: "任务名称",
value: "",
},
{
label: "启用状态",
value: "启用",
childSlot: "status",
label: "执行次数",
value: "",
},
{
label: "预警对象",
value: "容器云",
label: "执行成功次数",
value: "",
},
{
label: "预警分类",
value: "容器集群",
label: "执行失败次数",
value: "",
},
{
label: "创建人",
value: "admin",
value: "",
},
{
label: "创建时间",
value: "2023-08-19 23:22:22",
value: "",
},
{
label: "更新时间",
value: "2023-08-19 23:22:22",
},
{
label: "预警指标",
value: "CPU使用率",
label: "任务描述",
value: "",
},
],
useText: "",
docFile: [],
historyHeaders: [
{
label: "状态",
......@@ -106,19 +111,19 @@ const state = reactive({
},
{
label: "执行说明",
prop: "desc",
prop: "exec_desc",
},
{
label: "执行开始时间",
prop: "begin",
prop: "exec_start_time",
},
{
label: "执行耗时",
prop: "time",
label: "执行耗时(s)",
prop: "exec_time",
},
{
label: "操作人",
prop: "person",
prop: "create_user",
},
],
historyTableRows: [],
......@@ -129,38 +134,77 @@ const state = reactive({
tableTotal: 0,
pcHeaders: [
{
label: "账号",
prop: "account",
label: "IP",
prop: "ip",
},
{
label: "端口",
prop: "port",
},
],
pcTableRows: [
{
account: "asasdd",
port: "8080",
},
{
account: "asasdd",
port: "8080",
},
],
pcTableRows: [],
});
const downloadFile = () => {};
const download = (url, name) => {
downloadFile(url, name);
};
const changePage = (page) => {
state.filter.page = page;
getTableRows();
};
const changeSize = (size) => {
state.filter.limit = size;
state.filter.size = size;
changePage(1);
};
const getTableRows = () => {};
const getTableRows = () => {
axios
.get(`/v1/api/automated_mainten/task_history/task_info_list`, {
params: {
task_id: route.query.id,
page: state.filter.page,
page_size: state.filter.size,
},
})
.then((res) => {
if (res.data.code == 200) {
state.historyTableRows = res.data.data;
state.tableTotal = res.data.total;
}
});
};
const getDetails = () => {
axios
.get(`/v1/api/automated_mainten/task_manage/details`, {
params: {
id: route.query.id,
},
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data;
state.baseInfo[0].value = data.task_name;
state.baseInfo[1].value = data.exec_cnt;
state.baseInfo[2].value = data.success_cnt;
state.baseInfo[3].value = data.fail_cnt;
state.baseInfo[4].value = data.create_user;
state.baseInfo[5].value = data.create_time.split("+")[0].replace("T", " ").replace("Z", " ");
state.baseInfo[6].value = data.task_desc;
state.useText = data.yaml_desc;
state.docFile = data.yaml_url ? JSON.parse(data.yaml_url) : [];
state.pcTableRows = data.host_list || [];
}
});
};
onBeforeMount(() => {
getDetails();
getTableRows();
});
</script>
<style lang="scss" scoped>
......
......@@ -11,7 +11,7 @@
</el-button>
<el-button type="default" @click="deleteAllTips"> 批量删除 </el-button>
<span class="header_info"
>已选择 <span style="color: #202531; font-weight: bold"> {{ state.selected.length }} </span>
>已选择 <span style="color: #202531; font-weight: bold"> {{ state.selectedNum }} </span>
</span>
<span class="header_info can_click_text" @click="clearSelected">清空</span>
</div>
......@@ -23,7 +23,7 @@
<el-date-picker
v-model="filter.time"
type="daterange"
value-format="yyyy-MM-DD"
value-format="YYYY-MM-DD"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期" />
......@@ -45,13 +45,13 @@
:isIndex="true"
:select="true"
:stripe="true">
<template v-slot:name="{ row }">
<template v-slot:task_name="{ row }">
<span class="can_click_text" @click="gotoPage(`/auto-maintenance/task-manage/detail?id=${row.id}`)">
{{ row.name }}
{{ row.task_name }}
</span>
</template>
<template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
<template v-slot:create_time="{ row }">
{{ row.create_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template>
<template v-slot:action="{ row }">
<bg-table-btns2 :limit="3" :tableData="tableRows">
......@@ -65,7 +65,7 @@
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:size="filter.page_size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
......@@ -128,25 +128,26 @@ const dataTable = ref(null);
const headers = [
{
label: "任务名称",
prop: "name",
prop: "task_name",
width: 200,
},
{
label: "执行次数",
prop: "times",
prop: "exec_cnt",
},
{
label: "描述",
prop: "describe",
minWidth: 360,
prop: "task_desc",
minWidth: 300,
},
{
label: "创建人",
prop: "person",
prop: "create_user",
},
{
label: "创建时间",
prop: "updated_time",
width: 220,
prop: "create_time",
width: 180,
},
{
label: "操作",
......@@ -157,28 +158,22 @@ const headers = [
];
const state = reactive({
tableRows: [
{
name: 23123,
times: 1,
describe: 12313,
person: 21323,
updated_time: "2021-01-01+TZ",
},
], // 表格数据
tableRows: [], // 表格数据
selected: [], //选择数据
selectedNum: 0, //选择数据数量
tableTotal: 0, // 表格数据条数
filter: {
time: "",
search: "",
page: 1,
limit: 10,
page_size: 10,
}, // 表格筛选项
actionRow: null, // 当前操作的数据
dialogDelete: false, // 删除弹窗
useScriptShow: false,
useType: 0,
useData: ["yaml", "json"],
deleteType: 0, //0单个删除,1批量删除
});
const useRow = (row) => {
......@@ -197,13 +192,38 @@ const confirmUse = () => {
const deleteRow = (row) => {
state.actionRow = row;
state.dialogDelete = true;
state.deleteType = 0;
};
const deleteData = () => {
state.dialogDelete = false;
let ids = [];
if (state.deleteType == 0) {
ids = [state.actionRow.id];
} else {
let dealData = dataTable.value.dealSelectData();
for (const key in dealData) {
ids.push(dealData[key].id);
}
}
axios
.delete(`/v1/api/automated_mainten/task_manage/del`, {
data: {
id: ids,
},
})
.then((res) => {
if (res.data.code == 200) {
ElMessage.success("删除成功");
changePage(1);
} else {
ElMessage.error(res.data.msg);
}
});
};
const selectRows = (data) => {
state.selectedNum = data.allLength;
state.selected = data.selection;
};
......@@ -214,6 +234,7 @@ const clearSelected = () => {
const deleteAllTips = () => {
if (state.selected.length > 0) {
state.dialogDelete = true;
state.deleteType = 1;
} else {
ElMessage.error("请先选择要删除任务");
}
......@@ -236,21 +257,30 @@ const filterClear = () => {
state.filter = {
time: "",
search: "",
limit: 10,
page: 1,
page_size: 10,
};
changePage(1);
}; // 重置筛选项
const getTableRows = () => {
let params = { ...state.filter };
if (params.time) {
params.create_date_from = params.time[0];
params.create_date_to = params.time[1];
} else {
params.create_date_from = "";
params.create_date_to = "";
}
axios
.get(`/apaas/system/v5/dictionary/list`, {
.get(`/v1/api/automated_mainten/task_manage/list`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
let data = res.data.data || [];
state.tableRows = data;
state.tableTotal = res.data.total;
} else {
ElMessage.error(res.data.data);
}
......@@ -263,11 +293,13 @@ const changePage = (page) => {
}; // 改变页码
const changeSize = (size) => {
state.filter.limit = size;
state.filter.page_size = size;
changePage(1);
}; // 改变每页条数
onBeforeMount(() => {});
onBeforeMount(() => {
getTableRows();
});
const { tableRows, tableTotal, filter } = toRefs(state);
</script>
......@@ -275,7 +307,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
<style lang="scss" scoped>
.detail_container {
width: 100%;
height: calc(100vh - 56px);
padding: 0 24px;
min-height: 100%;
display: flex;
......@@ -304,9 +335,6 @@ const { tableRows, tableTotal, filter } = toRefs(state);
height: calc(100% - 70px);
width: 100%;
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
}
......
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="directoryForm"
:rules="directoryFormRules"
ref="directoryRef"
style="max-width: 80%">
<el-form-item label="上级目录" prop="p_organization_id" v-if="formType === 'create'">
<el-tree-select
v-model="directoryForm.p_organization_id"
:data="orgData"
:props="treeProps"
:render-after-expand="false"
:check-strictly="true"
:disabled="directoryForm.level"
style="width: 80%" />
<el-form-item label="" style="padding-left: 16px">
<el-checkbox v-model="directoryForm.level" @change="isTop" label="顶级" />
</el-form-item>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="directoryForm.name" />
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted, onBeforeMount, nextTick } from "vue";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const props = defineProps({
formType: {
type: String,
default: "create", //false 新增 true 编辑
},
});
const directoryForm = reactive({
p_organization_id: "",
name: "",
level: false,
});
const directoryFormRules = reactive({
p_organization_id: [{ required: true, message: "请输入上级目录", trigger: "blur" }],
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
});
const directoryRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!directoryRef) return;
await directoryRef.value.validate((valid, fields) => {
if (valid) {
emit("action", directoryForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!directoryRef) return;
directoryRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(directoryForm, data);
};
const orgData = ref([]);
const treeProps = {
label: "name",
children: "Child",
value: "organization_id",
disabled: "disabled",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
orgDataTemp.shift();
orgData.value = filterOrg(orgDataTemp);
} else {
ElMessage.error(res.data.data);
}
});
};
const filterOrg = (data) => {
if (data.length > 0) {
data.forEach((item) => {
item.disabled = item.data_type === 0 ? false : true;
if (item.Child) {
filterOrg(item.Child);
} else {
return;
}
});
}
return data;
};
const isTop = (data) => {
directoryForm.p_organization_id = data ? " " : ""; //空格绕过表单非空校验
};
onBeforeMount(() => {
getOrgTree();
});
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="flex_row">
<div class="flex_left bgc_white">
<div class="tree_header">政务组织</div>
<div class="tree_content">
<div class="search">
<el-input v-model="search" placeholder="请输入组织名称搜索" :prefix-icon="Search" @input="searchChange" />
</div>
<div class="tree">
<tree ref="orgTree" @action="treeAction" @select="treeSelect"></tree>
</div>
</div>
</div>
<div class="flex_right">
<div class="info_container bgc_white">
<div class="title">
<span class="icon_box">
<span class="step_icon">
<bg-icon icon="#bg-ic-file"></bg-icon>
</span>
<span> 基本信息 </span>
</span>
<span class="can_click_text detail_btn" v-if="selectTreeDataType === 1" @click="toOrgDetail">
查看详情
<bg-icon style="font-size: 8px; color: #95a3ca; vertical-align: middle" icon="#bg-ic-arrow-right" />
</span>
</div>
<bg-info class="info_box" v-if="selectTreeDataType === 1" :data="baseInfo"></bg-info>
<bg-info class="info_box" v-if="selectTreeDataType === 2" :data="baseInfo2"></bg-info>
</div>
<div class="main_container bgc_white">
<bg-filter-group @search="changeSearch" v-model="filter.key_word" placeholder="请输入关键字">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="primary" @click="addAccount">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
{{ selectTreeDataType === 1 ? "新增组织管理员" : "新增平台用户" }}
</el-button>
<el-button @click="deleteBatch"> 批量删除 </el-button>
<el-button @click="resetPsd"> 重置密码 </el-button>
<span class="header_info"
>已选择<span style="color: #202531; font-weight: bold">{{ selected.length }}</span
></span
>
<span class="header_info can_click_text" @click="clearSelected">清空</span>
</div>
</template>
<template v-slot:filter_group>
<div class="left-filter filter_list">
<div class="filter_item">
<span class="filter_title">启用状态</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px">
<el-option
v-for="(item, index) in stateOptions"
:key="'pushOptions' + index"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
<div class="right-action apaas_button">
<el-button type="primary" @click="filterAction"> 查询 </el-button>
<el-button type="default" @click="filterClear"> 重置 </el-button>
</div>
</template>
</bg-filter-group>
<div class="table_container apaas_scroll">
<bg-table
ref="dataTable"
:headers="headers"
:rows="tableRows"
:isIndex="true"
canEdit
canEditFlag="canSelect"
:stripe="true"
:select="true"
@selectAc="selectRows">
<template v-slot:system_account="{ row }">
<span @click="goDetail(row)" class="can_click_text">
{{ row.system_account }}
</span>
</template>
<template v-slot:state="{ row }">
<bg-switch
@click="stateChange(row)"
:labels="['否', '是']"
:values="[0, 1]"
v-model="row.state"
:disabled="row.is_admin == 4"></bg-switch>
</template>
<template v-slot:action="{ row }">
<bg-table-btn :disabled="row.is_admin == 4" @click="editAccount(row)" class="can_click_text">
编辑
</bg-table-btn>
<bg-table-btn
:disabled="row.is_admin == 4 && userInfo.is_admin !== 4"
@click="editPsdAccount(row)"
class="can_click_text">
修改密码
</bg-table-btn>
<bg-table-btn :disabled="row.is_admin == 4" @click="deleteAccount(row)" class="can_click_text">
删除
</bg-table-btn>
</template>
</bg-table>
<div class="pagination_box">
<bg-pagination
:page="filter.page"
:size="filter.limit"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</div>
</div>
</div>
<el-dialog
v-model="dialogDirectory"
:title="action === 'create' ? '新增目录' : '编辑目录'"
width="758px"
:before-close="handleCloseDirectory"
destroy-on-close>
<div class="dialog_form">
<directoryForm
ref="directoryFormRef"
:form-type="directoryFormType"
@action="getDirectoryFromData"></directoryForm>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseDirectory">取消</el-button>
<el-button type="primary" @click="saveDirectory">保存</el-button>
</span>
</template>
</el-dialog>
<el-dialog
v-model="dialogOrg"
:title="action === 'create' ? '新增组织' : '编辑组织'"
width="758px"
:before-close="handleCloseOrg"
destroy-on-close>
<div class="dialog_form">
<orgForm ref="orgFormRef" :form-type="orgFormType" @action="getOrgFormData"></orgForm>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseOrg">取消</el-button>
<el-button type="primary" @click="saveOrg">保存</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="dialogDelNode" title="删除" width="520px" :before-close="handleCloseDelNode">
<div class="dialog_form">确认删除吗?</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseDelNode">取消</el-button>
<el-button type="primary" @click="confirmDelNode">确认</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="deleteRowFlag" title="删除" width="520px" :before-close="handleCloseRowDelete">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedRow.system_account }}</span
>做删除操作。
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseRowDelete">取消</el-button>
<el-button type="primary" @click="deleteRowConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="editFlag" title="修改密码" width="520px" :before-close="handleCloseEdit">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedRow.system_account }}</span
>做修改密码操作,修改后旧密码将无法登录。
</div>
<div>
<el-form
:label-position="'right'"
label-width="120px"
:model="passwordForm"
:rules="passwordFormRules"
ref="passwordRef"
style="max-width: 80%">
<el-form-item label="新密码" prop="password">
<el-input
v-model="passwordForm.password"
:type="password_eye ? 'text' : 'password'"
placeholder="请输入密码">
<template #suffix>
<bg-icon @click="password_eye = !password_eye" class="icon_eye" icon="#bg-ic-eye"></bg-icon>
</template>
</el-input>
</el-form-item>
<el-form-item label="确认新密码" prop="confirm_password">
<el-input
v-model="passwordForm.confirm_password"
:type="confirm_eye ? 'text' : 'password'"
placeholder="请确认新密码">
<template #suffix>
<bg-icon @click="confirm_eye = !confirm_eye" class="icon_eye" icon="#bg-ic-eye"></bg-icon>
</template>
</el-input>
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseEdit">取消</el-button>
<el-button type="primary" @click="editConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="deleteFlag" title="删除" width="520px" :before-close="handleCloseDelete">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; mdeleteconfirmargin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedName.join("、") }}</span
>做删除操作。
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseDelete">取消</el-button>
<el-button type="primary" @click="deleteConfirm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="resetFlag" title="重置密码" width="520px" :before-close="handleCloseReset">
<div class="warning_info">
<bg-icon
style="font-size: 12px; color: #a9b1c7; margin-right: 8px; vertical-align: baseline"
icon="#bg-ic-circle-tips"></bg-icon>
您正在对 <span class="danger_info">{{ selectedName.join("、") }}</span
>做重置密码操作。
</div>
<div>重置密码为123456,是否继续?</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseReset">取消</el-button>
<el-button type="primary" @click="resetConfirm">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { computed, onBeforeMount, nextTick, reactive, ref, toRefs } from "@vue/runtime-core";
import { useRouter } from "vue-router";
import tree from "./tree.vue";
import directoryForm from "./directory-form.vue";
import orgForm from "./org-form.vue";
import CryptoJS from "crypto-js";
import { downloadFileFormatNew } from "@/services/helper";
import store from "@/store";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const dataTable = ref(null);
const toOrgDetail = () => {
router.push({
path: "/system/organization/org-detail",
query: {
id: selectOrgNode.value.organization_id,
},
});
};
const baseInfo = reactive([
{
name: "组织类型",
value: "",
nameWidth: 130,
},
{
name: "组织代码",
value: "",
nameWidth: 130,
},
{
name: "组织名称",
value: "",
callback: toOrgDetail,
nameWidth: 130,
},
{
name: "创建时间",
value: "",
nameWidth: 130,
},
{
name: "组织管理员数量",
value: "",
nameWidth: 130,
},
{
name: "业务系统数量",
value: "",
nameWidth: 130,
},
]);
const baseInfo2 = reactive([
{
name: "组织名称",
value: "",
nameWidth: 130,
},
{
name: "组织代码",
value: "",
nameWidth: 130,
},
{
name: "用户数",
value: "",
nameWidth: 130,
full: true,
},
]);
const headers = reactive([
{
label: "账号",
prop: "system_account",
minWidth: 150,
},
{
label: "手机号",
prop: "contact_phone",
minWidth: 150,
},
{
label: "角色",
prop: "system_role",
minWidth: 150,
},
{
label: "创建时间",
prop: "created_time",
minWidth: 200,
},
{
label: "是否启用",
prop: "state",
width: 80,
},
{
label: "操作",
prop: "action",
width: 220,
fixed: "right",
},
]);
const stateOptions = ref([
{
name: "全部",
value: "",
},
{
name: "启用",
value: "1",
},
{
name: "禁用",
value: "0",
},
]);
const tableRows = ref([]);
const tableTotal = ref(0);
const orgTree = ref(null);
const selectTreeData = ref(null);
const actionTreeData = ref(null);
const selectTreeDataType = ref(2);
const selectOrgNode = ref(null);
const dialogDelNode = ref(false);
const router = useRouter();
const filter = reactive({
state: "",
key_word: "",
page: 1,
limit: 10,
});
const deleteFlag = ref(false);
const deleteRowFlag = ref(false);
const resetFlag = ref(false);
const selectedRow = ref({});
const selected = ref([]);
const selectedName = ref([]);
const editFlag = ref(false);
const password_eye = ref(false);
const confirm_eye = ref(false);
const passwordRef = ref(null);
const passwordForm = reactive({
password: "",
confirm_password: "",
});
const search = ref("");
const userInfo = computed(() => {
return store.state.userInfo;
});
const validatePass = (rule, value, callback) => {
if (value !== passwordForm.password) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
};
const passwordFormRules = reactive({
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, message: "密码长度不得低于8位", trigger: "blur" },
],
confirm_password: [
{ required: true, message: "请确认密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
});
const addAccount = () => {
if (selectTreeDataType.value === 1) {
router.push({
path: "/system/organization/org-user",
query: {
orgId: selectOrgNode.value.organization_id,
},
});
} else {
router.push({
path: "/system/organization/platform-user",
});
}
};
const changeSize = (size) => {
filter.limit = size;
changePage(1);
};
const changePage = (page) => {
filter.page = page;
getTableRows();
};
const changeSearch = (val) => {
filter.key_word = val;
changePage(1);
}; // 表格关键字筛选
const filterAction = () => {
changePage(1);
}; // 查询按钮
const filterClear = () => {
filter.state = "";
filter.key_word = "";
filter.limit = 10;
filter.page = 1;
changePage(1);
}; // 重置筛选项
const dialogDirectory = ref(false);
const directoryFormType = ref("create");
const orgFormType = ref("create");
const handleCloseDirectory = () => {
dialogDirectory.value = false;
};
const directoryFormRef = ref(null);
const saveDirectory = () => {
directoryFormRef.value.submitForm();
};
//新增/编剧目录
const getDirectoryFromData = (data) => {
if (directoryFormType.value === "create") {
const params = {
p_organization_id: data.level ? "" : data.p_organization_id,
name: data.name,
data_type: 0,
};
axios.post(`/apaas/system/v5/org/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(res.data.data.id);
} else {
ElMessage.error(res.data.data);
}
handleCloseDirectory();
});
} else if (directoryFormType.value === "edit") {
const params = {
name: data.name,
data_type: 0,
};
axios.put(`/apaas/system/v5/org/${actionTreeData.value.id}`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id);
} else {
ElMessage.error(res.data.data);
}
handleCloseDirectory();
});
}
};
const dialogOrg = ref(false);
const handleCloseOrg = () => {
dialogOrg.value = false;
};
const orgFormRef = ref(null);
const saveOrg = () => {
orgFormRef.value.submitForm();
};
//新增/编辑组织
const getOrgFormData = (data) => {
if (orgFormType.value === "create") {
const params = {
p_organization_id: data.level ? "" : data.p_organization_id,
name: data.name,
organization_code: data.organization_code,
description: data.description,
attachment:
data.attachment && data.attachment.length > 0 ? data.attachment.map((item) => item.url).join(",") : "",
data_type: 1,
};
axios.post(`/apaas/system/v5/org/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(res.data.data.id);
} else {
ElMessage.error(res.data.data);
}
handleCloseOrg();
});
} else if (orgFormType.value === "edit") {
const params = {
// p_organization_id: data.level ? "" : data.p_organization_id,
name: data.name,
organization_code: data.organization_code,
description: data.description,
attachment:
data.attachment && data.attachment.length > 0 ? data.attachment.map((item) => item.url).join(",") : "",
data_type: 1,
};
axios.put(`/apaas/system/v5/org/${actionTreeData.value.id}`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id);
} else {
ElMessage.error(res.data.data);
}
handleCloseOrg();
});
}
};
const handleCloseDelNode = () => {
dialogDelNode.value = false;
};
//删除目录/组织
const confirmDelNode = () => {
axios.delete(`/apaas/system/v5/org/${actionTreeData.value.id}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(actionTreeData.value.id === selectTreeData.value.id ? null : selectTreeData.value.id);
} else {
ElMessage.error(res.data.data);
}
handleCloseDelNode();
});
};
const moveOrg = (params) => {
axios.put(`/apaas/system/v5/org/sort`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
orgTree.value.getOrgTree(selectTreeData.value.id);
} else {
ElMessage.error(res.data.data);
}
});
};
const action = ref("create");
const treeAction = (data) => {
action.value = data.action;
if (data.action === "create" || data.action === "edit") {
if (data.type === "org") {
orgFormType.value = data.action;
dialogOrg.value = true;
nextTick(() => {
if (data.data) {
if (data.action === "edit") {
orgFormRef.value.setForm({
name: data.data.value.name,
p_organization_id: data.data.value.p_organization_id,
level: data.data.value.p_organization_id ? false : true,
organization_code: data.data.value.organization_code,
description: data.data.value.description,
attachment: data.data.value.attachment.split(",").map((i) => {
return { name: downloadFileFormatNew(i), url: i };
}),
});
} else if (data.action === "create") {
orgFormRef.value.setForm({ p_organization_id: data.data.value.organization_id });
}
}
});
} else {
directoryFormType.value = data.action;
dialogDirectory.value = true;
nextTick(() => {
if (data.data) {
if (data.action === "edit") {
directoryFormRef.value.setForm({ name: data.data.value.name });
} else if (data.action === "create") {
directoryFormRef.value.setForm({ p_organization_id: data.data.value.organization_id });
}
}
});
}
} else if (data.action === "delete") {
dialogDelNode.value = true;
} else if (data.action === "mvup" || data.action === "mvdown") {
moveOrg(data.data);
}
};
const treeSelect = (data) => {
if (data.type === "action") {
actionTreeData.value = data.data.value;
} else {
selectTreeData.value = data.data.value;
}
if (data.type === "click" && (data.data.value.data_type === 1 || data.data.value.data_type === 2)) {
selectTreeDataType.value = data.data.value.data_type;
selectOrgNode.value = data.data.value;
getTableRows();
}
};
const getTableRows = () => {
let params = {
...filter,
organization_id: selectTreeData.value.organization_id,
data_type: selectTreeData.value.data_type,
};
axios
.get(`/apaas/system/v5/org/detail`, {
params,
})
.then((res) => {
if (res.data.code == 200) {
tableRows.value = (res.data.data.org_users.data || []).map((item) => {
item.system_role = item.system_role ? item.system_role.join("") : "-";
return item;
});
tableRows.value.forEach((e) => {
if (e.is_admin == 4 && userInfo.value.is_admin != 4) {
e.canSelect = 1;
} else {
e.canSelect = 0;
}
});
tableTotal.value = res.data.data.org_users.total;
if (params.data_type === 1) {
baseInfo[0].value = res.data.data.org_info.organization_type;
baseInfo[1].value = res.data.data.org_info.organization_code;
baseInfo[2].value = res.data.data.org_info.name;
baseInfo[3].value = res.data.data.org_info.created_time;
baseInfo[4].value = res.data.data.org_info.org_admin_number;
baseInfo[5].value = res.data.data.org_info.business_system_number;
} else {
baseInfo2[0].value = res.data.data.org_info.name;
baseInfo2[1].value = res.data.data.org_info.organization_code;
baseInfo2[2].value = res.data.data.org_info.platform_users_number;
}
console.log(baseInfo);
} else {
ElMessage.error(res.data.data);
}
});
};
const searchChange = (val) => {
orgTree.value.filterTree(val);
};
const goDetail = (params) => {
router.push({
path: "/system/organization/user-detail",
query: {
id: params.id,
},
});
};
const stateChange = (row) => {
if (row.is_admin == 4) {
return;
}
const state = row.state.toString();
axios.post(`/apaas/system/v5/user/state/${row.id}/${state}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
row.state = row.state == 0 ? 1 : 0;
}
});
};
const editPsdAccount = (data) => {
selectedRow.value = data;
editFlag.value = true;
};
const handleCloseEdit = () => {
if (!passwordRef) return;
passwordRef.value.resetFields();
editFlag.value = false;
};
const editConfirm = () => {
if (!passwordRef) return;
passwordRef.value.validate((valid, fields) => {
if (valid) {
axios
.post(`/apaas/system/v5/user/editpwd`, {
id: selectedRow.value.id,
password: CryptoJS.AES.encrypt(passwordForm.password, "swuE9cmCZQwrkYRV").toString(),
})
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
} else {
ElMessage.error(res.data.data);
}
handleCloseEdit();
});
}
});
};
const deleteAccount = (data) => {
if (data.state === 0) {
selectedRow.value = data;
deleteRowFlag.value = true;
} else {
ElMessage.error("当前状态已启用,不可删除!");
}
};
const handleCloseRowDelete = () => {
deleteRowFlag.value = false;
};
const deleteRowConfirm = () => {
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: [selectedRow.value.id] } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseRowDelete();
});
};
const editAccount = (data) => {
if (selectTreeDataType.value === 1) {
router.push({
path: "/system/organization/org-user/edit",
query: {
id: data.id,
orgId: selectOrgNode.value.organization_id,
},
});
} else {
router.push({
path: "/system/organization/platform-user/edit",
query: {
id: data.id,
},
});
}
};
const handleCloseDelete = () => {
deleteFlag.value = false;
};
const deleteConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.delete(`/apaas/system/v5/user/delete`, { data: { ids: ids } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseDelete();
});
};
const deleteBatch = () => {
if (selectedName.value.length > 0) {
deleteFlag.value = true;
} else {
ElMessage.error("请先选择需要操作的数据!");
}
};
const handleCloseReset = () => {
resetFlag.value = false;
};
const resetPsd = () => {
if (selectedName.value.length > 0) {
resetFlag.value = true;
} else {
ElMessage.error("请先选择需要操作的数据!");
}
};
const resetConfirm = () => {
const ids = selected.value.map((item) => item.id);
axios.post(`/apaas/system/v5/user/resetpwd`, { ids: ids }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
getTableRows();
} else {
ElMessage.error(res.data.data);
}
handleCloseReset();
});
};
const selectRows = (data) => {
selected.value = data.selection;
selectedName.value = data.selection.map((item) => item.system_account);
};
const clearSelected = () => {
dataTable.value.clearTable();
};
onBeforeMount(() => {});
</script>
<style scoped>
.tree_header {
height: 40px;
line-height: 40px;
background-color: #f7f7f9;
border-radius: 6px 6px 0px 0px;
font-size: 16px;
letter-spacing: 0px;
color: #202531;
padding-left: 16px;
}
.tree_content {
overflow: hidden;
height: calc(100% - 45px);
}
.search {
padding: 16px;
}
.tree {
overflow: hidden auto;
height: calc(100% - 65px);
/* padding: 5px; */
}
.tree :deep() .el-tree-node > .el-tree-node__children {
overflow: unset;
}
.flex_right {
display: flex;
flex-direction: column;
}
.info_container {
padding: 15px;
margin-bottom: 10px;
}
.title {
font-size: 18px;
color: #202531;
font-weight: bold;
margin-bottom: 10px;
max-width: 960px;
display: flex;
justify-content: space-between;
align-items: center;
}
.detail_btn {
font-size: 14px;
font-weight: normal;
}
.icon_box {
display: flex;
align-items: center;
}
.step_icon {
display: inline-block;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
background-color: #2a4aa7;
color: #fff;
border-radius: 4px;
font-size: 14px;
margin-right: 8px;
}
.info_box {
max-width: 960px;
}
.main_container {
flex: 1;
overflow: hidden;
}
.filter-group .left-filter {
flex: 1;
display: flex;
justify-content: start;
flex-wrap: wrap;
}
.filter-group .right-action {
width: 144px;
padding-bottom: 16px;
}
.filter-group .right-action .el-button {
width: 64px;
}
.table_container {
height: calc(100% - 20px);
overflow: auto;
padding: 0 16px;
}
.bg-pagination {
bottom: unset;
}
.dialog_form {
padding: 24px 8px 6px;
}
</style>
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content apaas_scroll">
<div class="info_row">
<div class="title">
<div><span class="icon_box"></span> 基础信息</div>
<div class="dashed_line"></div>
</div>
<div class="info_content">
<div class="info_box">
<bg-info :data="baseInfo"></bg-info>
</div>
<div class="org_file info_box">
<div class="pl-1">组织附件</div>
<div>
<div class="file_item pl-1" v-for="(item, index) in fileList" :key="'file_' + index">
<span><bg-icon style="font-size: 24px" :icon="'#bg-ic-' + formatFile(item)"></bg-icon></span>
<span class="file_name">{{ downloadFileFormatNew(item) }}</span>
<span class="fr download_btn">
<el-button type="primary" @click="downloadFile(item)"
><bg-icon icon="#bg-ic-to-bottom"></bg-icon>下载</el-button
>
</span>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="title">
<div><span class="icon_box"></span> 业务系统信息</div>
<div class="dashed_line"></div>
</div>
<div class="info_content info_box">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true"> </bg-table>
<div class="pagination_box">
<bg-pagination
:page="filter.page"
:size="filter.limit"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, toRefs, ref, computed, onBeforeMount } from "vue";
import { useRoute } from "vue-router";
import { downloadFileFormatNew } from "@/services/helper";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const route = useRoute();
const baseInfo = reactive([
{
name: "组织名称",
value: "",
nameWidth: 130,
},
{
name: "组织代码",
value: "",
nameWidth: 130,
},
{
name: "组织管理员数量",
value: "",
nameWidth: 130,
},
{
name: "业务系统数量",
value: "",
nameWidth: 130,
},
{
name: "组织描述",
value: "",
nameWidth: 130,
},
]);
const headers = reactive([
{
label: "业务系统名称",
prop: "business_name",
},
{
label: "是否启用",
prop: "state",
},
{
label: "业务系统账号",
prop: "system_account",
},
]);
const tableRows = ref([]);
const fileList = ref([]);
const filter = reactive({
page: 1,
limit: 10,
});
const tableTotal = ref(0);
const changeSize = (size) => {
filter.limit = size;
changePage(1);
};
const changePage = (page) => {
filter.page = page;
getSystemInfo();
};
const downloadFile = (data) => {
const a = document.createElement("a"); // 创建a标签
a.setAttribute("download", ""); // download属性
a.setAttribute("href", data); // href链接
a.click(); // 自执行点击事件
};
const formatFile = (url) => {
const file = url.split(".")[1];
let icon = "";
if ("docx".indexOf(file) !== -1) {
icon = "c-file-doc";
} else if ("xlsx".indexOf(file) !== -1) {
icon = "c-file-xlsx";
} else if ("pdf".indexOf(file) !== -1) {
icon = "c-file-pdf";
} else if ("txt".indexOf(file) !== -1) {
icon = "c-file-txt";
} else if ("zip".indexOf(file) !== -1) {
icon = "c-file-zip";
} else if ("jpg,png".indexOf(file) !== -1) {
icon = "c-file-image";
} else {
icon = "txt";
}
return icon;
};
const getDetail = () => {
axios
.get(`/apaas/system/v5/org/detail?organization_id=${route.query.id}&key_word=&state=&limit=&page=&data_type=1`)
.then((res) => {
if (res.data.code == 200) {
const detail = res.data.data.org_info;
baseInfo[0].value = detail.name;
baseInfo[1].value = detail.organization_code;
baseInfo[2].value = detail.org_admin_number;
baseInfo[3].value = detail.business_system_number;
baseInfo[4].value = detail.description;
fileList.value = detail.attachment ? detail.attachment.split(",") : [];
} else {
ElMessage.error(res.data.data);
}
});
};
const getSystemInfo = () => {
const params = { ...filter, organization_id: route.query.id };
axios.get(`/apaas/system/v5/org/business/msg`, { params }).then((res) => {
if (res.data.code == 200) {
tableRows.value = res.data.data || [];
tableTotal.value = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
};
onBeforeMount(() => {
if (route.query.id) {
getDetail();
getSystemInfo();
}
});
</script>
<style scoped>
.page_content {
padding: 15px;
overflow: auto;
font-size: 14px;
color: #202531;
}
.info_content {
/* display: flex; */
}
.org_file {
margin-top: 15px;
}
.file_item {
height: 48px;
line-height: 48px;
background-color: #fafafa;
border-radius: 4px;
font-size: 14px;
margin-bottom: 8px;
}
.file_name {
padding-left: 10px;
color: #202531;
}
.download_btn {
padding-right: 4px;
}
.info_row {
margin-bottom: 40px;
}
.img_box {
width: 120px\;;
}
.info_box {
width: 60%;
}
.title {
font-size: 18px;
color: #1a1a1a;
font-weight: bold;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.dashed_line {
flex: 1;
height: 1px;
margin: 0 10px;
border-bottom: dashed 1px #dadee7;
}
.icon_box {
display: inline-block;
width: 4px;
height: 14px;
background-color: #3759be;
border-radius: 2px;
margin-right: 5px;
}
.pagination_box {
position: sticky;
position: -webkit-sticky;
margin-top: 16px;
bottom: -15px;
background-color: #fff;
z-index: 1024;
height: 40px;
line-height: 40px;
padding-top: 5px;
}
.bg-pagination {
margin-top: 0px;
}
.info_content :deep() .bg-table .empty_container {
height: 160px;
padding-top: 25px;
}
</style>
<template>
<el-form :label-position="'right'" label-width="120px" :model="orgForm" :rules="formRules" ref="orgRef">
<el-form-item label="上级目录" prop="p_organization_id" v-if="formType === 'create'">
<el-tree-select
v-model="orgForm.p_organization_id"
:data="orgData"
:props="treeProps"
:render-after-expand="false"
:check-strictly="true"
:disabled="orgForm.level"
style="width: 80%" />
<el-form-item label="" style="padding-left: 16px">
<el-checkbox v-model="orgForm.level" @change="isTop" label="顶级" />
</el-form-item>
</el-form-item>
<el-form-item label="政务组织名称" prop="name">
<el-input v-model="orgForm.name" />
</el-form-item>
<el-form-item label="组织代码" prop="organization_code">
<el-input v-model="orgForm.organization_code" />
</el-form-item>
<el-form-item label="组织介绍" prop="description">
<el-input type="textarea" :rows="3" v-model="orgForm.description" maxlength="300" show-word-limit />
</el-form-item>
<el-form-item label="组织附件" prop="logo">
<bg-upload
v-model="orgForm.attachment"
customTips
:limit="3"
:fileTypes="['zip', 'rar', 'doc', 'docx', 'xlsx', 'xls', 'png', 'jpg']"
:otherInfo="'最多可上传三个附件,可上传zip,rar,doc,docx,xlsx,xls,png,jpg,可上传营业执照和相关协议文件等'">
<span>将文件拖到此处,或 点击上传</span>
</bg-upload>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted, onBeforeMount } from "vue";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const props = defineProps({
formType: {
type: String,
default: "create", //false 新增 true 编辑
},
});
const orgForm = reactive({
p_organization_id: "",
level: false,
name: "",
organization_code: "",
description: "",
attachment: [],
});
const checkCode = (rule, value, callback) => {
var reg = /^[a-zA-Z0-9]+$/;
if (!reg.test(value)) {
callback(new Error("只能输入字母和数字"));
} else {
callback();
}
};
const checkName = (rule, value, callback) => {
var reg = /^[a-zA-Z\u4e00-\u9fa5]+$/;
if (!reg.test(value)) {
callback(new Error("只能输入字母和汉字"));
} else {
callback();
}
};
const formRules = reactive({
p_organization_id: [{ required: true, message: "输入上级目录", trigger: "blur" }],
name: [
{ required: true, message: "请输入组织名称", trigger: "blur" },
{ max: 50, message: "组织名称最大长度为50位", trigger: "blur" },
{ validator: checkName, trigger: "blur" },
],
organization_code: [
{ required: true, message: "请输入组织代码", trigger: "blur" },
{ max: 18, message: "组织代码最大长度为18位", trigger: "blur" },
{ validator: checkCode, trigger: "blur" },
],
});
const orgRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!orgRef) return;
await orgRef.value.validate((valid, fields) => {
if (valid) {
emit("action", orgForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!orgRef) return;
orgRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(orgForm, data);
};
const orgData = ref([]);
const treeProps = {
label: "name",
children: "Child",
value: "organization_id",
disabled: "disabled",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
const orgDataTemp = res.data.data || [];
orgDataTemp.shift();
orgData.value = filterOrg(orgDataTemp);
} else {
ElMessage.error(res.data.data);
}
});
};
const filterOrg = (data) => {
if (data.length > 0) {
data.forEach((item) => {
item.disabled = item.data_type === 0 ? false : true;
if (item.Child) {
filterOrg(item.Child);
} else {
return;
}
});
}
return data;
};
const isTop = (data) => {
orgForm.p_organization_id = data ? " " : ""; //空格绕过表单非空校验
};
onBeforeMount(() => {
getOrgTree();
});
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content flex_cloumn">
<div class="content_top apaas_scroll">
<div class="content_process">
<div>
<el-steps :active="step">
<el-step title="" :class="{ process_complete: step > 1 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 0"
><bg-icon class="step_icon" icon="#bg-ic-file"></bg-icon
></span>
<span class="circle" v-else></span>
账号信息
</span>
</template>
</el-step>
<el-step title="" :class="{ process_complete: step > 2 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 1"
><bg-icon class="step_icon" icon="#bg-ic-file-staff"></bg-icon
></span>
<span class="circle" v-else></span>
个人信息
</span>
</template>
</el-step>
<el-step title="">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 2"
><bg-icon class="step_icon" icon="#bg-ic-file-success"></bg-icon
></span>
<span class="circle" v-else></span>
完成
</span>
</template>
</el-step>
</el-steps>
</div>
</div>
<div class="content_main">
<orgAccountForm
v-show="step === 1"
:form-type="route.query.id ? true : false"
:id="route.query.id"
ref="orgAccountRef"
@action="getOrgAccountFormData"></orgAccountForm>
<orgPersonForm v-show="step === 2" ref="orgPersonRef" @action="getOrgPersonFormData"></orgPersonForm>
<div class="process_end" v-show="step === 3">
<div>
<div>
<img v-if="successFlag" src="@/assets/imgs/img_data-complete.png" alt="" />
<img v-else src="@/assets/imgs/img_data-fail.png" alt="" />
</div>
<div class="font_bold">
{{
route.query.id
? successFlag
? "组织用户编辑成功"
: "组织用户编辑失败"
: successFlag
? "组织用户新增成功"
: "组织用户新增失败"
}}
</div>
<el-button @click="cancel">返回列表</el-button>
<el-button v-if="!route.query.id" type="primary" @click="continueCreate">继续创建</el-button>
</div>
</div>
</div>
</div>
<div class="content_bottom" v-if="step !== 3">
<div v-show="step === 1">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="nextStep">下一步</el-button>
</div>
<div v-show="step === 2">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="previousStep">上一步</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { useRoute, useRouter } from "vue-router";
import orgAccountForm from "./org-account-form.vue";
import orgPersonForm from "./org-person-form.vue";
import { reactive, ref, onBeforeMount, toRefs, computed, onBeforeUnmount, onMounted } from "vue";
import CryptoJS from "crypto-js";
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 step = ref(1);
const orgAccountRef = ref(null);
const orgPersonRef = ref(null);
const formData = reactive({
organization_id: "",
select_role: "",
logo: [],
system_account: "",
contact_phone: "",
password: "",
confirm_password: "",
state: 1,
contact_name: "",
document_type: "",
document_number: "",
contact_email: "",
remark: "",
}); //账号信息表单+个人信息表单
const successFlag = ref(false);
const orgId = ref("");
// 下一步
const nextStep = () => {
orgAccountRef.value.submitForm();
};
//账号信息表单检验触发事件 data为null 校验失败
const getOrgAccountFormData = (data) => {
if (data) {
Object.assign(formData, data);
step.value = 2;
} else {
}
};
//个人信息表单检验触发事件 data为null 校验失败
const getOrgPersonFormData = (data) => {
if (data) {
if (data) {
Object.assign(formData, data);
if (route.query.id) {
let params = {
...formData,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
};
params.document_type = params.document_type == "" ? 0 : params.document_type;
axios.put(`/apaas/system/v5/org/update/user/${route.query.id}`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
} else {
const params = {
...formData,
// organization_id: orgId.value,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
is_admin: 2,
password: CryptoJS.AES.encrypt(formData.password, "swuE9cmCZQwrkYRV").toString(),
};
params.document_type = params.document_type == "" ? 0 : params.document_type;
axios.post(`/apaas/system/v5/org/add/user`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
}
}
}
};
//上一步
const previousStep = () => {
step.value--;
};
//提交表单
const submit = () => {
orgPersonRef.value.submitForm();
};
//继续创建 清空表单
const continueCreate = () => {
orgAccountRef.value.clearForm();
orgPersonRef.value.clearForm();
step.value = 1;
successFlag.value = false;
};
//取消
const cancel = () => {
router.push({
path: "/system/organization",
query: {
id: route.query.orgId,
},
});
};
const getDetail = () => {
axios.get(`/apaas/system/v5/org/user/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
const form = res.data.data;
orgAccountRef.value.setForm({
organization_id: form.organization_id,
select_role: form.select_role,
logo: form.logo ? [{ url: form.logo }] : [],
system_account: form.system_account,
contact_phone: form.contact_phone,
state: form.state,
});
orgPersonRef.value.setForm({
contact_name: form.contact_name,
document_type: form.document_type ? form.document_type : "",
document_number: form.document_number,
contact_email: form.contact_email,
remark: form.remark,
});
} else {
ElMessage.error(res.data.data);
}
});
};
onBeforeMount(() => {
if (route.query.id) {
getDetail();
}
});
onMounted(() => {});
</script>
<style scoped>
.flex_cloumn {
display: flex;
flex-direction: column;
}
.content_top {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
/* .content_top::-webkit-scrollbar {
width: 5px;
height: 0px;
}
.content_top::-webkit-scrollbar-thumb {
background: #dedede;
border-radius: 10px;
height: 0px;
}
.content_top::-webkit-scrollbar-track {
background: transparent;
border-radius: 2px;
} */
.content_bottom {
height: 68px;
line-height: 68px;
text-align: right;
padding: 0 20px;
border-top: 1px solid #e6e9ef;
}
.content_process {
border-bottom: 1px solid #e6e9ef;
padding: 38px 16%;
}
.content_main {
flex: 1;
padding: 30px;
box-sizing: border-box;
}
.process_desc {
background-color: #fff;
display: inline-block;
position: absolute;
padding: 0 5px;
font-size: 18px;
color: #202531;
font-weight: bold;
}
.process_desc img {
height: 25px;
width: 25px;
vertical-align: middle;
}
.process_end {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.process_end div {
text-align: center;
}
.step_icon {
color: #fff;
font-weight: 600;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.icon_box {
display: inline-block;
background-color: #2b4695;
width: 48px;
height: 48px;
border-radius: 99px;
position: relative;
border: 3px solid #b0bee8;
vertical-align: middle;
}
.circle {
display: inline-block;
background-color: #a9b1c7;
width: 24px;
height: 24px;
border-radius: 99px;
position: relative;
border: 4px solid #e6e9ef;
vertical-align: middle;
}
.content_process :deep() .el-step.is-horizontal .el-step__line {
height: 4px;
}
.content_process :deep() .el-step__head.is-finish .el-step__line {
background: linear-gradient(to right, #2b4695 50%, #e6e9ef 50%);
}
.process_complete :deep() .el-step__head.is-finish .el-step__line {
background: linear-gradient(to right, #2b4695 100%, #e6e9ef 0%);
}
</style>
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="orgAccountForm"
:rules="orgAccountFormRules"
ref="orgformAccountRef"
style="max-width: 66%">
<el-form-item label="所属组织" prop="organization_id">
<el-tree-select
v-model="orgAccountForm.organization_id"
:data="orgData"
:props="treeProps"
:render-after-expand="false"
:disabled="true"
style="width: 100%" />
<!-- <el-input v-model="orgAccountForm.organization_id" /> -->
</el-form-item>
<el-form-item label="角色" prop="select_role" v-if="!formType">
<el-select
v-model="orgAccountForm.select_role"
multiple
placeholder="请选择角色"
:disabled="true"
style="width: 100%">
<el-option v-for="item in roleList" :key="item.role_id" :label="item.role_name" :value="item.role_id" />
</el-select>
</el-form-item>
<el-form-item label="头像" prop="logo">
<bg-upload-image
v-model="orgAccountForm.logo"
:showTips="true"
:limit="1"
:fileSize="500"
:fileSizeUnit="'KB'"
listType="picture-card"
:accept="['.jpg', '.jpeg', '.png']"
customTips="请选择图片上传:大小120 * 120像素支持jpg、png等格式,图片需小于500KB"></bg-upload-image>
</el-form-item>
<el-form-item label="账号" prop="system_account">
<el-input v-model="orgAccountForm.system_account" />
</el-form-item>
<el-form-item label="手机号" prop="contact_phone">
<el-input v-model="orgAccountForm.contact_phone" />
</el-form-item>
<el-form-item label="密码" prop="password" v-if="!formType">
<el-input type="password" v-model="orgAccountForm.password" />
</el-form-item>
<el-form-item label="确认密码" prop="confirm_password" v-if="!formType">
<el-input type="password" v-model="orgAccountForm.confirm_password" />
</el-form-item>
<el-form-item label="是否启用" prop="state">
<bg-switch :labels="['否', '是']" :values="[0, 1]" v-model="orgAccountForm.state"></bg-switch>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted, onBeforeMount } from "vue";
import { useRoute } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const route = useRoute();
const props = defineProps({
formType: {
type: Boolean,
default: false, //false 新增 true 编辑
},
id: {
type: String,
default: "",
},
});
const orgAccountForm = reactive({
organization_id: "",
select_role: "",
logo: [],
system_account: "",
contact_phone: "",
password: "",
confirm_password: "",
state: 1,
});
const validatePass = (rule, value, callback) => {
if (value !== orgAccountForm.password) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
};
const validateSystemAccount = (rule, value, callback) => {
let reg = /^[a-zA-Z0-9]+$/;
if (!reg.test(value)) {
callback(new Error("只能输入字母和数字"));
} else {
let params = null;
if (props.id) {
params = { id: parseInt(props.id), system_account: value };
} else {
params = { system_account: value };
}
axios.post(`/apaas/system/v5/user/check/account`, params).then((res) => {
if (res.data.code == 200) {
callback();
} else {
callback(new Error(res.data.data));
}
});
}
};
const checkPhone = (rule, value, callback) => {
var phone_ruler = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/;
setTimeout(() => {
if (!phone_ruler.test(value) && value.length !== 0) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
});
};
const checkPhoneRepet = (rule, value, callback) => {
let params = null;
if (props.id) {
params = { id: parseInt(props.id), contact_phone: value };
} else {
params = { id: 0, contact_phone: value };
}
axios.post(`/apaas/system/v5/org/check`, params).then((res) => {
if (res.data.code == 200) {
callback();
} else {
callback(new Error(res.data.data));
}
});
};
const orgAccountFormRules = reactive({
organization_id: [{ required: true, message: "请选择组织", trigger: "blur" }],
select_role: [{ required: true, message: "请选择角色", trigger: "blur" }],
system_account: [
{ required: true, message: "请输入账号", trigger: "blur" },
{ min: 4, message: "帐号长度不得低于4个字符", trigger: "blur" },
{ max: 20, message: "帐号最大长度为20个字符", trigger: "blur" },
{ validator: validateSystemAccount, trigger: "blur" },
],
contact_phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ validator: checkPhone, trigger: "blur" },
{ validator: checkPhoneRepet, trigger: "blur" },
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, message: "密码长度不得低于8位", trigger: "blur" },
],
confirm_password: [
{ required: true, message: "请确认密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
});
const orgformAccountRef = ref(null);
const emit = defineEmits(["action"]);
const roleList = ref([]);
const submitForm = async () => {
if (!orgformAccountRef) return;
await orgformAccountRef.value.validate((valid, fields) => {
if (valid) {
emit("action", orgAccountForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!orgformAccountRef) return;
orgformAccountRef.value.resetFields();
orgAccountForm.select_role = [roleList.value[0].role_id];
};
const setForm = (data) => {
Object.assign(orgAccountForm, data);
};
const orgData = ref([]);
const treeProps = {
label: "name",
children: "Child",
value: "organization_id",
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
orgData.value = res.data.data || [];
} else {
ElMessage.error(res.data.data);
}
});
};
const getRoleList = () => {
axios.get(`/apaas/system/v5/org/select/role?is_admin=2`).then((res) => {
if (res.data.code == 200) {
roleList.value = res.data.data;
orgAccountForm.select_role = [roleList.value[0].role_id];
} else {
}
});
};
onBeforeMount(() => {
getOrgTree();
getRoleList();
orgAccountForm.organization_id = route.query.orgId;
});
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="orgPersonForm"
:rules="orgPersonFormRules"
ref="orgPersonFormRef"
style="max-width: 66%">
<el-form-item label="联系人姓名" prop="contact_name">
<el-input v-model="orgPersonForm.contact_name" />
</el-form-item>
<el-form-item label="证件类型" prop="document_type">
<el-select v-model="orgPersonForm.document_type" placeholder="请选择证件类型" style="width: 100%">
<el-option v-for="item in documentTypeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="证件号" prop="document_number">
<el-input v-model="orgPersonForm.document_number" />
</el-form-item>
<el-form-item label="联系人邮箱" prop="contact_email">
<el-input v-model="orgPersonForm.contact_email" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="3" v-model="orgPersonForm.remark" />
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue";
const orgPersonForm = reactive({
contact_name: "",
document_type: "",
document_number: "",
contact_email: "",
remark: "",
});
const documentTypeList = ref([
{
label: "身份证",
value: 1,
},
]);
const orgPersonFormRules = reactive({
contact_email: [
// { required: true, message: '请输入手机号', trigger: 'blur' },
{ type: "email", message: "请输入正确的邮箱", trigger: "blur" },
],
document_number: [
{
pattern:
/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx]$)/,
message: "请输入正确的身份证号",
trigger: "blur",
},
],
});
const orgPersonFormRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!orgPersonFormRef) return;
await orgPersonFormRef.value.validate((valid, fields) => {
if (valid) {
emit("action", orgPersonForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!orgPersonFormRef) return;
orgPersonFormRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(orgPersonForm, data);
};
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content flex_cloumn">
<div class="content_top apaas_scroll">
<div class="content_process" v-if="!route.query.id">
<div>
<el-steps :active="step">
<el-step title="" :class="{ process_complete: step > 1 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 0"
><bg-icon class="step_icon" icon="#bg-ic-file"></bg-icon
></span>
<span class="circle" v-else></span>
账号信息
</span>
</template>
</el-step>
<el-step title="" :class="{ process_complete: step > 2 }">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 1"
><bg-icon class="step_icon" icon="#bg-ic-file-staff"></bg-icon
></span>
<span class="circle" v-else></span>
个人
</span>
</template>
</el-step>
<el-step title="">
<template #icon>
<span class="process_desc">
<span class="icon_box" v-if="step > 2"
><bg-icon class="step_icon" icon="#bg-ic-file-success"></bg-icon
></span>
<span class="circle" v-else></span>
完成
</span>
</template>
</el-step>
</el-steps>
</div>
</div>
<div class="content_main">
<platformAccountForm
v-show="step === 1"
:form-type="route.query.id ? true : false"
:id="route.query.id"
ref="platformAccountFormRef"
@action="getPlatformAccountFormData"></platformAccountForm>
<platformPersonForm
v-show="step === 2"
ref="plplatformPersonFormRef"
@action="getPlatformPersonFormData"></platformPersonForm>
<div class="process_end" v-show="step === 3">
<div>
<div>
<img v-if="successFlag" src="@/assets/imgs/img_data-complete.png" alt="" />
<img v-else src="@/assets/imgs/img_data-fail.png" alt="" />
</div>
<div class="font_bold">
{{
route.query.id
? successFlag
? "平台用户编辑成功"
: "平台用户编辑失败"
: successFlag
? "平台用户新增成功"
: "平台用户新增失败"
}}
</div>
<el-button @click="cancel">返回列表</el-button>
<el-button v-if="!route.query.id" type="primary" @click="continueCreate">继续创建</el-button>
</div>
</div>
</div>
</div>
<div class="content_bottom" v-if="step !== 3">
<div v-show="!route.query.id && step === 1">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="nextStep">下一步</el-button>
</div>
<div v-show="step === 2">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="previousStep">上一步</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</div>
<div v-show="route.query.id">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="nextStep">保存</el-button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { useRoute, useRouter } from "vue-router";
import platformAccountForm from "./platform-account-form.vue";
import platformPersonForm from "./platform-person-form.vue";
import CryptoJS from "crypto-js";
import { reactive, ref, onBeforeMount, toRefs, computed, onMounted } from "vue";
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 step = ref(1);
const platformAccountFormRef = ref(null);
const plplatformPersonFormRef = ref(null);
const formData = reactive({
logo: "",
system_account: "",
contact_phone: "",
password: "",
confirm_password: "",
select_role: "",
state: "",
contact_name: "",
contact_email: "",
remark: "",
}); //账号信息表单+个人信息表单
const orgId = ref(null);
const successFlag = ref(false);
// 下一步
const nextStep = () => {
platformAccountFormRef.value.submitForm();
};
//账号信息表单检验触发事件 data为null 校验失败
const getPlatformAccountFormData = (data) => {
if (data) {
if (route.query.id) {
Object.assign(formData, data);
let params = {
...formData,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
};
axios.put(`/apaas/system/v5/org/update/user/${route.query.id}`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
} else {
Object.assign(formData, data);
step.value = 2;
}
} else {
}
};
//个人信息表单检验触发事件 data为null 校验失败
const getPlatformPersonFormData = (data) => {
if (data) {
Object.assign(formData, data);
if (route.query.id) {
console.log(formData);
// let params = {
// }
// axios.post(`/apaas/system/v5/org/update/user/${route.query.id}`,params)
// .then((res) => {
// if (res.data.code == 200) {
// successFlag.value = true;
// step.value = 3;
// }else {
// ElMessage.error(res.data.msg)
// }
// })
} else {
const params = {
...formData,
organization_id: orgId.value,
logo: formData.logo && formData.logo.length > 0 ? formData.logo[0].url : "",
is_admin: 3,
password: CryptoJS.AES.encrypt(formData.password, "swuE9cmCZQwrkYRV").toString(),
};
axios.post(`/apaas/system/v5/org/add/user`, params).then((res) => {
if (res.data.code == 200) {
successFlag.value = true;
step.value = 3;
} else {
ElMessage.error(res.data.data);
}
});
}
}
};
//上一步
const previousStep = () => {
step.value--;
};
//提交表单
const submit = () => {
plplatformPersonFormRef.value.submitForm();
};
//继续创建 清空表单
const continueCreate = () => {
platformAccountFormRef.value.clearForm();
plplatformPersonFormRef.value.clearForm();
step.value = 1;
successFlag.value = false;
};
//取消
const cancel = () => {
router.go(-1);
};
const getOrgTree = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
orgId.value = res.data.data[0].organization_id;
} else {
ElMessage.error(res.data.data);
}
});
};
const getDetail = () => {
axios.get(`/apaas/system/v5/org/user/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
const form = res.data.data;
console.log(form);
platformAccountFormRef.value.setForm({
logo: form.logo ? [{ url: form.logo }] : [],
system_account: form.system_account,
contact_phone: form.contact_phone,
state: form.state,
contact_name: form.contact_name,
contact_email: form.contact_email,
remark: form.remark,
select_role: form.select_role,
});
} else {
ElMessage.error(res.data.data);
}
});
};
onBeforeMount(() => {
getOrgTree();
if (route.query.id) {
getDetail();
}
});
onMounted(() => {});
</script>
<style scoped>
.flex_cloumn {
display: flex;
flex-direction: column;
}
.content_top {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}
/* .content_top::-webkit-scrollbar {
width: 5px;
height: 0px;
}
.content_top::-webkit-scrollbar-thumb {
background: #dedede;
border-radius: 10px;
height: 0px;
}
.content_top::-webkit-scrollbar-track {
background: transparent;
border-radius: 2px;
} */
.content_bottom {
height: 68px;
line-height: 68px;
text-align: right;
padding: 0 20px;
border-top: 1px solid #e6e9ef;
}
.content_process {
border-bottom: 1px solid #e6e9ef;
padding: 38px 16%;
}
.content_main {
flex: 1;
padding: 30px;
box-sizing: border-box;
}
.process_desc {
background-color: #fff;
display: inline-block;
position: absolute;
padding: 0 5px;
font-size: 18px;
color: #202531;
font-weight: bold;
}
.process_desc img {
height: 25px;
width: 25px;
vertical-align: middle;
}
.process_end {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.process_end div {
text-align: center;
}
.step_icon {
color: #fff;
font-weight: 600;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.icon_box {
display: inline-block;
background-color: #2b4695;
width: 48px;
height: 48px;
border-radius: 99px;
position: relative;
border: 3px solid #b0bee8;
vertical-align: middle;
}
.circle {
display: inline-block;
background-color: #a9b1c7;
width: 24px;
height: 24px;
border-radius: 99px;
position: relative;
border: 4px solid #e6e9ef;
vertical-align: middle;
}
.content_process :deep() .el-step.is-horizontal .el-step__line {
height: 4px;
}
.content_process :deep() .el-step__head.is-finish .el-step__line {
background: linear-gradient(to right, #2b4695 50%, #e6e9ef 50%);
}
.process_complete :deep() .el-step__head.is-finish .el-step__line {
background: linear-gradient(to right, #2b4695 100%, #e6e9ef 0%);
}
</style>
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="platformAccountForm"
:rules="platformAccountFormRules"
ref="platformAccountRef"
style="max-width: 66%">
<el-form-item label="头像" prop="logo">
<bg-upload-image
v-model="platformAccountForm.logo"
:showTips="true"
:limit="1"
:fileSize="500"
:fileSizeUnit="'KB'"
listType="picture-card"
:accept="['.jpg', '.jpeg', '.png']"
customTips="请选择图片上传:大小120 * 120像素支持jpg、png等格式,图片需小于500KB"></bg-upload-image>
</el-form-item>
<el-form-item label="账号" prop="system_account">
<el-input v-model="platformAccountForm.system_account" />
</el-form-item>
<el-form-item label="手机号" prop="contact_phone">
<el-input v-model="platformAccountForm.contact_phone" />
</el-form-item>
<el-form-item v-if="!formType" label="密码" prop="password">
<el-input type="password" v-model="platformAccountForm.password" />
</el-form-item>
<el-form-item v-if="!formType" label="确认密码" prop="confirm_password">
<el-input type="password" v-model="platformAccountForm.confirm_password" />
</el-form-item>
<el-form-item label="角色授权" prop="select_role">
<el-select v-model="platformAccountForm.select_role" multiple placeholder="请选择角色" style="width: 100%">
<el-option v-for="item in roleList" :key="item.role_id" :label="item.role_name" :value="item.role_id" />
</el-select>
</el-form-item>
<el-form-item v-if="formType" label="姓名" prop="contact_name">
<el-input v-model="platformAccountForm.contact_name" />
</el-form-item>
<el-form-item v-if="formType" label="邮箱" prop="contact_email">
<el-input v-model="platformAccountForm.contact_email" />
</el-form-item>
<el-form-item v-if="formType" label="备注" prop="remark">
<el-input type="textarea" :rows="3" v-model="platformAccountForm.remark" />
</el-form-item>
<el-form-item label="是否启用" prop="state">
<bg-switch :labels="['否', '是']" :values="[0, 1]" v-model="platformAccountForm.state"></bg-switch>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted, onBeforeMount } from "vue";
import axios from "@/request/http.js";
const props = defineProps({
formType: {
type: Boolean,
default: false, //false 新增 true 编辑
},
id: {
type: String,
default: "",
},
});
const platformAccountForm = reactive({
logo: [],
system_account: "",
contact_phone: "",
password: "",
confirm_password: "",
select_role: "",
state: 1,
contact_name: "",
contact_email: "",
remark: "",
});
const validatePass = (rule, value, callback) => {
if (value !== platformAccountForm.password) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
};
const checkPhone = (rule, value, callback) => {
var phone_ruler = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/;
setTimeout(() => {
if (!phone_ruler.test(value) && value.length !== 0) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
});
};
const validateSystemAccount = (rule, value, callback) => {
let reg = /^[a-zA-Z0-9]+$/;
if (!reg.test(value)) {
callback(new Error("只能输入字母和数字"));
} else {
let params = null;
if (props.id) {
params = { id: parseInt(props.id), system_account: value };
} else {
params = { system_account: value };
}
axios.post(`/apaas/system/v5/user/check/account`, params).then((res) => {
if (res.data.code == 200) {
callback();
} else {
callback(new Error(res.data.data));
}
});
}
};
const checkPhoneRepet = (rule, value, callback) => {
let params = null;
if (props.id) {
params = { id: parseInt(props.id), contact_phone: value };
} else {
params = { id: 0, contact_phone: value };
}
axios.post(`/apaas/system/v5/org/check`, params).then((res) => {
if (res.data.code == 200) {
callback();
} else {
callback(new Error(res.data.data));
}
});
};
const platformAccountFormRules = reactive({
system_account: [
{ required: true, message: "请输入账号", trigger: "blur" },
{ min: 4, message: "帐号长度不得低于4个字符", trigger: "blur" },
{ max: 20, message: "帐号最大长度为20个字符", trigger: "blur" },
{ validator: validateSystemAccount, trigger: "blur" },
],
contact_phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ validator: checkPhone, trigger: "blur" },
{ validator: checkPhoneRepet, trigger: "blur" },
],
select_role: [{ required: true, message: "请选择角色", trigger: "blur" }],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 8, message: "密码长度不得低于8位", trigger: "blur" },
],
confirm_password: [
{ required: true, message: "请确认密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
contact_email: [{ type: "email", message: "请输入正确的邮箱", trigger: "blur" }],
});
const roleList = ref([]);
const platformAccountRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!platformAccountRef) return;
await platformAccountRef.value.validate((valid, fields) => {
if (valid) {
emit("action", platformAccountForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!platformAccountRef) return;
platformAccountRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(platformAccountForm, data);
};
const getRoleList = () => {
axios.get(`/apaas/system/v5/org/select/role?is_admin=3`).then((res) => {
if (res.data.code == 200) {
roleList.value = res.data.data;
} else {
}
});
};
onBeforeMount(() => {
getRoleList();
});
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<el-form
:label-position="'right'"
label-width="120px"
:model="platformPersonForm"
:rules="platformPersonFormRules"
ref="platformPersonFormRef"
style="max-width: 66%">
<el-form-item label="姓名" prop="contact_name">
<el-input v-model="platformPersonForm.contact_name" />
</el-form-item>
<el-form-item label="邮箱" prop="contact_email">
<el-input v-model="platformPersonForm.contact_email" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :rows="3" v-model="platformPersonForm.remark" />
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue";
const platformPersonForm = reactive({
contact_name: "",
contact_email: "",
remark: "",
});
const platformPersonFormRules = reactive({
contact_email: [{ type: "email", message: "请输入正确的邮箱", trigger: "blur" }],
});
const platformPersonFormRef = ref(null);
const emit = defineEmits(["action"]);
const submitForm = async () => {
if (!platformPersonFormRef) return;
await platformPersonFormRef.value.validate((valid, fields) => {
if (valid) {
emit("action", platformPersonForm);
} else {
emit("action", null);
}
});
};
const clearForm = () => {
if (!platformPersonFormRef) return;
platformPersonFormRef.value.resetFields();
};
const setForm = (data) => {
Object.assign(platformPersonForm, data);
};
onMounted(() => {});
defineExpose({ submitForm, clearForm, setForm });
</script>
<template>
<el-tree
ref="treeRef"
class="file-tree"
:data="orgData"
:props="defaultProps"
@node-click="handleNodeClick"
node-key="id"
:highlight-current="true"
:filter-node-method="filterNode"
:expand-on-click-node="false"
:default-expand-all="true">
<template #default="{ node, data }">
<div class="custom_tree_node">
<span class="label-text" :title="data.name">{{ data.name }} </span>
<span
v-if="data.data_type === 2"
class="tree-action-box first_node"
:class="{ first_node_focus: (selectData && selectData.id === data.id) || !selectData }"
@click.stop="showAction($event, data, node)">
<bg-icon class="tree-more" icon="#bg-ic-s-more"></bg-icon>
</span>
<span
v-else
class="tree-action-box"
@click.stop="showAction($event, data, node)">
<bg-icon class="tree-more" icon="#bg-ic-s-more"></bg-icon>
</span>
</div>
</template>
</el-tree>
<Teleport to="body">
<div
ref="treeActionRef"
class="tree-action"
v-show="actionFlag"
:style="{ top: acTop, left: acLeft, bottom: acBottom }">
<!-- 平台用户组织 -->
<div
v-if="selectData && selectData.data_type === 2"
class="action"
@click="treeAction({ type: 'directory', action: 'create', target: null })">
新增目录
</div>
<div
v-if="selectData && selectData.data_type === 2"
class="action"
@click="treeAction({ type: 'org', action: 'create', target: null })">
新增组织
</div>
<!-- 目录 -->
<div
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'create', target: 'local' })">
新增本级目录
</div>
<div
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'create', target: 'child' })">
新增下级目录
</div>
<div
v-if="selectData && selectData.data_type === 0 && selectData.level !== 1"
class="action"
@click="treeAction({ type: 'org', action: 'create', target: 'local' })">
新增本级组织
</div>
<div
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'org', action: 'create', target: 'child' })">
新增下级组织
</div>
<div
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'edit', target: 'local' })">
编辑目录
</div>
<div
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'delete', target: 'local' })">
删除
</div>
<div
:class="{
disable:
mvDataParent.indexOf(selectData) === 0 ||
(mvDataParent.indexOf(selectData) === 1 && mvDataParent[0].data_type == 2),
}"
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'mvup', target: 'local' })">
上移
</div>
<div
:class="{ disable: mvDataParent.indexOf(selectData) === mvDataParent.length - 1 }"
v-if="selectData && selectData.data_type === 0"
class="action"
@click="treeAction({ type: 'directory', action: 'mvdown', target: 'local' })">
下移
</div>
<!-- 组织 -->
<div
v-if="selectData && selectData.data_type === 1"
class="action"
@click="treeAction({ type: 'org', action: 'create', target: 'local' })">
新增本级组织
</div>
<div
v-if="selectData && selectData.data_type === 1"
class="action"
@click="treeAction({ type: 'org', action: 'edit', target: 'local' })">
编辑组织
</div>
<div
v-if="selectData && selectData.data_type === 1"
class="action"
@click="treeAction({ type: 'org', action: 'delete', target: 'local' })">
删除
</div>
<div
:class="{ disable: mvDataParent.indexOf(selectData) === 0 }"
v-if="selectData && selectData.data_type === 1"
class="action"
@click="treeAction({ type: 'org', action: 'mvup', target: 'local' })">
上移
</div>
<div
:class="{ disable: mvDataParent.indexOf(selectData) === mvDataParent.length - 1 }"
v-if="selectData && selectData.data_type === 1"
class="action"
@click="treeAction({ type: 'org', action: 'mvdown', target: 'local' })">
下移
</div>
</div>
</Teleport>
</template>
<script setup>
import { reactive, toRefs, ref, computed, onBeforeMount, onBeforeUnmount, watch, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
const route = useRoute();
const acTop = ref("");
const acLeft = ref("");
const acBottom = ref("");
const actionFlag = ref(false);
const selectData = ref(null);
const selectDataParent = ref(null);
const mvDataParent = ref([]);
const treeRef = ref(null);
const treeActionRef = ref(null);
const bottomGap = ref(30); //弹窗吸底高度
const orgData = ref([]);
const selectNodeObj = ref(null);
const customNodeClass = (data, node) => {
if (data.data_type == 0) {
return "noFocus";
} else {
return "";
}
};
const defaultProps = {
label: "name",
children: "Child",
value: "organization_id",
class: customNodeClass,
};
const getOrgTree = (data) => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
orgData.value = res.data.data || [];
console.log(route.query.id);
if (route.query.id) {
searchItem(orgData.value, route.query.id);
data = selectNodeObj.value;
}
if (data) {
nextTick(() => {
setCurrentNode(data);
});
} else {
nextTick(() => {
setCurrentNode(orgData.value[0].id);
});
}
} else {
ElMessage.error(res.data.data);
}
});
};
const searchItem = (data, id) => {
data.forEach((e) => {
if (e.organization_id == id) {
selectNodeObj.value = e;
} else {
if (e.Child) {
searchItem(e.Child, id);
}
}
});
};
const filterTree = (val) => {
treeRef.value.filter(val);
};
const setCurrentNode = (data) => {
if (data) {
treeRef.value.setCurrentKey(data, true);
const curNode = treeRef.value.getCurrentNode();
selectData.value = curNode;
emit("select", { data: ref(curNode), type: "click" });
} else {
treeRef.value.setCurrentKey(orgData.value[0].id, true);
const curNode = treeRef.value.getCurrentNode();
selectData.value = curNode;
emit("select", { data: ref(curNode), type: "click" });
}
};
const filterNode = (value, data) => {
if (!value) return true;
return data.name.includes(value);
};
const showAction = (e, data, node) => {
acTop.value = "";
acLeft.value = "";
acBottom.value = "";
var allHeight = document.body.scrollHeight;
actionFlag.value = true;
selectData.value = data;
selectDataParent.value = node.parent.data.name ? node.parent.data : null;
mvDataParent.value = node.parent.data.Child ? node.parent.data.Child : node.parent.data;
const rect = e.target.getBoundingClientRect(); //获取点击的dom的位置
nextTick().then(() => {
setTimeout(() => {
var height = window.getComputedStyle(treeActionRef.value).height;
height = parseInt(height);
//判断弹窗位置是否超过屏幕,超过则吸底展示
if (height + rect.y - 17 > allHeight - bottomGap.value) {
acBottom.value = bottomGap.value + "px";
acLeft.value = rect.x + 35 + "px";
} else {
acTop.value = rect.y - 17 + "px";
acLeft.value = rect.x + 35 + "px";
}
});
});
// acTop.value = rect.y - 17 + "px";
// acLeft.value = rect.x + 35 + "px";
};
const isSticky = (data) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
context.font = "14px MicrosoftYaHei";
const { width } = context.measureText(data);
return width > 255 ? true : false;
};
const closeAction = () => {
actionFlag.value = false;
};
const emit = defineEmits(["action", "select"]);
const handleNodeClick = (node, nodeAttr, treeNode, event) => {
if (node.data_type !== 0) {
selectData.value = node;
emit("select", { data: selectData, type: "click" });
} else {
nextTick(() => {
treeRef.value.setCurrentKey(null);
});
}
//只读则无操作事件
closeAction();
};
const treeAction = (params) => {
emit("select", { data: selectData, type: "action" });
let data = null;
if (params.action === "create") {
if (params.target === "local") {
data = selectDataParent;
} else if (params.target === "child") {
data = selectData;
} else {
}
} else if (params.action === "mvup") {
// 已经是第一个元素 或者上一个元素是平台组织 则不可上移 平台组织始终在第一个
if (
mvDataParent.value.indexOf(selectData.value) === 0 ||
(mvDataParent.value.indexOf(selectData.value) === 1 && mvDataParent.value[0].data_type == 2)
) {
// ElMessage.error('已经是第一个元素,不可上移')
return 0;
} else {
let brother = mvDataParent.value[mvDataParent.value.indexOf(selectData.value) - 1];
data = [
{ id: selectData.value.id, sort: brother.sort },
{ id: brother.id, sort: selectData.value.sort },
];
}
} else if (params.action === "mvdown") {
if (mvDataParent.value.indexOf(selectData.value) === mvDataParent.value.length - 1) {
// ElMessage.error('已经是最后一个元素,不可下移')
return 0;
} else {
let brother = mvDataParent.value[mvDataParent.value.indexOf(selectData.value) + 1];
data = [
{ id: selectData.value.id, sort: brother.sort },
{ id: brother.id, sort: selectData.value.sort },
];
}
} else {
data = selectData;
}
emit("action", { type: params.type, action: params.action, data: data });
};
onBeforeMount(() => {
//只读则无操作事件
window.addEventListener("click", closeAction);
window.addEventListener("scroll", closeAction, true);
getOrgTree();
});
onBeforeUnmount(() => {
//只读则无操作事件
window.removeEventListener("click", closeAction);
window.removeEventListener("scroll", closeAction);
});
defineExpose({ getOrgTree, filterTree, setCurrentNode });
</script>
<style scoped>
.tree-action-box {
display: none;
position: absolute;
right: -5px;
top: 0px;
width: 44px;
height: 36px;
line-height: 36px;
text-align: center;
background-color: #f2f3f7;
box-shadow: -3px 0px 8px -3px rgba(0, 7, 101, 0.15);
}
.position_sticky {
position: sticky;
position: -webkit-sticky;
}
.tree-more {
font-size: 12px;
color: #3759be;
}
.file-tree :deep() .el-tree-node__content:hover .tree-action-box {
display: inline-block;
}
.file-tree :deep() .el-tree-node__content:hover + .label-text {
width: calc(100% - 48px);
}
.file-tree :deep() .el-tree-node__content .first_node {
display: inline-block;
background-color: #fff;
box-shadow: none;
}
.file-tree :deep() .el-tree-node__content .first_node_focus {
background-color: #f2f3f7;
box-shadow: -3px 0px 8px -3px rgba(0, 7, 101, 0.15);
}
.file-tree :deep() .el-tree-node__content:hover .first_node {
background-color: #f2f3f7;
box-shadow: -3px 0px 8px -3px rgba(0, 7, 101, 0.15);
}
.file-tree :deep() .el-tree-node > .el-tree-node__children {
overflow: visible;
}
.file-tree :deep() .el-tree-node__content {
position: relative;
}
.action-box:hover .tree-action {
display: block;
}
.label-text {
font-size: 14px;
color: #404a62;
display: inline-block;
width: calc(100% - 24px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tree-action-box:hover + .label-text {
padding: 8px 0;
background-color: var(--el-tree-node-hover-bg-color);
}
.label-text:hover {
padding: 8px 0;
/* background-color: var(--el-tree-node-hover-bg-color); */
width: calc(100% - 48px);
}
.is_active {
padding: 8px 0;
background-color: var(--el-color-primary-light-9);
}
.custom_tree_node {
width: 100%;
font-size: 14px;
color: #202531;
padding-right: 16px;
}
.text_clip {
width: 100%;
display: inline-block;
}
.tree-action .action {
width: 100%;
height: 34px;
line-height: 34px;
padding-left: 16px;
font-size: 14px;
color: #202531;
cursor: pointer;
}
.tree-action :deep().el-upload {
width: 100%;
}
.tree-action .action:hover {
background-color: #eff2fa;
color: #3759be;
}
.tree-action .disable {
cursor: not-allowed;
color: #616f94;
}
.tree-action .disable:hover {
background-color: #fff;
color: #616f94;
}
.tree-action {
/* display: none; */
width: 144px;
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
padding: 4px 0;
border-radius: 4px;
position: fixed;
z-index: 9;
}
.file-tree :deep().el-tree-node__content {
height: 36px !important;
}
.tree-action .disable {
cursor: not-allowed;
color: #616f94;
}
.tree-action .disable:hover {
background-color: #fff;
color: #616f94;
}
.file-tree :deep().noFocus:focus > .el-tree-node__content {
background-color: #fff;
}
</style>
<template>
<div class="page_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="page_content apaas_scroll">
<div class="info_row">
<div class="title">
<div><span class="icon_box"></span> 账号信息</div>
<div class="dashed_line"></div>
</div>
<div class="info_content">
<div class="img_box">
<img v-if="logo" :src="logo" style="height: 96px; width: 96px; border-radius: 99px" alt="" />
<img
v-else
src="/src/assets/imgs/home_ic_user.png"
style="height: 96px; width: 96px; border-radius: 99px"
alt="" />
</div>
<div class="info_box">
<bg-info :data="accountInfo"></bg-info>
</div>
</div>
</div>
<div>
<div class="title">
<div><span class="icon_box"></span> 个人信息</div>
<div class="dashed_line"></div>
</div>
<div class="info_content">
<div class="img_box"></div>
<div class="info_box">
<bg-info v-if="accountType === 2" :data="personInfo"></bg-info>
<bg-info v-if="accountType === 3" :data="personInfo2"></bg-info>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, toRefs, ref, computed, onBeforeMount } from "vue";
import { useRoute } from "vue-router";
import axios from "@/request/http.js";
import { ElMessage } from "element-plus";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const route = useRoute();
const accountInfo = reactive([
{
name: "手机号",
value: "",
nameWidth: 130,
},
{
name: "账号",
value: "",
nameWidth: 130,
},
{
name: "角色",
value: "",
nameWidth: 130,
},
{
name: "所属组织",
value: "",
nameWidth: 130,
},
{
name: "创建人",
value: "",
nameWidth: 130,
},
{
name: "创建账号",
value: "",
nameWidth: 130,
},
{
name: "最后编辑时间",
value: "",
nameWidth: 130,
},
{
name: "创建时间",
value: "",
nameWidth: 130,
},
]);
const personInfo = reactive([
{
name: "姓名",
value: "",
nameWidth: 130,
},
{
name: "邮箱",
value: "",
nameWidth: 130,
},
{
name: "证据类型",
value: "",
nameWidth: 130,
},
{
name: "身份证号",
value: "",
idCard: true,
nameWidth: 130,
},
{
name: "备注",
value: "",
full: true,
nameWidth: 130,
},
]);
const personInfo2 = reactive([
{
name: "姓名",
value: "",
nameWidth: 130,
},
{
name: "邮箱",
value: "",
nameWidth: 130,
},
{
name: "备注",
value: "",
full: true,
nameWidth: 130,
},
]);
const logo = ref("");
const accountType = ref(2); //1.业务系统账号 2.组织管理员账号 3.平台用户账号
const getDetail = () => {
axios.get(`/apaas/system/v5/org/user/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
const detail = res.data.data;
accountInfo[0].value = detail.contact_phone;
accountInfo[1].value = detail.system_account;
accountInfo[2].value = detail.system_role && detail.system_role.length > 0 ? detail.system_role.join("") : "";
accountInfo[3].value = detail.organization;
accountInfo[4].value = detail.created_by;
accountInfo[5].value = detail.created_by_account;
accountInfo[6].value = detail.updated_time;
accountInfo[7].value = detail.created_time;
personInfo[0].value = detail.contact_name;
personInfo[1].value = detail.contact_email;
personInfo[2].value = detail.document_type === 1 ? "身份证" : "";
personInfo[3].value = detail.document_number;
personInfo[4].value = detail.remark;
personInfo2[0].value = detail.contact_name;
personInfo2[1].value = detail.contact_email;
personInfo2[2].value = detail.remark;
logo.value = detail.logo;
accountType.value = detail.is_admin;
} else {
ElMessage.error(res.data.data);
}
});
};
onBeforeMount(() => {
if (route.query.id) {
getDetail();
}
});
</script>
<style scoped>
.page_content {
padding: 15px;
overflow: auto;
}
.info_content {
display: flex;
}
.info_row {
margin-bottom: 40px;
}
.img_box {
width: 120px;
}
.info_box {
width: 60%;
}
.title {
font-size: 18px;
color: #1a1a1a;
font-weight: bold;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.dashed_line {
flex: 1;
height: 1px;
margin: 0 10px;
border-bottom: dashed 1px #dadee7;
}
.icon_box {
display: inline-block;
width: 4px;
height: 14px;
background-color: #3759be;
border-radius: 2px;
margin-right: 5px;
}
</style>
<!-- 角色管理新增 -->
<template>
<role-form></role-form>
</template>
<script setup>
import roleForm from "./role_form.vue";
</script>
<!-- 角色管理 -->
<template>
<div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<div class="top_form bg-scroll">
<el-form ref="form" :rules="rules" :model="formData" class="role_form">
<el-form-item prop="role_name" label="角色名称">
<el-input v-model.trim="formData.role_name" maxlength="50" show-word-limit :disabled="rowType != 0" />
</el-form-item>
<el-form-item prop="role_desc" label="描述">
<el-input
class="decs_box"
type="textarea"
v-model="formData.role_desc"
maxlength="300"
show-word-limit
:autosize="{ minRows: 5 }"
:disabled="rowType != 0"></el-input>
</el-form-item>
<el-form-item label="数据权限" prop="data_purview">
<el-radio-group v-model="formData.data_purview" :disabled="rowType != 0">
<el-radio :label="3">全平台所有</el-radio>
<el-radio :label="2">本组织所有</el-radio>
<el-radio :label="1">仅自己</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="菜单功能权限" prop="permission_arr">
<bg-permission
:values="formData.permission_arr"
:options="permissionData"
:props="defaultProps"
@changeMenu="changeMenu" />
</el-form-item>
<el-form-item label="是否启用" prop="state" class="state_item">
<el-switch
class="bg-switch-ele"
v-model="formData.state"
:active-value="1"
:inactive-value="0"
inline-prompt
active-text="是"
inactive-text="否"
:disabled="rowType != 0" />
</el-form-item>
</el-form>
</div>
<div class="bottom_action">
<el-button @click="goList"> 取消 </el-button>
<el-button type="primary" @click="saveRole"> 保存 </el-button>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, toRefs, ref, onBeforeMount, nextTick } from "vue";
import axios from "../../../../../request/http.js";
import { ElMessage } from "element-plus";
import { useRouter, useRoute } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const router = useRouter();
const route = useRoute();
const form = ref(null);
const checkMenuLength = (rule, value, callback) => {
if (value.length === 0) {
callback(new Error("请选择所需菜单"));
} else {
callback();
}
};
const roleState = reactive({
form,
formData: {
role_name: "",
role_desc: "",
data_purview: 3,
state: 1,
permission_arr: [],
}, // 表单项
rules: {
role_name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
data_purview: [{ required: true, message: "请选择数据权限", trigger: "change" }],
state: [{ required: true, message: "请选择是否启用", trigger: "change" }],
permission_arr: [{ required: true, type: "array", validator: checkMenuLength, trigger: "change" }],
}, // 表单校验规则
defaultProps: {
name: "menu_name",
value: "id",
children: "Child",
remark: "remark",
}, // 菜单框默认配置
permissionData: [], // 菜单数据
rowType: 0,
});
const getMenuTree = () => {
axios.get(`/apaas/system/v5/menu/tree`).then((res) => {
if (res.data.code == 200) {
roleState.permissionData = res.data.data || [];
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取菜单数据
const changeMenu = (val) => {
roleState.formData.permission_arr = val;
}; // 修改选中的菜单
const getRoleDetail = () => {
axios.get(`/apaas/system/v5/role/detail/${route.query.id}`).then((res) => {
if (res.data.code == 200) {
let { role_name, role_desc, data_purview, state, menus } = res.data.data;
roleState.rowType = res.data.data.role_type;
let permission_arr = [];
if (menus && menus.length > 0) {
menus.forEach((e) => {
permission_arr.push(e.id);
});
}
roleState.formData = {
role_name,
role_desc,
data_purview,
state,
permission_arr: [...permission_arr],
};
console.log(roleState.formData.permission_arr);
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取角色详情
const saveRole = () => {
roleState.form.validate((valid) => {
if (valid) {
let params = {
role_name: roleState.formData.role_name,
role_desc: roleState.formData.role_desc,
state: roleState.formData.state,
data_purview: roleState.formData.data_purview,
menu_ids: [...roleState.formData.permission_arr],
};
if (!route.query.id) {
// 新增
axios.put(`/apaas/system/v5/role/create`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
router.push("/system/role");
} else {
ElMessage.error(res.data.data);
}
});
} else {
// 编辑
params.id = +route.query.id;
axios.post(`/apaas/system/v5/role/update`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
router.push("/system/role");
} else {
ElMessage.error(res.data.data);
}
});
}
}
});
}; // 新增或编辑角色的保存
const goList = () => {
router.push("/system/role");
};
onBeforeMount(() => {
getMenuTree();
if (route.query.id) {
// 有id表示是编辑,请求详情,回显
getRoleDetail();
}
});
const { formData, rules, defaultProps, permissionData, rowType } = toRefs(roleState);
</script>
<style lang="scss" scoped>
.detail_container {
width: 100%;
padding: 0 24px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
flex-grow: 1;
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
background-color: #fff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
margin: 0 0 16px;
position: relative;
height: calc(100% - 62px);
.top_form {
height: calc(100% - 68px);
padding: 30px 0 0 40px;
.role_form {
width: 1048px;
:deep().el-form-item {
display: block;
margin-bottom: 24px;
.el-form-item__label {
display: block;
}
.el-input__count {
bottom: -20px;
right: 4px;
color: #a9b1c7;
}
}
.state_item {
display: flex;
}
}
}
.bottom_action {
height: 68px;
border-top: 1px solid #e6e9ef;
padding: 16px;
text-align: right;
.el-button {
width: 92px;
}
}
}
}
</style>
<!-- 角色管理编辑 -->
<template>
<role-form></role-form>
</template>
<script setup>
import roleForm from "../add/role_form.vue";
</script>
<!-- 角色管理 -->
<template>
<div class="detail_container">
<bg-breadcrumb></bg-breadcrumb>
<div class="main_container">
<bg-filter-group @search="changeSearch" v-model="filter.search" placeholder="请输入角色名称">
<template v-slot:left_action>
<div class="apaas_button">
<el-button type="primary" @click="register">
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新增
</el-button>
<el-button type="primary" @click="deleteRows"> 批量删除 </el-button>
<div class="select_text">
<span>已选择</span>
<span class="num">{{ selection.length }}</span>
<span></span>
<span class="can_click_text" @click="clearRoleSelection">清空</span>
</div>
</div>
</template>
</bg-filter-group>
<div class="table_container">
<div class="table bg-scroll">
<bg-table
ref="Bgtable"
:headers="headers"
:rows="tableRows"
:select="true"
:stripe="true"
canEdit
canEditFlag="state"
@selectAc="selectRows">
<template v-slot:state="{ row }">
<bg-switch
@click="changeUseRow(row)"
:labels="['否', '是']"
:values="[0, 1]"
v-model="row.state"
:disabled="row.role_type == 1 || row.role_type == 2" />
</template>
<template v-slot:created_time="{ row }">
{{ row.created_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template>
<template v-slot:action="{ row }">
<bg-table-btn
class="can_click_text"
:click="
() => {
edit_row(row);
}
">
编辑
</bg-table-btn>
<bg-table-btn
class="can_click_text"
:click="
() => {
distribute_user(row);
}
"
:disabled="row.cant_allot == 1">
分配用户
</bg-table-btn>
<bg-table-btn
class="can_click_text"
:click="
() => {
delete_row(row);
}
"
:disabled="row.state == 1 || row.role_type == 1">
删除
</bg-table-btn>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.limit"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div>
</div>
<!-- 删除弹窗 -->
<el-dialog class="dialog_box" title="提示" v-model="delDialog" width="400px">
<div>确定要删除选中的数据吗?</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="delDialog = false">取 消</el-button>
<el-button type="primary" @click="deleteData">确 定</el-button>
</div>
</template>
</el-dialog>
<!-- 分配用户 -->
<el-dialog class="distribute_dialog" title="分配用户" v-model="distributeDialog" width="1062px">
<div class="distribute_box">
<div class="topFilter">
<div class="left">
<span>已选择</span>
<span class="num">{{ userSelection.length }}</span>
<span></span>
<span class="can_click_text" @click="clearUserSelection">清空</span>
</div>
<div class="right">
<el-select v-model="userFilter.is_admin" placeholder="请选择" style="width: 200px">
<el-option
v-for="(item, index) in userTypeList"
:key="'pushOptions' + index"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<el-cascader
v-model="userFilter.organization_id"
:options="orgList"
placeholder="请选择组织"
:props="{
expandTrigger: 'hover',
label: 'name',
value: 'id',
emitPath: false,
checkStrictly: true,
children: 'Child',
}"
:clearable="true"
collapse-tags
style="width: 200px">
<template #default="{ data }">
<span>{{ data.name }}</span>
</template>
</el-cascader>
<el-input
v-model.trim="userFilter.search"
placeholder="请输入内容"
style="width: 200px"
:prefix-icon="Search" />
<el-button type="primary" @click="searchAction">查询</el-button>
<el-button type="default" @click="clearAction">重置</el-button>
</div>
</div>
<div class="table_box">
<div class="user_table bg-scroll">
<bg-table
ref="userTable"
:headers="userHeaders"
:rows="userRows"
:select="true"
:stripe="true"
@selectAc="selectUserRows">
<template v-slot:is_admin="{ row }">
{{ ["", "业务系统账号", "组织管理员账号", "平台用户账号"][row.is_admin] }}
</template>
</bg-table>
</div>
<bg-pagination
:page="userFilter.page"
:size="userFilter.limit"
:total="total"
@change-page="changeUserPage"
@change-size="changeUserSize">
</bg-pagination>
</div>
</div>
<template v-slot:footer>
<div class="apaas_button">
<el-button type="default" @click="distributeDialog = false">取 消</el-button>
<el-button type="primary" @click="distribute">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { reactive, toRefs, ref, onBeforeMount, nextTick } from "vue";
import axios from "../../../../request/http.js";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const router = useRouter();
const Bgtable = ref(null);
const userTable = ref(null);
const state = reactive({
filter: {
page: 1,
limit: 10,
search: "",
},
headers: [
{
label: "角色名",
prop: "role_name",
width: 220,
},
{
label: "创建人",
prop: "created_by",
width: 220,
},
{
label: "创建时间",
prop: "created_time",
width: 276,
},
{
label: "账号数",
prop: "user_count",
},
{
label: "描述",
prop: "role_desc",
minWidth: 346,
},
{
label: "是否启用",
prop: "state",
width: 95,
},
{
label: "操作",
prop: "action",
width: 220,
fixed: "right",
},
],
tableRows: [],
tableTotal: 0,
actionRow: {},
selection: [],
delDialog: false,
delType: 1, // 删除类型 1-单条删除 2-批量删除
});
const userState = reactive({
userFilter: {
is_admin: "",
organization_id: "",
search: "",
limit: 10,
page: 1,
},
userTypeList: [
{
name: "全部类型",
value: "",
},
{
name: "组织管理员账号",
value: 2,
},
{
name: "平台用户账号",
value: 3,
},
],
orgList: [],
userHeaders: [
{
label: "帐号",
prop: "system_account",
},
{
label: "类型",
prop: "is_admin",
},
{
label: "用户手机号",
prop: "contact_phone",
},
{
label: "所属组织",
prop: "organization_name",
},
],
userRows: [],
total: 0,
userSelection: [],
distributeDialog: false, // 分配用户弹窗
});
const getRoleRows = () => {
let params = { ...state.filter };
console.log(params);
axios.get(`/apaas/system/v5/role/list`, { params }).then((res) => {
if (res.data.code == 200) {
state.tableRows = res.data.data || [];
state.tableTotal = res.data.total;
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取角色列表
const getOrgList = () => {
axios.get(`/apaas/system/v5/org/tree`).then((res) => {
if (res.data.code == 200) {
console.log(res.data.data);
userState.orgList = res.data.data || [];
} else {
ElMessage.error(res.data.data);
}
});
}; // 获取组织列表
const changePage = (val) => {
state.filter.page = val;
getRoleRows();
}; // 改变页码
const changeSize = (val) => {
state.filter.limit = val;
changePage(1);
}; // 改变每页条数
const changeSearch = (val) => {
state.filter.search = val;
changePage(1);
}; // 表格关键字筛选
const changeUseRow = (row) => {
if (row.role_type == 1 || row.role_type == 2) {
return;
}
axios.post(`/apaas/system/v5/role/state/${row.id}/${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 selectRows = (data) => {
state.selection = data.selection;
}; // 表格多选
const clearRoleSelection = () => {
Bgtable.value.clearTable();
};
const register = () => {
router.push("/system/role/add");
}; // 新增角色
const edit_row = (row) => {
router.push({
path: "/system/role/edit",
query: {
id: row.id,
},
});
}; // 编辑角色
const distribute_user = (row) => {
clearAction(1);
userState.distributeDialog = true;
state.actionRow = row;
getUserList();
}; // 分配角色按钮
const getUserList = () => {
nextTick(() => {
clearUserSelection();
});
let params = {
limit: userState.userFilter.limit,
page: userState.userFilter.page,
search: userState.userFilter.search,
organization_id: userState.userFilter.organization_id,
is_admin: userState.userFilter.is_admin,
role_id: state.actionRow.id,
};
axios.get(`/apaas/system/v5/role/allotment/list`, { params }).then((res) => {
if (res.data.code == 200) {
console.log(res.data.data);
userState.userRows = res.data.data || [];
userState.total = res.data.total;
nextTick(() => {
userState.userRows.forEach((e) => {
if (e.is_bind == 1) {
console.log(userTable);
userTable.value.toggleRowSelection(e, true);
}
});
});
} else {
ElMessage.error(res.data.data);
}
});
};
const changeUserPage = (val) => {
userState.userFilter.page = val;
getUserList();
};
const changeUserSize = (val) => {
userState.userFilter.limit = val;
changeUserPage(1);
};
const searchAction = () => {
console.log(userState.userFilter);
changeUserPage(1);
};
const clearAction = (type) => {
userState.userFilter = {
is_admin: "",
organization_id: "",
search: "",
limit: 10,
page: 1,
};
if (type != 1) {
changeUserPage(1);
}
};
const clearUserSelection = () => {
console.log(userTable.value);
userTable.value.clearTable();
};
const selectUserRows = (data) => {
userState.userSelection = data.selection;
};
const distribute = () => {
let user_ids = [];
userState.userSelection.forEach((e) => {
user_ids.push(e.id);
});
let params = {
id: state.actionRow.id,
user_ids: user_ids,
};
axios.post(`/apaas/system/v5/role/allotment/user`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
userState.distributeDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
};
const delete_row = (row) => {
state.actionRow = row;
state.delType = 1;
state.delDialog = true;
}; // 删除角色
const deleteRows = () => {
if (state.selection.length == 0) {
ElMessage.error("请先选择要删除的数据");
} else {
state.delType = 2;
state.delDialog = true;
}
}; // 批量删除按钮
const deleteData = () => {
let ids = [];
if (state.delType == 1) {
ids.push(state.actionRow.id);
} else {
state.selection.forEach((e) => {
ids.push(e.id);
});
}
let params = {
ids: [...ids],
};
axios.delete(`/apaas/system/v5/role/delete`, { data: { ids: [...ids] } }).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.delDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
};
onBeforeMount(() => {
getRoleRows();
getOrgList();
});
const { filter, headers, tableRows, tableTotal, delDialog, selection } = toRefs(state);
const { userFilter, userTypeList, orgList, userHeaders, userRows, total, userSelection, distributeDialog } =
toRefs(userState);
</script>
<style lang="scss" scoped>
.detail_container {
width: 100%;
padding: 0 24px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
.main_container {
flex-grow: 1;
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
background-color: #fff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
margin: 0 0 16px;
position: relative;
height: calc(100% - 62px);
.table_container {
height: calc(100% - 70px);
padding: 0 16px;
.table {
max-height: calc(100% - 64px);
}
}
.select_text {
display: inline-block;
margin-left: 40px;
font-size: 14px;
color: #404a62;
.num {
color: #202531;
font-weight: 700;
margin: 0 3px;
}
.can_click_text {
margin-left: 24px;
}
}
}
.distribute_dialog {
.distribute_box {
width: 100%;
height: 626px;
.topFilter {
height: 68px;
padding: 16px;
border-bottom: 1px solid #e6e9ef;
display: flex;
text-align: left;
font-size: 14px;
align-items: center;
.left {
width: 240px;
padding-left: 15px;
color: #404a62;
.num {
color: #202531;
font-weight: 700;
margin: 0 3px;
}
.can_click_text {
margin-left: 24px;
}
}
.right {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
.el-button {
margin: 0;
width: 64px;
}
}
}
.table_box {
padding: 10px 16px;
height: calc(100% - 68px);
.user_table {
max-height: calc(100% - 48px);
:deep().bg-table {
.el-scrollbar {
--el-scrollbar-bg-color: #fff;
}
.el-table__empty-block {
.empty_container {
height: calc(100% - 45px);
}
}
}
}
}
}
}
}
</style>
<style>
.distribute_dialog .el-dialog__footer {
padding: 16px !important;
}
.distribute_dialog .el-dialog__body {
padding: 0px !important;
}
.distribute_dialog {
margin-top: 130px !important;
}
</style>
import autoMaintenance from "./api/auto-maintenance";
export default {
autoMaintenance,
};
import axios from "@/request/http"; // 导入http中创建的axios实例
const autoMaintenance = {
getHostManageList(params) {
return axios({
method: "get",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/page_list`,
params,
});
},
getHostManageDetail(id) {
return axios({
method: "get",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/details?id=${id}`,
});
},
postHostManageState(data) {
return axios({
method: "post",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/state`,
data,
headers: {
"Content-Type": "multipart/form-data",
},
timeout: 0,
});
},
getHostManageIPExceptionList(params) {
return axios({
method: "get",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/ip_exception_list`,
params,
});
},
postHostManageAdd(data) {
return axios({
method: "post",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/add`,
data,
});
},
putHostManageEdit(data) {
return axios({
method: "put",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/edit`,
data,
});
},
uploadHostManageFile(data) {
return axios({
method: "post",
baseURL: "/v1",
url: `/api/add_file`,
data,
headers: {
"Content-Type": "multipart/form-data",
},
});
},
deleteHostManage(data) {
return axios({
method: "delete",
baseURL: "/v1",
url: `/api/automated_mainten/host_manage/del`,
data,
});
},
};
export default autoMaintenance;
......@@ -223,6 +223,25 @@ var timeForMatAdd = function (count) {
};
};
/**
* 传入秒数,输出多少小时,如10秒输出00:00:10
* @param {number} second
*/
var secondeToHour = function (second) {
let ss = second % 60;
let mm = Math.floor((second - ss) / 60) % 60;
let hh = (second - mm * 60 - ss) / 3600;
let deal = (num) => {
if (num < 10) {
return "0" + num;
} else {
return num;
}
};
return `${deal(hh)}:${deal(mm)}:${deal(ss)}`;
};
//计算时间差
var timeDifference = function (startTime, endTime) {
//可以传日期时间或时间戳
......@@ -299,6 +318,18 @@ const downloadBlob = (blobData, type, fileName) => {
window.URL.revokeObjectURL(url);
};
const downloadFile = (url, fileName) => {
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);
};
export {
GetProperty,
dateFormat,
......@@ -317,4 +348,6 @@ export {
getFirstChild,
getImageUrl,
downloadBlob,
downloadFile,
secondeToHour,
};
......@@ -65,9 +65,9 @@ export default {
changeOrigin: true, // true/false, Default: false - changes the origin of the host header to the target URL
secure: false, //解决证书缺失问题
},
"/v1/api": {
target: "https://so.wodcloud.com/v1/api", // 所要代理的目标地址
rewrite: (path) => path.replace(/^\/v1\/api/, ""), // 重写传过来的path路径,比如 `/api/index/1?id=10&name=zs`(注意:path路径最前面有斜杠(/),因此,正则匹配的时候不要忘了是斜杠(/)开头的;选项的 key 也是斜杠(/)开头的)
"/v1": {
target: "https://so.wodcloud.com/v1", // 所要代理的目标地址
rewrite: (path) => path.replace(/^\/v1/, ""), // 重写传过来的path路径,比如 `/api/index/1?id=10&name=zs`(注意:path路径最前面有斜杠(/),因此,正则匹配的时候不要忘了是斜杠(/)开头的;选项的 key 也是斜杠(/)开头的)
changeOrigin: true, // true/false, Default: false - changes the origin of the host header to the target URL
secure: false, //解决证书缺失问题
},
......
......@@ -2,131 +2,128 @@
# yarn lockfile v1
"@babel/parser@^7.16.4":
version "7.18.9"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.18.9.tgz"
integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==
"@babel/parser@^7.20.15", "@babel/parser@^7.21.3":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea"
integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==
"@babel/runtime@^7.12.0":
version "7.20.6"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.20.6.tgz"
integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
dependencies:
regenerator-runtime "^0.13.11"
"@ctrl/tinycolor@^3.4.1":
version "3.4.1"
resolved "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz"
integrity sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==
version "3.6.0"
resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz#53fa5fe9c34faee89469e48f91d51a3766108bc8"
integrity sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==
"@element-plus/icons-vue@^2.0.6":
version "2.0.6"
resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.0.6.tgz"
integrity sha512-lPpG8hYkjL/Z97DH5Ei6w6o22Z4YdNglWCNYOPcB33JCF2A4wye6HFgSI7hEt9zdLyxlSpiqtgf9XcYU+m5mew==
version "2.1.0"
resolved "https://registry.yarnpkg.com/@element-plus/icons-vue/-/icons-vue-2.1.0.tgz#7ad90d08a8c0d5fd3af31c4f73264ca89614397a"
integrity sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==
"@esbuild/android-arm@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80"
integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==
"@floating-ui/core@^1.0.4":
version "1.0.4"
resolved "https://registry.npmmirror.com/@floating-ui/core/-/core-1.0.4.tgz"
integrity sha512-FPFLbg2b06MIw1dqk2SOEMAMX3xlrreGjcui5OTxfBDtaKTmh0kioOVjT8gcfl58juawL/yF+S+gnq8aUYQx/Q==
"@esbuild/linux-loong64@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239"
integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==
"@floating-ui/core@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.3.1.tgz#4d795b649cc3b1cbb760d191c80dcb4353c9a366"
integrity sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==
"@floating-ui/dom@^1.0.1":
version "1.0.12"
resolved "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.0.12.tgz"
integrity sha512-HeG/wHoa2laUHlDX3xkzqlUqliAfa+zqV04LaKIwNCmCNaW2p0fQi4/Kd0LB4GdFoJ2UllLFq5gWnXAd67lg7w==
dependencies:
"@floating-ui/core" "^1.0.4"
"@intlify/core-base@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.1.10.tgz"
integrity sha512-So9CNUavB/IsZ+zBmk2Cv6McQp6vc2wbGi1S0XQmJ8Vz+UFcNn9MFXAe9gY67PreIHrbLsLxDD0cwo1qsxM1Nw==
dependencies:
"@intlify/devtools-if" "9.1.10"
"@intlify/message-compiler" "9.1.10"
"@intlify/message-resolver" "9.1.10"
"@intlify/runtime" "9.1.10"
"@intlify/shared" "9.1.10"
"@intlify/vue-devtools" "9.1.10"
"@intlify/devtools-if@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.1.10.tgz"
integrity sha512-SHaKoYu6sog3+Q8js1y3oXLywuogbH1sKuc7NSYkN3GElvXSBaMoCzW+we0ZSFqj/6c7vTNLg9nQ6rxhKqYwnQ==
dependencies:
"@intlify/shared" "9.1.10"
"@intlify/message-compiler@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.1.10.tgz"
integrity sha512-+JiJpXff/XTb0EadYwdxOyRTB0hXNd4n1HaJ/a4yuV960uRmPXaklJsedW0LNdcptd/hYUZtCkI7Lc9J5C1gxg==
dependencies:
"@intlify/message-resolver" "9.1.10"
"@intlify/shared" "9.1.10"
source-map "0.6.1"
version "1.4.3"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.4.3.tgz#0854a3297ea03894932381f3ea1403fab3a6e602"
integrity sha512-nB/68NyaQlcdY22L+Fgd1HERQ7UGv7XFN+tPxwrEfQL4nKtAP/jIZnZtpUlXbtV+VEGHh6W/63Gy2C5biWI3sA==
dependencies:
"@floating-ui/core" "^1.3.1"
"@intlify/message-resolver@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/message-resolver/-/message-resolver-9.1.10.tgz"
integrity sha512-5YixMG/M05m0cn9+gOzd4EZQTFRUu8RGhzxJbR1DWN21x/Z3bJ8QpDYj6hC4FwBj5uKsRfKpJQ3Xqg98KWoA+w==
"@intlify/core-base@9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.2.2.tgz#5353369b05cc9fe35cab95fe20afeb8a4481f939"
integrity sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==
dependencies:
"@intlify/devtools-if" "9.2.2"
"@intlify/message-compiler" "9.2.2"
"@intlify/shared" "9.2.2"
"@intlify/vue-devtools" "9.2.2"
"@intlify/runtime@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/runtime/-/runtime-9.1.10.tgz"
integrity sha512-7QsuByNzpe3Gfmhwq6hzgXcMPpxz8Zxb/XFI6s9lQdPLPe5Lgw4U1ovRPZTOs6Y2hwitR3j/HD8BJNGWpJnOFA==
"@intlify/devtools-if@9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.2.2.tgz#b13d9ac4b4e2fe6d2e7daa556517a8061fe8bd39"
integrity sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==
dependencies:
"@intlify/message-compiler" "9.1.10"
"@intlify/message-resolver" "9.1.10"
"@intlify/shared" "9.1.10"
"@intlify/shared" "9.2.2"
"@intlify/shared@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/shared/-/shared-9.1.10.tgz"
integrity sha512-Om54xJeo1Vw+K1+wHYyXngE8cAbrxZHpWjYzMR9wCkqbhGtRV5VLhVc214Ze2YatPrWlS2WSMOWXR8JktX/IgA==
"@intlify/message-compiler@9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.2.2.tgz#e42ab6939b8ae5b3d21faf6a44045667a18bba1c"
integrity sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==
dependencies:
"@intlify/shared" "9.2.2"
source-map "0.6.1"
"@intlify/vue-devtools@9.1.10":
version "9.1.10"
resolved "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.1.10.tgz"
integrity sha512-5l3qYARVbkWAkagLu1XbDUWRJSL8br1Dj60wgMaKB0+HswVsrR6LloYZTg7ozyvM621V6+zsmwzbQxbVQyrytQ==
"@intlify/shared@9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.2.2.tgz#5011be9ca2b4ab86f8660739286e2707f9abb4a5"
integrity sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==
"@intlify/vue-devtools@9.2.2":
version "9.2.2"
resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz#b95701556daf7ebb3a2d45aa3ae9e6415aed8317"
integrity sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==
dependencies:
"@intlify/message-resolver" "9.1.10"
"@intlify/runtime" "9.1.10"
"@intlify/shared" "9.1.10"
"@intlify/core-base" "9.2.2"
"@intlify/shared" "9.2.2"
"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
version "2.11.7"
resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz"
resolved "https://registry.yarnpkg.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
"@transloadit/prettier-bytes@0.0.7":
version "0.0.7"
resolved "https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz"
resolved "https://registry.yarnpkg.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz#cdb5399f445fdd606ed833872fa0cabdbc51686b"
integrity sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==
"@types/event-emitter@^0.3.3":
version "0.3.3"
resolved "https://registry.npmmirror.com/@types/event-emitter/-/event-emitter-0.3.3.tgz"
resolved "https://registry.yarnpkg.com/@types/event-emitter/-/event-emitter-0.3.3.tgz#727032a9fc67565f96bbd78b2e2809275c97d7e7"
integrity sha512-UfnOK1pIxO7P+EgPRZXD9jMpimd8QEFcEZ5R67R1UhGbv4zghU5+NE7U8M8G9H5Jc8FI51rqDWQs6FtUfq2e/Q==
"@types/lodash-es@^4.17.6":
version "4.17.6"
resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.6.tgz"
integrity sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==
version "4.17.7"
resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.7.tgz#22edcae9f44aff08546e71db8925f05b33c7cc40"
integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*", "@types/lodash@^4.14.182":
version "4.14.182"
resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.182.tgz"
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
version "4.14.195"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632"
integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==
"@types/web-bluetooth@^0.0.16":
version "0.0.16"
resolved "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8"
integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
"@uppy/companion-client@^2.2.2":
version "2.2.2"
resolved "https://registry.npmmirror.com/@uppy/companion-client/-/companion-client-2.2.2.tgz"
resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-2.2.2.tgz#c70b42fdcca728ef88b3eebf7ee3e2fa04b4923b"
integrity sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==
dependencies:
"@uppy/utils" "^4.1.2"
......@@ -134,7 +131,7 @@
"@uppy/core@^2.1.1":
version "2.3.4"
resolved "https://registry.npmmirror.com/@uppy/core/-/core-2.3.4.tgz"
resolved "https://registry.yarnpkg.com/@uppy/core/-/core-2.3.4.tgz#260b85b6bf3aa03cdc67da231f8c69cfbfdcc84a"
integrity sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==
dependencies:
"@transloadit/prettier-bytes" "0.0.7"
......@@ -148,19 +145,19 @@
"@uppy/store-default@^2.1.1":
version "2.1.1"
resolved "https://registry.npmmirror.com/@uppy/store-default/-/store-default-2.1.1.tgz"
resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-2.1.1.tgz#62a656a099bdaa012306e054d093754cb2d36e3e"
integrity sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==
"@uppy/utils@^4.1.2", "@uppy/utils@^4.1.3":
version "4.1.3"
resolved "https://registry.npmmirror.com/@uppy/utils/-/utils-4.1.3.tgz"
resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-4.1.3.tgz#9d0be6ece4df25f228d30ef40be0f14208258ce3"
integrity sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==
dependencies:
lodash.throttle "^4.1.1"
"@uppy/xhr-upload@^2.0.3":
version "2.1.3"
resolved "https://registry.npmmirror.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz"
resolved "https://registry.yarnpkg.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz#0d4e355332fe0c6eb372d7731315e04d02aeeb18"
integrity sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==
dependencies:
"@uppy/companion-client" "^2.2.2"
......@@ -168,144 +165,144 @@
nanoid "^3.1.25"
"@vitejs/plugin-vue@^3.0.0":
version "3.0.1"
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-3.0.1.tgz"
integrity sha512-Ll9JgxG7ONIz/XZv3dssfoMUDu9qAnlJ+km+pBA0teYSXzwPCIzS/e1bmwNYl5dcQGs677D21amgfYAnzMl17A==
version "3.2.0"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz#a1484089dd85d6528f435743f84cdd0d215bbb54"
integrity sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==
"@vue/compiler-core@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.37.tgz"
integrity sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==
"@vue/compiler-core@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz#7fbf591c1c19e1acd28ffd284526e98b4f581128"
integrity sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/shared" "3.2.37"
"@babel/parser" "^7.21.3"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-dom@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz"
integrity sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==
dependencies:
"@vue/compiler-core" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-sfc@3.2.37", "@vue/compiler-sfc@^3.2.31":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz"
integrity sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.37"
"@vue/compiler-dom" "3.2.37"
"@vue/compiler-ssr" "3.2.37"
"@vue/reactivity-transform" "3.2.37"
"@vue/shared" "3.2.37"
source-map-js "^1.0.2"
"@vue/compiler-dom@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz#f56e09b5f4d7dc350f981784de9713d823341151"
integrity sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==
dependencies:
"@vue/compiler-core" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/compiler-sfc@3.3.4", "@vue/compiler-sfc@^3.2.31":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz#b19d942c71938893535b46226d602720593001df"
integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==
dependencies:
"@babel/parser" "^7.20.15"
"@vue/compiler-core" "3.3.4"
"@vue/compiler-dom" "3.3.4"
"@vue/compiler-ssr" "3.3.4"
"@vue/reactivity-transform" "3.3.4"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
magic-string "^0.25.7"
magic-string "^0.30.0"
postcss "^8.1.10"
source-map "^0.6.1"
source-map-js "^1.0.2"
"@vue/compiler-ssr@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz"
integrity sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==
"@vue/compiler-ssr@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz#9d1379abffa4f2b0cd844174ceec4a9721138777"
integrity sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==
dependencies:
"@vue/compiler-dom" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-dom" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.7", "@vue/devtools-api@^6.1.4":
version "6.2.1"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz"
integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.2.1", "@vue/devtools-api@^6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
"@vue/reactivity-transform@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz"
integrity sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==
"@vue/reactivity-transform@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929"
integrity sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.37"
"@vue/shared" "3.2.37"
"@babel/parser" "^7.20.15"
"@vue/compiler-core" "3.3.4"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
magic-string "^0.25.7"
magic-string "^0.30.0"
"@vue/reactivity@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.37.tgz"
integrity sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==
"@vue/reactivity@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.4.tgz#a27a29c6cd17faba5a0e99fbb86ee951653e2253"
integrity sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==
dependencies:
"@vue/shared" "3.2.37"
"@vue/shared" "3.3.4"
"@vue/runtime-core@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.37.tgz"
integrity sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==
"@vue/runtime-core@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz#4bb33872bbb583721b340f3088888394195967d1"
integrity sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==
dependencies:
"@vue/reactivity" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/reactivity" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/runtime-dom@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz"
integrity sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==
"@vue/runtime-dom@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz#992f2579d0ed6ce961f47bbe9bfe4b6791251566"
integrity sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==
dependencies:
"@vue/runtime-core" "3.2.37"
"@vue/shared" "3.2.37"
csstype "^2.6.8"
"@vue/runtime-core" "3.3.4"
"@vue/shared" "3.3.4"
csstype "^3.1.1"
"@vue/server-renderer@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.37.tgz"
integrity sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==
"@vue/server-renderer@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz#ea46594b795d1536f29bc592dd0f6655f7ea4c4c"
integrity sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==
dependencies:
"@vue/compiler-ssr" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-ssr" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/shared@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.37.tgz"
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
"@vue/shared@3.3.4":
version "3.3.4"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780"
integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
"@vueuse/core@^9.1.0":
version "9.6.0"
resolved "https://registry.npmmirror.com/@vueuse/core/-/core-9.6.0.tgz"
integrity sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==
version "9.13.0"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-9.13.0.tgz#2f69e66d1905c1e4eebc249a01759cf88ea00cf4"
integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==
dependencies:
"@types/web-bluetooth" "^0.0.16"
"@vueuse/metadata" "9.6.0"
"@vueuse/shared" "9.6.0"
"@vueuse/metadata" "9.13.0"
"@vueuse/shared" "9.13.0"
vue-demi "*"
"@vueuse/metadata@9.6.0":
version "9.6.0"
resolved "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.6.0.tgz"
integrity sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==
"@vueuse/metadata@9.13.0":
version "9.13.0"
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-9.13.0.tgz#bc25a6cdad1b1a93c36ce30191124da6520539ff"
integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
"@vueuse/shared@9.6.0":
version "9.6.0"
resolved "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.6.0.tgz"
integrity sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==
"@vueuse/shared@9.13.0":
version "9.13.0"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-9.13.0.tgz#089ff4cc4e2e7a4015e57a8f32e4b39d096353b9"
integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
dependencies:
vue-demi "*"
"@wangeditor/basic-modules@^1.1.7":
version "1.1.7"
resolved "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz#a9c3ccf4ef53332f29550d59d3676e15f395946f"
integrity sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==
dependencies:
is-url "^1.2.4"
"@wangeditor/code-highlight@^1.0.3":
version "1.0.3"
resolved "https://registry.npmmirror.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz#90256857714d5c0cf83ac475aea64db7bf29a7cd"
integrity sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==
dependencies:
prismjs "^1.23.0"
"@wangeditor/core@^1.1.19":
version "1.1.19"
resolved "https://registry.npmmirror.com/@wangeditor/core/-/core-1.1.19.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/core/-/core-1.1.19.tgz#f9155f7fd92d03cb1982405b3b82e54c31f1c2b0"
integrity sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==
dependencies:
"@types/event-emitter" "^0.3.3"
......@@ -317,12 +314,12 @@
"@wangeditor/editor-for-vue@^5.1.12":
version "5.1.12"
resolved "https://registry.npmmirror.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz#f7d5f239b39cdfc01d31151488de8443fe6edc64"
integrity sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==
"@wangeditor/editor@^5.1.14":
version "5.1.23"
resolved "https://registry.npmmirror.com/@wangeditor/editor/-/editor-5.1.23.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/editor/-/editor-5.1.23.tgz#c9d2007b7cb0ceef6b72692b4ee87b01ee2367b3"
integrity sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==
dependencies:
"@uppy/core" "^2.1.1"
......@@ -349,74 +346,74 @@
"@wangeditor/list-module@^1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@wangeditor/list-module/-/list-module-1.0.5.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/list-module/-/list-module-1.0.5.tgz#3fc0b167acddf885536b45fa0c127f9c6adaea33"
integrity sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==
"@wangeditor/table-module@^1.1.4":
version "1.1.4"
resolved "https://registry.npmmirror.com/@wangeditor/table-module/-/table-module-1.1.4.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/table-module/-/table-module-1.1.4.tgz#757d4a5868b2b658041cd323854a4d707c8347e9"
integrity sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==
"@wangeditor/upload-image-module@^1.0.2":
version "1.0.2"
resolved "https://registry.npmmirror.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz#89e9b9467e10cbc6b11dc5748e08dd23aaebee30"
integrity sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==
"@wangeditor/video-module@^1.1.4":
version "1.1.4"
resolved "https://registry.npmmirror.com/@wangeditor/video-module/-/video-module-1.1.4.tgz"
resolved "https://registry.yarnpkg.com/@wangeditor/video-module/-/video-module-1.1.4.tgz#b9df1b3ab2cd53f678b19b4d927e200774a6f532"
integrity sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==
ace-builds@^1.4.13, ace-builds@^1.9.6:
version "1.14.0"
resolved "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.14.0.tgz"
integrity sha512-3q8LvawomApRCt4cC0OzxVjDsZ609lDbm8l0Xl9uqG06dKEq4RT0YXLUyk7J2SxmqIp5YXzZNw767Dr8GKUruw==
version "1.23.1"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.23.1.tgz#2a1a2c2717c21cfd102f641552cf371ab6bce6e4"
integrity sha512-vmLfsfOOvEiQPri2Vz+76FvUalz/nHB7+X2GqonG7rc2V+WrHvqc4xYowt1+fxHH3aWw/pDF2jqKQrd8JNMmiQ==
anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
async-validator@^4.2.5:
version "4.2.5"
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz"
resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
axios@^0.21.1:
version "0.21.4"
resolved "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.14.0"
base64-arraybuffer@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
"chokidar@>=3.0.0 <4.0.0":
version "3.5.3"
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
dependencies:
anymatch "~3.1.2"
......@@ -431,7 +428,7 @@ braces@~3.0.2:
clipboard@^2.0.11:
version "2.0.11"
resolved "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==
dependencies:
good-listener "^1.2.2"
......@@ -440,73 +437,73 @@ clipboard@^2.0.11:
commander@^2.20.3:
version "2.20.3"
resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
compute-scroll-into-view@^1.0.20:
version "1.0.20"
resolved "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43"
integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==
crypto-js@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
css-line-break@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz"
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
dependencies:
utrie "^1.0.2"
cssfilter@0.0.10:
version "0.0.10"
resolved "https://registry.npmmirror.com/cssfilter/-/cssfilter-0.0.10.tgz"
resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae"
integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==
csstype@^2.6.8:
version "2.6.20"
resolved "https://registry.npmmirror.com/csstype/-/csstype-2.6.20.tgz"
integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==
csstype@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
d@1, d@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/d/-/d-1.0.1.tgz"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
dependencies:
es5-ext "^0.10.50"
type "^1.0.1"
dayjs@^1.11.3:
version "1.11.4"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.4.tgz"
integrity sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g==
version "1.11.9"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==
delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
dom7@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/dom7/-/dom7-3.0.0.tgz"
resolved "https://registry.yarnpkg.com/dom7/-/dom7-3.0.0.tgz#b861ce5d67a6becd7aaa3ad02942ff14b1240331"
integrity sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==
dependencies:
ssr-window "^3.0.0-alpha.1"
echarts@^5.3.3:
version "5.3.3"
resolved "https://registry.npmmirror.com/echarts/-/echarts-5.3.3.tgz"
integrity sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==
version "5.4.2"
resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.4.2.tgz#9f38781c9c6ae323e896956178f6956952c77a48"
integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA==
dependencies:
tslib "2.3.0"
zrender "5.3.2"
zrender "5.4.3"
element-plus@^2.2.19:
version "2.2.26"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.26.tgz"
integrity sha512-O/rdY5m9DkclpVg8r3GynyqCunm7MxSR142xSsjrZA77bi7bcwA3SIy6SPEDqHi5R4KqgkGYgKSp4Q4e3irbYg==
version "2.3.7"
resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-2.3.7.tgz#544a127f0e65f51715e3b24ec3ebf545c46859cd"
integrity sha512-h6TxclbaLUJxg/Bv5j/ZKsK+K5yadQliw5+R30HWyE69pXlqXTX24oYx+yw3pA4Dy+lqEDi5501FQ0CORk3OSA==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.6"
......@@ -526,12 +523,12 @@ element-plus@^2.2.19:
entities@~3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/entities/-/entities-3.0.1.tgz"
resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14:
version "0.10.62"
resolved "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.62.tgz"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
dependencies:
es6-iterator "^2.0.3"
......@@ -540,7 +537,7 @@ es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14:
es6-iterator@^2.0.3:
version "2.0.3"
resolved "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
dependencies:
d "1"
......@@ -549,151 +546,153 @@ es6-iterator@^2.0.3:
es6-symbol@^3.1.1, es6-symbol@^3.1.3:
version "3.1.3"
resolved "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.3.tgz"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
dependencies:
d "^1.0.1"
ext "^1.1.2"
esbuild-android-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz#9e4682c36dcf6e7b71b73d2a3723a96e0fdc5054"
integrity sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==
esbuild-android-arm64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz#9861b1f7e57d1dd1f23eeef6198561c5f34b51f6"
integrity sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==
esbuild-darwin-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz#fd30a5ebe28704a3a117126c60f98096c067c8d1"
integrity sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==
esbuild-darwin-arm64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz#c04a3a57dad94a972c66a697a68a25aa25947f41"
integrity sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==
esbuild-freebsd-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz#c404dbd66c98451395b1eef0fa38b73030a7be82"
integrity sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==
esbuild-freebsd-arm64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz#b62cec96138ebc5937240ce3e1b97902963ea74a"
integrity sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==
esbuild-linux-32@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz#495b1cc011b8c64d8bbaf65509c1e7135eb9ddbf"
integrity sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==
esbuild-linux-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz#3f28dd8f986e6ff42f38888ee435a9b1fb916a56"
integrity sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==
esbuild-linux-arm64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz#a52e99ae30246566dc5f33e835aa6ca98ef70e33"
integrity sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==
esbuild-linux-arm@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz#7c33d05a64ec540cf7474834adaa57b3167bbe97"
integrity sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==
esbuild-linux-mips64le@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz#ed062bd844b587be649443831eb84ba304685f25"
integrity sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==
esbuild-linux-ppc64le@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz#c0786fb5bddffd90c10a2078181513cbaf077958"
integrity sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==
esbuild-linux-riscv64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz#579b0e7cc6fce4bfc698e991a52503bb616bec49"
integrity sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==
esbuild-linux-s390x@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz#09eb15c753e249a500b4e28d07c5eef7524a9740"
integrity sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==
esbuild-netbsd-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz#f7337cd2bddb7cc9d100d19156f36c9ca117b58d"
integrity sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==
esbuild-openbsd-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz#1f8bdc49f8a44396e73950a3fb6b39828563631d"
integrity sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==
esbuild-sunos-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz#47d042739365b61aa8ca642adb69534a8eef9f7a"
integrity sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==
esbuild-windows-32@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz#79198c88ec9bde163c18a6b430c34eab098ec21a"
integrity sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==
esbuild-windows-64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz"
integrity sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==
esbuild-windows-arm64@0.14.49:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz#d83c03ff6436caf3262347cfa7e16b0a8049fae7"
integrity sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==
esbuild@^0.14.47:
version "0.14.49"
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.14.49.tgz"
integrity sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==
esbuild-android-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz#20a7ae1416c8eaade917fb2453c1259302c637a5"
integrity sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==
esbuild-android-arm64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz#9cc0ec60581d6ad267568f29cf4895ffdd9f2f04"
integrity sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==
esbuild-darwin-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz#428e1730ea819d500808f220fbc5207aea6d4410"
integrity sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==
esbuild-darwin-arm64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz#b6dfc7799115a2917f35970bfbc93ae50256b337"
integrity sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==
esbuild-freebsd-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz#4e190d9c2d1e67164619ae30a438be87d5eedaf2"
integrity sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==
esbuild-freebsd-arm64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz#18a4c0344ee23bd5a6d06d18c76e2fd6d3f91635"
integrity sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==
esbuild-linux-32@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz#9a329731ee079b12262b793fb84eea762e82e0ce"
integrity sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==
esbuild-linux-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz#532738075397b994467b514e524aeb520c191b6c"
integrity sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==
esbuild-linux-arm64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz#5372e7993ac2da8f06b2ba313710d722b7a86e5d"
integrity sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==
esbuild-linux-arm@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz#e734aaf259a2e3d109d4886c9e81ec0f2fd9a9cc"
integrity sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==
esbuild-linux-mips64le@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz#c0487c14a9371a84eb08fab0e1d7b045a77105eb"
integrity sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==
esbuild-linux-ppc64le@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz#af048ad94eed0ce32f6d5a873f7abe9115012507"
integrity sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==
esbuild-linux-riscv64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz#423ed4e5927bd77f842bd566972178f424d455e6"
integrity sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==
esbuild-linux-s390x@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz#21d21eaa962a183bfb76312e5a01cc5ae48ce8eb"
integrity sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==
esbuild-netbsd-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz#ae75682f60d08560b1fe9482bfe0173e5110b998"
integrity sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==
esbuild-openbsd-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz#79591a90aa3b03e4863f93beec0d2bab2853d0a8"
integrity sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==
esbuild-sunos-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz#fd528aa5da5374b7e1e93d36ef9b07c3dfed2971"
integrity sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==
esbuild-windows-32@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz#0e92b66ecdf5435a76813c4bc5ccda0696f4efc3"
integrity sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==
esbuild-windows-64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz#0fc761d785414284fc408e7914226d33f82420d0"
integrity sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==
esbuild-windows-arm64@0.15.18:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz#5b5bdc56d341d0922ee94965c89ee120a6a86eb7"
integrity sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==
esbuild@^0.15.9:
version "0.15.18"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.18.tgz#ea894adaf3fbc036d32320a00d4d6e4978a2f36d"
integrity sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==
optionalDependencies:
esbuild-android-64 "0.14.49"
esbuild-android-arm64 "0.14.49"
esbuild-darwin-64 "0.14.49"
esbuild-darwin-arm64 "0.14.49"
esbuild-freebsd-64 "0.14.49"
esbuild-freebsd-arm64 "0.14.49"
esbuild-linux-32 "0.14.49"
esbuild-linux-64 "0.14.49"
esbuild-linux-arm "0.14.49"
esbuild-linux-arm64 "0.14.49"
esbuild-linux-mips64le "0.14.49"
esbuild-linux-ppc64le "0.14.49"
esbuild-linux-riscv64 "0.14.49"
esbuild-linux-s390x "0.14.49"
esbuild-netbsd-64 "0.14.49"
esbuild-openbsd-64 "0.14.49"
esbuild-sunos-64 "0.14.49"
esbuild-windows-32 "0.14.49"
esbuild-windows-64 "0.14.49"
esbuild-windows-arm64 "0.14.49"
"@esbuild/android-arm" "0.15.18"
"@esbuild/linux-loong64" "0.15.18"
esbuild-android-64 "0.15.18"
esbuild-android-arm64 "0.15.18"
esbuild-darwin-64 "0.15.18"
esbuild-darwin-arm64 "0.15.18"
esbuild-freebsd-64 "0.15.18"
esbuild-freebsd-arm64 "0.15.18"
esbuild-linux-32 "0.15.18"
esbuild-linux-64 "0.15.18"
esbuild-linux-arm "0.15.18"
esbuild-linux-arm64 "0.15.18"
esbuild-linux-mips64le "0.15.18"
esbuild-linux-ppc64le "0.15.18"
esbuild-linux-riscv64 "0.15.18"
esbuild-linux-s390x "0.15.18"
esbuild-netbsd-64 "0.15.18"
esbuild-openbsd-64 "0.15.18"
esbuild-sunos-64 "0.15.18"
esbuild-windows-32 "0.15.18"
esbuild-windows-64 "0.15.18"
esbuild-windows-arm64 "0.15.18"
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
event-emitter@^0.3.5:
version "0.3.5"
resolved "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz"
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
dependencies:
d "1"
......@@ -701,67 +700,67 @@ event-emitter@^0.3.5:
ext@^1.1.2:
version "1.7.0"
resolved "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
dependencies:
type "^2.7.2"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
follow-redirects@^1.14.0:
version "1.15.1"
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.1.tgz"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
github-markdown-css@^5.1.0:
version "5.1.0"
resolved "https://registry.npmmirror.com/github-markdown-css/-/github-markdown-css-5.1.0.tgz"
integrity sha512-QLtORwHHtUHhPMHu7i4GKfP6Vx5CWZn+NKQXe+cBhslY1HEt0CTEkP4d/vSROKV0iIJSpl4UtlQ16AD8C6lMug==
version "5.2.0"
resolved "https://registry.yarnpkg.com/github-markdown-css/-/github-markdown-css-5.2.0.tgz#9f9e30f16cbc1d3b76110667b7c36ca3d96c9cdc"
integrity sha512-hq5RaCInSUZ48bImOZpkppW2/MT44StRgsbsZ8YA4vJFwLKB/Vo3k7R2t+pUGqO+ThG0QDMi96TewV/B3vyItg==
glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==
dependencies:
delegate "^3.1.2"
has@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/has/-/has-1.0.3.tgz"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
html-void-elements@^2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-2.0.1.tgz"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f"
integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==
html2canvas@^1.4.1:
version "1.4.1"
resolved "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz"
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
dependencies:
css-line-break "^2.1.0"
......@@ -769,134 +768,139 @@ html2canvas@^1.4.1:
i18next@^20.4.0:
version "20.6.1"
resolved "https://registry.npmmirror.com/i18next/-/i18next-20.6.1.tgz"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.6.1.tgz#535e5f6e5baeb685c7d25df70db63bf3cc0aa345"
integrity sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==
dependencies:
"@babel/runtime" "^7.12.0"
immer@^9.0.6:
version "9.0.16"
resolved "https://registry.npmmirror.com/immer/-/immer-9.0.16.tgz"
integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==
version "9.0.21"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176"
integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
immutable@^4.0.0:
version "4.1.0"
resolved "https://registry.npmmirror.com/immutable/-/immutable-4.1.0.tgz"
integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
version "4.3.0"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be"
integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==
install@^0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/install/-/install-0.13.0.tgz#6af6e9da9dd0987de2ab420f78e60d9c17260776"
integrity sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
dependencies:
binary-extensions "^2.0.0"
is-core-module@^2.9.0:
version "2.9.0"
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.9.0.tgz"
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
is-core-module@^2.11.0:
version "2.12.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd"
integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
dependencies:
has "^1.0.3"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-hotkey@^0.2.0:
version "0.2.0"
resolved "https://registry.npmmirror.com/is-hotkey/-/is-hotkey-0.2.0.tgz"
resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.2.0.tgz#1835a68171a91e5c9460869d96336947c8340cef"
integrity sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-url@^1.2.4:
version "1.2.4"
resolved "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz"
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
linkify-it@^4.0.1:
version "4.0.1"
resolved "https://registry.npmmirror.com/linkify-it/-/linkify-it-4.0.1.tgz"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==
dependencies:
uc.micro "^1.0.1"
lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash-unified@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.2.tgz"
integrity sha512-OGbEy+1P+UT26CYi4opY4gebD8cWRDxAT6MAObIVQMiqYdxZr1g3QHWCToVsm31x2NkLS4K3+MC2qInaRMa39g==
version "1.0.3"
resolved "https://registry.yarnpkg.com/lodash-unified/-/lodash-unified-1.0.3.tgz#80b1eac10ed2eb02ed189f08614a29c27d07c894"
integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
lodash.foreach@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
integrity sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz"
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
lodash.toarray@^4.4.0:
version "4.4.0"
resolved "https://registry.npmmirror.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz"
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
integrity sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
magic-string@^0.25.7:
version "0.25.9"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz"
integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
magic-string@^0.30.0:
version "0.30.1"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.1.tgz#ce5cd4b0a81a5d032bd69aab4522299b2166284d"
integrity sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==
dependencies:
sourcemap-codec "^1.4.8"
"@jridgewell/sourcemap-codec" "^1.4.15"
markdown-it@^13.0.1:
version "13.0.1"
resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-13.0.1.tgz"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
dependencies:
argparse "^2.0.1"
......@@ -907,124 +911,124 @@ markdown-it@^13.0.1:
mavon-editor@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/mavon-editor/-/mavon-editor-3.0.1.tgz#0c2660569ded5b29e59d0e429af61eb618783a90"
resolved "https://registry.yarnpkg.com/mavon-editor/-/mavon-editor-3.0.1.tgz#0c2660569ded5b29e59d0e429af61eb618783a90"
integrity sha512-973cYCwv+AB+fcecsU6Ua6UXATxDMaY0Q7QzKQ/GmRW1sg+3DolZDnCGXth7XHDgrmqKTO57N42fVYujt0wfFw==
dependencies:
xss "^1.0.10"
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/mdurl/-/mdurl-1.0.1.tgz"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
mime-match@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/mime-match/-/mime-match-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/mime-match/-/mime-match-1.0.2.tgz#3f87c31e9af1a5fd485fb9db134428b23bbb7ba8"
integrity sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==
dependencies:
wildcard "^1.1.0"
namespace-emitter@^2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz"
resolved "https://registry.yarnpkg.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz#978d51361c61313b4e6b8cf6f3853d08dfa2b17c"
integrity sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==
nanoid@^3.1.25, nanoid@^3.2.0, nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
nanoid@^3.1.25, nanoid@^3.2.0, nanoid@^3.3.6:
version "3.3.6"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
next-tick@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
normalize-wheel-es@^1.2.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz"
resolved "https://registry.yarnpkg.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz#0fa2593d619f7245a541652619105ab076acf09e"
integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.3.1"
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
postcss@^8.1.10, postcss@^8.4.14:
version "8.4.14"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.14.tgz"
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
postcss@^8.1.10, postcss@^8.4.18:
version "8.4.24"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df"
integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==
dependencies:
nanoid "^3.3.4"
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
preact@^10.5.13:
version "10.11.3"
resolved "https://registry.npmmirror.com/preact/-/preact-10.11.3.tgz"
integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==
version "10.15.1"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.15.1.tgz#a1de60c9fc0c79a522d969c65dcaddc5d994eede"
integrity sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==
prismjs@^1.23.0:
version "1.29.0"
resolved "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
dependencies:
picomatch "^2.2.1"
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
resolve@^1.22.1:
version "1.22.1"
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
dependencies:
is-core-module "^2.9.0"
is-core-module "^2.11.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
rollup@^2.75.6:
version "2.77.0"
resolved "https://registry.npmmirror.com/rollup/-/rollup-2.77.0.tgz"
integrity sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==
rollup@^2.79.1:
version "2.79.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7"
integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==
optionalDependencies:
fsevents "~2.3.2"
sass@^1.35.1:
version "1.53.0"
resolved "https://registry.npmmirror.com/sass/-/sass-1.53.0.tgz"
integrity sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==
version "1.63.6"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.63.6.tgz#481610e612902e0c31c46b46cf2dad66943283ea"
integrity sha512-MJuxGMHzaOW7ipp+1KdELtqKbfAWbH7OLIdoSMnVe3EXPMTmxTmlaZDCTsgIpPCs3w99lLo9/zDKkOrJuT5byw==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
......@@ -1032,26 +1036,26 @@ sass@^1.35.1:
scroll-into-view-if-needed@^2.2.28:
version "2.2.31"
resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz"
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587"
integrity sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==
dependencies:
compute-scroll-into-view "^1.0.20"
select@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/select/-/select-1.1.2.tgz"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
slate-history@^0.66.0:
version "0.66.0"
resolved "https://registry.npmmirror.com/slate-history/-/slate-history-0.66.0.tgz"
resolved "https://registry.yarnpkg.com/slate-history/-/slate-history-0.66.0.tgz#ac63fddb903098ceb4c944433e3f75fe63acf940"
integrity sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==
dependencies:
is-plain-object "^5.0.0"
slate@^0.72.0:
version "0.72.8"
resolved "https://registry.npmmirror.com/slate/-/slate-0.72.8.tgz"
resolved "https://registry.yarnpkg.com/slate/-/slate-0.72.8.tgz#5a018edf24e45448655293a68bfbcf563aa5ba81"
integrity sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==
dependencies:
immer "^9.0.6"
......@@ -1060,137 +1064,127 @@ slate@^0.72.0:
snabbdom@^3.1.0:
version "3.5.1"
resolved "https://registry.npmmirror.com/snabbdom/-/snabbdom-3.5.1.tgz"
resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.1.tgz#25f80ef15b194baea703d9d5441892e369de18e1"
integrity sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
source-map@0.6.1, source-map@^0.6.1:
source-map@0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sourcemap-codec@^1.4.8:
version "1.4.8"
resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
ssr-window@^3.0.0-alpha.1:
version "3.0.0"
resolved "https://registry.npmmirror.com/ssr-window/-/ssr-window-3.0.0.tgz"
resolved "https://registry.yarnpkg.com/ssr-window/-/ssr-window-3.0.0.tgz#fd5b82801638943e0cc704c4691801435af7ac37"
integrity sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==
string-format@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b"
resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b"
integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
text-segmentation@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz"
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
dependencies:
utrie "^1.0.2"
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/tiny-warning/-/tiny-warning-1.0.3.tgz"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
tslib@2.3.0:
version "2.3.0"
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
type@^1.0.1:
version "1.2.0"
resolved "https://registry.npmmirror.com/type/-/type-1.2.0.tgz"
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
type@^2.7.2:
version "2.7.2"
resolved "https://registry.npmmirror.com/type/-/type-2.7.2.tgz"
resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.npmmirror.com/uc.micro/-/uc.micro-1.0.6.tgz"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
utrie@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
dependencies:
base64-arraybuffer "^1.0.2"
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
vite@^3.0.0:
version "3.0.2"
resolved "https://registry.npmmirror.com/vite/-/vite-3.0.2.tgz"
integrity sha512-TAqydxW/w0U5AoL5AsD9DApTvGb2iNbGs3sN4u2VdT1GFkQVUfgUldt+t08TZgi23uIauh1TUOQJALduo9GXqw==
version "3.2.7"
resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.7.tgz#35a62826bd4d6b778ae5db8766d023bcd4e7bef3"
integrity sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==
dependencies:
esbuild "^0.14.47"
postcss "^8.4.14"
esbuild "^0.15.9"
postcss "^8.4.18"
resolve "^1.22.1"
rollup "^2.75.6"
rollup "^2.79.1"
optionalDependencies:
fsevents "~2.3.2"
vue-demi@*:
version "0.13.11"
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-demi@^0.14.5:
vue-demi@*, vue-demi@^0.14.5:
version "0.14.5"
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
integrity sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==
vue-i18n@^9.1.7:
version "9.1.10"
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.1.10.tgz"
integrity sha512-jpr7gV5KPk4n+sSPdpZT8Qx3XzTcNDWffRlHV/cT2NUyEf+sEgTTmLvnBAibjOFJ0zsUyZlVTAWH5DDnYep+1g==
version "9.2.2"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.2.2.tgz#aeb49d9424923c77e0d6441e3f21dafcecd0e666"
integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==
dependencies:
"@intlify/core-base" "9.1.10"
"@intlify/shared" "9.1.10"
"@intlify/vue-devtools" "9.1.10"
"@vue/devtools-api" "^6.0.0-beta.7"
"@intlify/core-base" "9.2.2"
"@intlify/shared" "9.2.2"
"@intlify/vue-devtools" "9.2.2"
"@vue/devtools-api" "^6.2.1"
vue-router@^4.0.10:
version "4.1.2"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.2.tgz"
integrity sha512-5BP1qXFncVRwgV/XnqzsKApdMjQPqWIpoUBdL1ynz8HyLxIX/UDAx7Ql2BjmA5CXT/p61JfZvkpiFWFpaqcfag==
version "4.2.2"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.2.2.tgz#b0097b66d89ca81c0986be03da244c7b32a4fd81"
integrity sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==
dependencies:
"@vue/devtools-api" "^6.1.4"
"@vue/devtools-api" "^6.5.0"
vue3-ace-editor@^2.2.2:
version "2.2.2"
resolved "https://registry.npmmirror.com/vue3-ace-editor/-/vue3-ace-editor-2.2.2.tgz"
resolved "https://registry.yarnpkg.com/vue3-ace-editor/-/vue3-ace-editor-2.2.2.tgz#7fd694df2f556e8859edd2322703e039461c9ecc"
integrity sha512-fZ6OWosbU+odLrtrcGC/536QjCigujYJB0Hf6/tBp+ef/ohTadwQAqyBlVzOmvrmzZyubphpV9zkaZcx5Fuivw==
dependencies:
ace-builds "^1.4.13"
......@@ -1198,39 +1192,39 @@ vue3-ace-editor@^2.2.2:
vue "^3.2.26"
vue@^3.2.26, vue@^3.2.31:
version "3.2.37"
resolved "https://registry.npmmirror.com/vue/-/vue-3.2.37.tgz"
integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==
version "3.3.4"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.4.tgz#8ed945d3873667df1d0fcf3b2463ada028f88bd6"
integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==
dependencies:
"@vue/compiler-dom" "3.2.37"
"@vue/compiler-sfc" "3.2.37"
"@vue/runtime-dom" "3.2.37"
"@vue/server-renderer" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-dom" "3.3.4"
"@vue/compiler-sfc" "3.3.4"
"@vue/runtime-dom" "3.3.4"
"@vue/server-renderer" "3.3.4"
"@vue/shared" "3.3.4"
vuex@^4.0.2:
version "4.0.2"
resolved "https://registry.npmmirror.com/vuex/-/vuex-4.0.2.tgz"
integrity sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==
version "4.1.0"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.1.0.tgz#aa1b3ea5c7385812b074c86faeeec2217872e36c"
integrity sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==
dependencies:
"@vue/devtools-api" "^6.0.0-beta.11"
wildcard@^1.1.0:
version "1.1.2"
resolved "https://registry.npmmirror.com/wildcard/-/wildcard-1.1.2.tgz"
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-1.1.2.tgz#a7020453084d8cd2efe70ba9d3696263de1710a5"
integrity sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==
xss@^1.0.10:
version "1.0.14"
resolved "https://registry.npmmirror.com/xss/-/xss-1.0.14.tgz"
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.14.tgz#4f3efbde75ad0d82e9921cc3c95e6590dd336694"
integrity sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==
dependencies:
commander "^2.20.3"
cssfilter "0.0.10"
zrender@5.3.2:
version "5.3.2"
resolved "https://registry.npmmirror.com/zrender/-/zrender-5.3.2.tgz"
integrity sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==
zrender@5.4.3:
version "5.4.3"
resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.4.3.tgz#41ffaf835f3a3210224abd9d6964b48ff01e79f5"
integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ==
dependencies:
tslib "2.3.0"
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