mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-11-13 14:13:47 +08:00
v3.0.0
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.categoryId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.categoryId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item label="分类名称" name="categoryName">
|
||||
<a-input v-model:value="form.categoryName" placeholder="请输入分类名称" />
|
||||
@@ -25,7 +25,7 @@
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
// emit
|
||||
const emit = defineEmits('reloadList');
|
||||
const emit = defineEmits(['reloadList']);
|
||||
|
||||
// 组件
|
||||
const formRef = ref();
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<a-card size="small" :bordered="false" :hoverable="true">
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button @click="addCategory()" type="primary" size="small" v-privilege="`${privilegePrefix}Category:add`">
|
||||
<a-button @click="addCategory()" type="primary" size="small" v-privilege="`${privilegePrefix}category:add`">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
@@ -35,9 +35,11 @@
|
||||
<template #bodyCell="{ record, column }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="addCategory(record.categoryId)" type="link" v-privilege="`${privilegePrefix}Category:addChild`">增加子分类</a-button>
|
||||
<a-button @click="addCategory(undefined, record)" type="link" v-privilege="`${privilegePrefix}Category:edit`">编辑</a-button>
|
||||
<a-button @click="confirmDeleteCategory(record.categoryId)" danger type="link" v-privilege="`${privilegePrefix}Category:delete`">删除</a-button>
|
||||
<a-button @click="addCategory(record.categoryId)" type="link" v-privilege="`${privilegePrefix}category:addChild`">增加子分类</a-button>
|
||||
<a-button @click="addCategory(undefined, record)" type="link" v-privilege="`${privilegePrefix}category:update`">编辑</a-button>
|
||||
<a-button @click="confirmDeleteCategory(record.categoryId)" danger type="link" v-privilege="`${privilegePrefix}category:delete`"
|
||||
>删除</a-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -46,8 +48,8 @@
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, computed } from 'vue';
|
||||
import { Modal, message } from 'ant-design-vue';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import CategoryFormModal from './category-form-modal.vue';
|
||||
import { categoryApi } from '/@/api/business/category/category-api';
|
||||
@@ -65,7 +67,7 @@
|
||||
},
|
||||
];
|
||||
const columName = computed(() => {
|
||||
let find = columnNameList.find((e) => e.categoryType == props.categoryType);
|
||||
let find = columnNameList.find((e) => e.categoryType === props.categoryType);
|
||||
return find ? find.columnName : '';
|
||||
});
|
||||
|
||||
@@ -74,8 +76,8 @@
|
||||
categoryType: Number,
|
||||
privilegePrefix: {
|
||||
type: String,
|
||||
default: 'goods'
|
||||
}
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
// ------------------------------ 查询 ------------------------------
|
||||
@@ -100,8 +102,7 @@
|
||||
categoryType: props.categoryType,
|
||||
};
|
||||
let responseModel = await categoryApi.queryCategoryTree(queryForm);
|
||||
const list = responseModel.data;
|
||||
tableData.value = list;
|
||||
tableData.value = responseModel.data;
|
||||
} catch (e) {
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
@@ -152,7 +153,7 @@
|
||||
try {
|
||||
SmartLoading.show();
|
||||
await categoryApi.deleteCategoryById(categoryId);
|
||||
message.success('撤销成功');
|
||||
message.success('删除成功');
|
||||
queryList();
|
||||
} catch (e) {
|
||||
smartSentry.captureError(e);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<CategoryTreeTable :category-type="CATEGORY_TYPE_ENUM.DEMO.value" :privilegePrefix="'custom'"/>
|
||||
<CategoryTreeTable :category-type="CATEGORY_TYPE_ENUM.DEMO.value" :privilegePrefix="'custom:'"/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-drawer :title="form.goodsId ? '编辑' : '添加'" :width="500" :visible="visible" :body-style="{ paddingBottom: '80px' }" @close="onClose">
|
||||
<a-drawer :title="form.goodsId ? '编辑' : '添加'" :width="500" :open="visible" :body-style="{ paddingBottom: '80px' }" @close="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
|
||||
<a-form-item label="商品分类" name="categoryId">
|
||||
<CategoryTree v-model:value="form.categoryId" placeholder="请选择商品分类" :categoryType="CATEGORY_TYPE_ENUM.GOODS.value" />
|
||||
@@ -67,7 +67,7 @@
|
||||
import DictSelect from '/@/components/support/dict-select/index.vue';
|
||||
|
||||
// emit
|
||||
const emit = defineEmits('reloadList');
|
||||
const emit = defineEmits(['reloadList']);
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="快速筛选" class="smart-query-form-item">
|
||||
<a-radio-group v-model:value="queryForm.shelvesFlag" @change="queryData">
|
||||
<a-radio-group v-model:value="queryForm.shelvesFlag" @change="onSearch">
|
||||
<a-radio-button :value="undefined">全部</a-radio-button>
|
||||
<a-radio-button :value="true">上架</a-radio-button>
|
||||
<a-radio-button :value="false">下架</a-radio-button>
|
||||
@@ -41,7 +41,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="queryData" v-privilege="'goods:query'">
|
||||
<a-button type="primary" @click="onSearch" v-privilege="'goods:query'">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -69,12 +69,26 @@
|
||||
新建
|
||||
</a-button>
|
||||
|
||||
<a-button @click="confirmBatchDelete" type="danger" size="small" :disabled="selectedRowKeyList.length == 0" v-privilege="'goods:batchDelete'">
|
||||
<a-button @click="confirmBatchDelete" danger size="small" :disabled="selectedRowKeyList.length === 0" v-privilege="'goods:batchDelete'">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
批量删除
|
||||
</a-button>
|
||||
|
||||
<a-button @click="showImportModal" type="primary" size="small" v-privilege="'goods:importGoods'">
|
||||
<template #icon>
|
||||
<ImportOutlined />
|
||||
</template>
|
||||
导入
|
||||
</a-button>
|
||||
|
||||
<a-button @click="onExportGoods" type="primary" size="small" v-privilege="'goods:exportGoods'">
|
||||
<template #icon>
|
||||
<ExportOutlined />
|
||||
</template>
|
||||
导出
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="smart-table-setting-block">
|
||||
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.ERP.GOODS" :refresh="queryData" />
|
||||
@@ -127,6 +141,34 @@
|
||||
</div>
|
||||
|
||||
<GoodsFormModal ref="formModal" @reloadList="queryData" />
|
||||
|
||||
<a-modal v-model:open="importModalShowFlag" title="导入" @onCancel="hideImportModal" @ok="hideImportModal">
|
||||
<div style="text-align: center; width: 400px; margin: 0 auto">
|
||||
<a-button @click="downloadExcel"> <download-outlined />第一步:下载模板</a-button>
|
||||
<br />
|
||||
<br />
|
||||
<a-upload
|
||||
v-model:fileList="fileList"
|
||||
name="file"
|
||||
:multiple="false"
|
||||
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||||
accept=".xls,.xlsx"
|
||||
:before-upload="beforeUpload"
|
||||
@remove="handleRemove"
|
||||
>
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
第二步:选择文件
|
||||
</a-button>
|
||||
</a-upload>
|
||||
|
||||
<br />
|
||||
<a-button @click="onImportGoods">
|
||||
<ImportOutlined />
|
||||
第三步:开始导入
|
||||
</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
@@ -144,6 +186,8 @@
|
||||
import { GOODS_STATUS_ENUM } from '/@/constants/business/erp/goods-const';
|
||||
import DictSelect from '/@/components/support/dict-select/index.vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const.js';
|
||||
import FileUpload from '/@/components/support/file-upload/index.vue';
|
||||
|
||||
// ---------------------------- 表格列 ----------------------------
|
||||
|
||||
@@ -218,6 +262,12 @@
|
||||
queryData();
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryData();
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
async function queryData() {
|
||||
tableLoading.value = true;
|
||||
@@ -306,4 +356,60 @@
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------- 导出和导入 ---------------------------------
|
||||
// 导入弹窗
|
||||
const importModalShowFlag = ref(false);
|
||||
|
||||
const fileList = ref([]);
|
||||
// 显示导入
|
||||
function showImportModal() {
|
||||
fileList.value = [];
|
||||
importModalShowFlag.value = true;
|
||||
}
|
||||
|
||||
// 关闭 导入
|
||||
function hideImportModal() {
|
||||
importModalShowFlag.value = false;
|
||||
}
|
||||
|
||||
function handleChange() {}
|
||||
|
||||
function handleDrop() {}
|
||||
|
||||
function handleRemove(file) {
|
||||
const index = fileList.value.indexOf(file);
|
||||
const newFileList = fileList.value.slice();
|
||||
newFileList.splice(index, 1);
|
||||
fileList.value = newFileList;
|
||||
}
|
||||
function beforeUpload(file) {
|
||||
fileList.value = [...(fileList.value || []), file];
|
||||
return false;
|
||||
}
|
||||
|
||||
function downloadExcel() {
|
||||
window.open('https://smartadmin.vip/cdn/%E5%95%86%E5%93%81%E6%A8%A1%E6%9D%BF.xls');
|
||||
}
|
||||
|
||||
async function onImportGoods() {
|
||||
const formData = new FormData();
|
||||
fileList.value.forEach((file) => {
|
||||
formData.append('file', file.originFileObj);
|
||||
});
|
||||
|
||||
SmartLoading.show();
|
||||
try {
|
||||
let res = await goodsApi.importGoods(formData);
|
||||
message.success(res.msg);
|
||||
} catch (e) {
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
|
||||
async function onExportGoods() {
|
||||
await goodsApi.exportGoods();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -180,6 +180,11 @@
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,100 +8,99 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.bankId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit"
|
||||
@cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.bankId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
|
||||
<a-form-item label="开户银行" name="bankName">
|
||||
<a-input v-model:value="form.bankName" placeholder="请输入开户银行"/>
|
||||
<a-input v-model:value="form.bankName" placeholder="请输入开户银行" />
|
||||
</a-form-item>
|
||||
<a-form-item label="账户名称" name="accountName">
|
||||
<a-input v-model:value="form.accountName" placeholder="请输入账户名称"/>
|
||||
<a-input v-model:value="form.accountName" placeholder="请输入账户名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="账号" name="accountNumber">
|
||||
<a-input v-model:value="form.accountNumber" placeholder="请输入账号"/>
|
||||
<a-input v-model:value="form.accountNumber" placeholder="请输入账号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="是否对公" name="businessFlag">
|
||||
<a-switch v-model:checked="businessFlagChecked" @change="businessFlagCheckedChange"/>
|
||||
<a-switch v-model:checked="businessFlagChecked" @change="businessFlagCheckedChange" />
|
||||
</a-form-item>
|
||||
<a-form-item label="启用状态" name="disabledFlag">
|
||||
<a-switch v-model:checked="enabledChecked" @change="enabledCheckedChange"/>
|
||||
<a-switch v-model:checked="enabledChecked" @change="enabledCheckedChange" />
|
||||
</a-form-item>
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea v-model:value="form.remark" :rows="2"/>
|
||||
<a-textarea v-model:value="form.remark" :rows="2" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref, reactive} from 'vue';
|
||||
import {message} from 'ant-design-vue';
|
||||
import { SmartLoading } from "/@/components/framework/smart-loading";
|
||||
import {bankApi} from '/@/api/business/oa/bank-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { ref, reactive } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { bankApi } from '/@/api/business/oa/bank-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const props = defineProps({
|
||||
enterpriseId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
const props = defineProps({
|
||||
enterpriseId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
// emit
|
||||
const emit = defineEmits(['reloadList']);
|
||||
|
||||
// ---------------------- 显示、隐藏 ----------------------
|
||||
// 是否展示
|
||||
const visible = ref(false);
|
||||
function showModal(rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData) {
|
||||
Object.assign(form, rowData);
|
||||
businessFlagChecked.value = rowData.businessFlag;
|
||||
enabledChecked.value = !rowData.disabledFlag;
|
||||
}
|
||||
form.enterpriseId = props.enterpriseId;
|
||||
visible.value = true;
|
||||
}
|
||||
});
|
||||
// emit
|
||||
const emit = defineEmits(['reloadList']);
|
||||
|
||||
// ---------------------- 显示、隐藏 ----------------------
|
||||
// 是否展示
|
||||
const visible = ref(false);
|
||||
function showModal(rowData) {
|
||||
Object.assign(form, formDefault);
|
||||
if (rowData) {
|
||||
Object.assign(form, rowData);
|
||||
businessFlagChecked.value = rowData.businessFlag;
|
||||
enabledChecked.value = !rowData.disabledFlag;
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
}
|
||||
form.enterpriseId = props.enterpriseId;
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
}
|
||||
// ---------------------- 表单 ----------------------
|
||||
|
||||
// ---------------------- 表单 ----------------------
|
||||
// 组件
|
||||
const formRef = ref();
|
||||
|
||||
// 组件
|
||||
const formRef = ref();
|
||||
const formDefault = {
|
||||
bankId: undefined,
|
||||
enterpriseId: undefined,
|
||||
bankName: '',
|
||||
accountName: '',
|
||||
accountNumber: '',
|
||||
businessFlag: false,
|
||||
disabledFlag: false,
|
||||
remark: '',
|
||||
};
|
||||
let form = reactive({ ...formDefault });
|
||||
const rules = {
|
||||
bankName: [{ required: true, message: '请输入开户银行' }],
|
||||
accountName: [{ required: true, message: '请输入账户名称' }],
|
||||
accountNumber: [{ required: true, message: '请输入账号' }],
|
||||
};
|
||||
|
||||
const formDefault = {
|
||||
bankId: undefined,
|
||||
enterpriseId: undefined,
|
||||
bankName: '',
|
||||
accountName: '',
|
||||
accountNumber: '',
|
||||
businessFlag: false,
|
||||
disabledFlag: false,
|
||||
remark: '',
|
||||
};
|
||||
let form = reactive({...formDefault});
|
||||
const rules = {
|
||||
bankName: [{required: true, message: '请输入开户银行'}],
|
||||
accountName: [{required: true, message: '请输入账户名称'}],
|
||||
accountNumber: [{required: true, message: '请输入账号'}],
|
||||
};
|
||||
const businessFlagChecked = ref(false);
|
||||
const enabledChecked = ref(true);
|
||||
|
||||
const businessFlagChecked = ref(false);
|
||||
const enabledChecked = ref(true);
|
||||
function businessFlagCheckedChange(checked) {
|
||||
form.businessFlag = checked;
|
||||
}
|
||||
function enabledCheckedChange(checked) {
|
||||
form.disabledFlag = !checked;
|
||||
}
|
||||
|
||||
function businessFlagCheckedChange(checked) {
|
||||
form.businessFlag = checked;
|
||||
}
|
||||
function enabledCheckedChange(checked) {
|
||||
form.disabledFlag = !checked;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
formRef.value
|
||||
function onSubmit() {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
SmartLoading.show();
|
||||
@@ -121,13 +120,12 @@ function onSubmit() {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
debugger
|
||||
console.log('error', error);
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
showModal,
|
||||
});
|
||||
defineExpose({
|
||||
showModal,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
<div class="header">
|
||||
<div>
|
||||
关键字:
|
||||
<a-input style="width: 250px" v-model:value="queryForm.keywords" placeholder="姓名/手机号/登录账号" />
|
||||
<a-button class="button-style" type="primary" @click="queryEmployee">搜索</a-button>
|
||||
<a-input style="width: 250px" v-model:value="queryForm.keyword" placeholder="姓名/手机号/登录账号" />
|
||||
<a-button class="button-style" type="primary" @click="onSearch">搜索</a-button>
|
||||
<a-button class="button-style" type="default" @click="resetQueryEmployee">重置</a-button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a-button class="button-style" type="primary" @click="addEmployee" v-privilege="'enterprise:addEmployee'"> 添加员工 </a-button>
|
||||
<a-button class="button-style" type="primary" danger @click="batchDelete" v-privilege="'enterprise:deleteEmployee'"> 批量移除 </a-button>
|
||||
<a-button class="button-style" type="primary" @click="addEmployee" v-privilege="'oa:enterprise:addEmployee'"> 添加员工 </a-button>
|
||||
<a-button class="button-style" type="primary" danger @click="batchDelete" v-privilege="'oa:enterprise:deleteEmployee'"> 批量移除 </a-button>
|
||||
</div>
|
||||
</div>
|
||||
<a-table
|
||||
@@ -40,7 +40,7 @@
|
||||
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'operate'">
|
||||
<a @click="deleteEmployee(record.employeeId)" v-privilege="'enterprise:deleteEmployee'">移除</a>
|
||||
<a @click="deleteEmployee(record.employeeId)" v-privilege="'oa:enterprise:deleteEmployee'">移除</a>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
@@ -122,7 +122,7 @@
|
||||
pageNum: 1,
|
||||
pageSize: PAGE_SIZE,
|
||||
enterpriseId: undefined,
|
||||
keywords: undefined,
|
||||
keyword: undefined,
|
||||
};
|
||||
// 查询表单
|
||||
const queryForm = reactive({ ...defaultQueryForm });
|
||||
@@ -131,7 +131,12 @@
|
||||
const tableLoading = ref(false);
|
||||
|
||||
function resetQueryEmployee() {
|
||||
queryForm.keywords = '';
|
||||
queryForm.keyword = '';
|
||||
queryEmployee();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryEmployee();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -183,6 +183,11 @@
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.invoiceId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.invoiceId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item label="开票抬头" name="invoiceHeads">
|
||||
<a-input v-model:value="form.invoiceHeads" placeholder="请输入开票抬头" />
|
||||
@@ -36,7 +36,7 @@
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { invoiceApi } from '/@/api/business/oa/invoice-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const props = defineProps({
|
||||
enterpriseId: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-modal :visible="visible" title="添加" :width="700" forceRender ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" title="添加" :width="700" forceRender ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }">
|
||||
<a-form-item label="企业名称" name="enterpriseName">
|
||||
<a-input v-model:value="form.enterpriseName" placeholder="请输入企业名称" />
|
||||
@@ -72,7 +72,7 @@
|
||||
defineExpose({
|
||||
showModal,
|
||||
});
|
||||
const emit = defineEmits('refresh');
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// --------------------- modal 显示与隐藏 ---------------------
|
||||
// 是否展示
|
||||
@@ -134,7 +134,7 @@
|
||||
unifiedSocialCreditCode: undefined,
|
||||
businessLicense: undefined,
|
||||
contact: undefined,
|
||||
enterpriseLogo:undefined,
|
||||
enterpriseLogo: undefined,
|
||||
contactPhone: undefined,
|
||||
email: undefined,
|
||||
province: undefined,
|
||||
|
||||
@@ -51,18 +51,18 @@
|
||||
|
||||
<script setup>
|
||||
import _ from 'lodash';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import BankList from './components/enterprise-bank-list.vue';
|
||||
import EmployeeList from './components/enterprise-employee-list.vue';
|
||||
import InvoiceList from './components/enterprise-invoice-list.vue';
|
||||
import EnterpriseOperate from './components/enterprise-operate-modal.vue';
|
||||
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import DataTracer from '/@/components/support/data-tracer/index.vue';
|
||||
import FilePreview from '/@/components/support/file-preview/index.vue';
|
||||
import { DATA_TRACER_TYPE_ENUM } from '/@/constants/support/data-tracer-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import BankList from './components/enterprise-bank-list.vue';
|
||||
import EmployeeList from './components/enterprise-employee-list.vue';
|
||||
import InvoiceList from './components/enterprise-invoice-list.vue';
|
||||
import EnterpriseOperate from './components/enterprise-operate-modal.vue';
|
||||
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import DataTracer from '/@/components/support/data-tracer/index.vue';
|
||||
import FilePreview from '/@/components/support/file-preview/index.vue';
|
||||
import { DATA_TRACER_TYPE_ENUM } from '/@/constants/support/data-tracer-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const route = useRoute();
|
||||
let enterpriseId = ref();
|
||||
@@ -75,7 +75,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
//编辑
|
||||
const operateRef = ref();
|
||||
function showUpdate(){
|
||||
function showUpdate() {
|
||||
operateRef.value.showModal(enterpriseId.value);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-form class="smart-query-form" v-privilege="'enterprise:query'">
|
||||
<a-form class="smart-query-form" v-privilege="'oa:enterprise:query'">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="关键字" class="smart-query-form-item">
|
||||
<a-input style="width: 300px" v-model:value="queryForm.keywords" placeholder="企业名称/联系人/联系电话" />
|
||||
@@ -16,18 +16,18 @@
|
||||
|
||||
<a-form-item label="创建时间" class="smart-query-form-item">
|
||||
<a-space direction="vertical" :size="12">
|
||||
<a-range-picker v-model:value="searchDate" :ranges="defaultTimeRanges" @change="dateChange" />
|
||||
<a-range-picker v-model:value="searchDate" :presets="defaultTimeRanges" @change="dateChange" />
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery">
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -40,12 +40,18 @@
|
||||
<a-card size="small" :bordered="false" :hoverable="true">
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button @click="add()" v-privilege="'enterprise:add'" type="primary" size="small">
|
||||
<a-button @click="add()" v-privilege="'oa:enterprise:add'" type="primary" size="small">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
新建企业
|
||||
</a-button>
|
||||
<a-button @click="exportExcel()" v-privilege="'oa:enterprise:exportExcel'" type="primary" size="small">
|
||||
<template #icon>
|
||||
<FileExcelOutlined />
|
||||
</template>
|
||||
导出数据
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="smart-table-setting-block">
|
||||
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE" :refresh="ajaxQuery" />
|
||||
@@ -74,8 +80,8 @@
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="update(record.enterpriseId)" v-privilege="'enterprise:edit'" type="link">编辑</a-button>
|
||||
<a-button @click="confirmDelete(record.enterpriseId)" danger v-privilege="'enterprise:delete'" type="link">删除</a-button>
|
||||
<a-button @click="update(record.enterpriseId)" size="small" v-privilege="'oa:enterprise:update'" type="link">编辑</a-button>
|
||||
<a-button @click="confirmDelete(record.enterpriseId)" size="small" danger v-privilege="'oa:enterprise:delete'" type="link">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -168,7 +174,7 @@
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
fixed: 'right',
|
||||
// fixed: 'right',
|
||||
width: 100,
|
||||
},
|
||||
]);
|
||||
@@ -196,6 +202,11 @@
|
||||
queryForm.endTime = dateStrings[1];
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
searchDate.value = [];
|
||||
Object.assign(queryForm, queryFormState);
|
||||
@@ -216,6 +227,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------- 导出 ---------------------------
|
||||
async function exportExcel() {
|
||||
await enterpriseApi.exportExcel(queryForm);
|
||||
}
|
||||
|
||||
// --------------------------- 删除 ---------------------------
|
||||
|
||||
function confirmDelete(enterpriseId) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:title="formData.noticeId ? '编辑' : '新建'"
|
||||
:visible="visibleFlag"
|
||||
:open="visibleFlag"
|
||||
:width="1000"
|
||||
:footerStyle="{ textAlign: 'right' }"
|
||||
@close="onClose"
|
||||
@@ -103,7 +103,7 @@
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import lodash from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
|
||||
@@ -178,7 +178,7 @@
|
||||
SmartLoading.show();
|
||||
const result = await noticeApi.getUpdateNoticeInfo(noticeId);
|
||||
const attachment = result.data.attachment;
|
||||
if (!lodash.isEmpty(attachment)) {
|
||||
if (!_.isEmpty(attachment)) {
|
||||
defaultFileList.value = attachment;
|
||||
} else {
|
||||
defaultFileList.value = [];
|
||||
@@ -287,7 +287,7 @@
|
||||
const defaultFileList = ref([]);
|
||||
function changeAttachment(fileList) {
|
||||
defaultFileList.value = fileList;
|
||||
formData.attachment = lodash.isEmpty(fileList) ? [] : fileList;
|
||||
formData.attachment = _.isEmpty(fileList) ? [] : fileList;
|
||||
}
|
||||
|
||||
// ----------------------- 以下是暴露的方法内容 ------------------------
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal title="选择部门" v-model:visible="visibleFlag" :maskClosable="false" :width="768" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal title="选择部门" v-model:open="visibleFlag" :maskClosable="false" :width="768" @ok="onSubmit" @cancel="onClose">
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane :key="1" tab="选择员工">
|
||||
<NoticeFormVisibleTransferEmployee :employeeList="employeeList" @onChange="onChangeEmployee" />
|
||||
|
||||
@@ -34,171 +34,171 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
|
||||
import lodash from 'lodash';
|
||||
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
|
||||
import { departmentApi } from '/@/api/system/department/department-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const props = defineProps({
|
||||
// 已选择的部门数据列表
|
||||
departmentList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['onChange']);
|
||||
|
||||
const treeData = ref([]);
|
||||
async function queryDepartmentTree() {
|
||||
try {
|
||||
const result = await departmentApi.queryDepartmentTree();
|
||||
if (!lodash.isEmpty(result.data)) {
|
||||
treeData.value = result.data;
|
||||
setExpanded();
|
||||
}
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认展开的节点
|
||||
const expandedKeys = ref([]);
|
||||
function setExpanded() {
|
||||
expandedKeys.value = [treeData.value[0].departmentId];
|
||||
}
|
||||
|
||||
// 选择的部门列表数据
|
||||
const selectedList = ref([]);
|
||||
|
||||
// 选择的部门列表Ids
|
||||
const selectedIds = computed(() => {
|
||||
return selectedList.value.map((item) => item.dataId);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.departmentList,
|
||||
(newVal) => {
|
||||
selectedList.value = newVal;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 检查是否已选
|
||||
function checkExists(dataId) {
|
||||
return selectedIds.value.includes(dataId);
|
||||
}
|
||||
|
||||
// 点击左边添加
|
||||
function onSelectAdd(name, departmentId) {
|
||||
if (checkExists(departmentId)) {
|
||||
return;
|
||||
}
|
||||
selectedList.value.push({
|
||||
dataName: name,
|
||||
dataId: departmentId,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value,
|
||||
const props = defineProps({
|
||||
// 已选择的部门数据列表
|
||||
departmentList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
// 点击右边移除
|
||||
function onRemove(index) {
|
||||
selectedList.value.splice(index, 1);
|
||||
onChangeEmit();
|
||||
}
|
||||
const emits = defineEmits(['onChange']);
|
||||
|
||||
function onChangeEmit() {
|
||||
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
|
||||
}
|
||||
const treeData = ref([]);
|
||||
async function queryDepartmentTree() {
|
||||
try {
|
||||
const result = await departmentApi.queryDepartmentTree();
|
||||
if (!_.isEmpty(result.data)) {
|
||||
treeData.value = result.data;
|
||||
setExpanded();
|
||||
}
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryDepartmentTree();
|
||||
});
|
||||
// 设置默认展开的节点
|
||||
const expandedKeys = ref([]);
|
||||
function setExpanded() {
|
||||
expandedKeys.value = [treeData.value[0].departmentId];
|
||||
}
|
||||
|
||||
// 选择的部门列表数据
|
||||
const selectedList = ref([]);
|
||||
|
||||
// 选择的部门列表Ids
|
||||
const selectedIds = computed(() => {
|
||||
return selectedList.value.map((item) => item.dataId);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.departmentList,
|
||||
(newVal) => {
|
||||
selectedList.value = newVal;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 检查是否已选
|
||||
function checkExists(dataId) {
|
||||
return selectedIds.value.includes(dataId);
|
||||
}
|
||||
|
||||
// 点击左边添加
|
||||
function onSelectAdd(name, departmentId) {
|
||||
if (checkExists(departmentId)) {
|
||||
return;
|
||||
}
|
||||
selectedList.value.push({
|
||||
dataName: name,
|
||||
dataId: departmentId,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value,
|
||||
});
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
// 点击右边移除
|
||||
function onRemove(index) {
|
||||
selectedList.value.splice(index, 1);
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
function onChangeEmit() {
|
||||
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryDepartmentTree();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-tree-list-holder-inner) {
|
||||
display: block !important;
|
||||
.ant-tree-treenode {
|
||||
:deep(.ant-tree-list-holder-inner) {
|
||||
display: block !important;
|
||||
.ant-tree-treenode {
|
||||
align-items: center;
|
||||
padding-bottom: 0;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.ant-tree-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ant-tree-switcher-icon {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.ant-tree-node-content-wrapper {
|
||||
display: block;
|
||||
flex: 1;
|
||||
&:hover {
|
||||
cursor: auto;
|
||||
}
|
||||
.ant-tree-title {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
.sider-fl,
|
||||
.sider-fr {
|
||||
flex: 1;
|
||||
height: 500px;
|
||||
border: 1px solid #d9d9d9;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background-color: #ededed;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
height: 50px;
|
||||
background-color: #a1a1a1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.sider-fr {
|
||||
margin-left: 15px;
|
||||
.list-item {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 0;
|
||||
padding: 0 14px 0 0;
|
||||
height: 32px;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.ant-tree-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ant-tree-switcher-icon {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.ant-tree-node-content-wrapper {
|
||||
display: block;
|
||||
flex: 1;
|
||||
&:hover {
|
||||
&.active {
|
||||
.check-icon-style {
|
||||
cursor: auto;
|
||||
}
|
||||
.ant-tree-title {
|
||||
display: block;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
.sider-fl,
|
||||
.sider-fr {
|
||||
flex: 1;
|
||||
height: 500px;
|
||||
border: 1px solid #d9d9d9;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
.list-item-title {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background-color: #ededed;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
height: 50px;
|
||||
background-color: #a1a1a1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.sider-fr {
|
||||
margin-left: 15px;
|
||||
.list-item {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px 0 0;
|
||||
height: 32px;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
&.active {
|
||||
.check-icon-style {
|
||||
cursor: auto;
|
||||
color: @primary-color;
|
||||
color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
.list-item-title {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.check-icon-style {
|
||||
color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -41,212 +41,212 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted, watch, computed, nextTick } from 'vue';
|
||||
import lodash from 'lodash';
|
||||
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
|
||||
import { departmentApi } from '/@/api/system/department/department-api';
|
||||
import { employeeApi } from '/@/api/system/employee/employee-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM } from '/@/constants/business/oa/notice-const';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import { employeeApi } from '/@/api/system/employee-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const props = defineProps({
|
||||
// 已选择的员工数据列表
|
||||
employeeList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['onChange']);
|
||||
|
||||
const treeData = ref([]);
|
||||
|
||||
// 查询部门树形
|
||||
async function queryDepartmentTree() {
|
||||
try {
|
||||
const departmentResult = await departmentApi.queryDepartmentTree();
|
||||
const employeeResult = await employeeApi.queryAll();
|
||||
const departmentTree = departmentResult.data;
|
||||
buildDepartmentEmployeeTree(departmentTree, employeeResult.data);
|
||||
|
||||
if (!lodash.isEmpty(departmentTree)) {
|
||||
treeData.value = departmentTree;
|
||||
console.log(treeData.value);
|
||||
nextTick(() => {
|
||||
setExpanded();
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
}
|
||||
}
|
||||
|
||||
// 递归构建部门员工树
|
||||
function buildDepartmentEmployeeTree(departmentTree, employeeList) {
|
||||
for (const department of departmentTree) {
|
||||
if (department.dataType && department.dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
department.id = department.departmentId;
|
||||
department.key = 'department_' + department.departmentId;
|
||||
department.dataType = NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value;
|
||||
let employeeChildren = employeeList
|
||||
.filter((e) => e.departmentId === department.departmentId)
|
||||
.map((e) =>
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
id: e.employeeId,
|
||||
key: 'employee_' + e.employeeId,
|
||||
name: e.actualName,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
|
||||
}
|
||||
)
|
||||
);
|
||||
if (!department.children) {
|
||||
department.children = [];
|
||||
}
|
||||
department.children.push(...employeeChildren);
|
||||
buildDepartmentEmployeeTree(department.children, employeeList);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认展开的节点
|
||||
const expandedKeys = ref([]);
|
||||
function setExpanded() {
|
||||
expandedKeys.value = [treeData.value[0].key];
|
||||
}
|
||||
|
||||
// 选择的员工列表数据
|
||||
const selectedList = ref([]);
|
||||
|
||||
// 选择的员工列表Ids
|
||||
const selectedIds = computed(() => {
|
||||
return selectedList.value.map((item) => item.dataId);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.employeeList,
|
||||
(newVal) => {
|
||||
selectedList.value = newVal;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 检查是否已选
|
||||
function checkExists(id) {
|
||||
return selectedIds.value.includes(id);
|
||||
}
|
||||
|
||||
// 点击左边添加
|
||||
function onSelectAdd(name, id, dataType) {
|
||||
if (checkExists(id)) {
|
||||
return;
|
||||
}
|
||||
selectedList.value.push({
|
||||
dataName: name,
|
||||
dataId: id,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
|
||||
const props = defineProps({
|
||||
// 已选择的员工数据列表
|
||||
employeeList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
// 点击右边移除
|
||||
function onRemove(index) {
|
||||
selectedList.value.splice(index, 1);
|
||||
onChangeEmit();
|
||||
}
|
||||
const emits = defineEmits(['onChange']);
|
||||
|
||||
function onChangeEmit() {
|
||||
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
|
||||
}
|
||||
const treeData = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
queryDepartmentTree();
|
||||
});
|
||||
// 查询部门树形
|
||||
async function queryDepartmentTree() {
|
||||
try {
|
||||
const departmentResult = await departmentApi.queryDepartmentTree();
|
||||
const employeeResult = await employeeApi.queryAll();
|
||||
const departmentTree = departmentResult.data;
|
||||
buildDepartmentEmployeeTree(departmentTree, employeeResult.data);
|
||||
|
||||
if (!_.isEmpty(departmentTree)) {
|
||||
treeData.value = departmentTree;
|
||||
console.log(treeData.value);
|
||||
nextTick(() => {
|
||||
setExpanded();
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
smartSentry.captureError(err);
|
||||
}
|
||||
}
|
||||
|
||||
// 递归构建部门员工树
|
||||
function buildDepartmentEmployeeTree(departmentTree, employeeList) {
|
||||
for (const department of departmentTree) {
|
||||
if (department.dataType && department.dataType === NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
department.id = department.departmentId;
|
||||
department.key = 'department_' + department.departmentId;
|
||||
department.dataType = NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.DEPARTMENT.value;
|
||||
let employeeChildren = employeeList
|
||||
.filter((e) => e.departmentId === department.departmentId)
|
||||
.map((e) =>
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
id: e.employeeId,
|
||||
key: 'employee_' + e.employeeId,
|
||||
name: e.actualName,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
|
||||
}
|
||||
)
|
||||
);
|
||||
if (!department.children) {
|
||||
department.children = [];
|
||||
}
|
||||
department.children.push(...employeeChildren);
|
||||
buildDepartmentEmployeeTree(department.children, employeeList);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置默认展开的节点
|
||||
const expandedKeys = ref([]);
|
||||
function setExpanded() {
|
||||
expandedKeys.value = [treeData.value[0].key];
|
||||
}
|
||||
|
||||
// 选择的员工列表数据
|
||||
const selectedList = ref([]);
|
||||
|
||||
// 选择的员工列表Ids
|
||||
const selectedIds = computed(() => {
|
||||
return selectedList.value.map((item) => item.dataId);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.employeeList,
|
||||
(newVal) => {
|
||||
selectedList.value = newVal;
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 检查是否已选
|
||||
function checkExists(id) {
|
||||
return selectedIds.value.includes(id);
|
||||
}
|
||||
|
||||
// 点击左边添加
|
||||
function onSelectAdd(name, id, dataType) {
|
||||
if (checkExists(id)) {
|
||||
return;
|
||||
}
|
||||
selectedList.value.push({
|
||||
dataName: name,
|
||||
dataId: id,
|
||||
dataType: NOTICE_VISIBLE_RANGE_DATA_TYPE_ENUM.EMPLOYEE.value,
|
||||
});
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
// 点击右边移除
|
||||
function onRemove(index) {
|
||||
selectedList.value.splice(index, 1);
|
||||
onChangeEmit();
|
||||
}
|
||||
|
||||
function onChangeEmit() {
|
||||
emits('onChange', { selectedList: selectedList.value, selectedIds: selectedIds.value });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryDepartmentTree();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-tree-list-holder-inner) {
|
||||
display: block !important;
|
||||
.ant-tree-treenode {
|
||||
:deep(.ant-tree-list-holder-inner) {
|
||||
display: block !important;
|
||||
.ant-tree-treenode {
|
||||
align-items: center;
|
||||
padding-bottom: 0;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.ant-tree-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ant-tree-switcher-icon {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.ant-tree-node-content-wrapper {
|
||||
display: block;
|
||||
flex: 1;
|
||||
&:hover {
|
||||
cursor: auto;
|
||||
}
|
||||
.ant-tree-title {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
.sider-left,
|
||||
.sider-right {
|
||||
flex: 1;
|
||||
height: 500px;
|
||||
border: 1px solid #d9d9d9;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background-color: #ededed;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
height: 50px;
|
||||
background-color: #a1a1a1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.sider-right {
|
||||
margin-left: 15px;
|
||||
.list-item {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 0;
|
||||
padding: 0 14px 0 0;
|
||||
height: 32px;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.ant-tree-switcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.ant-tree-switcher-icon {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.ant-tree-node-content-wrapper {
|
||||
display: block;
|
||||
flex: 1;
|
||||
&:hover {
|
||||
&.active {
|
||||
.check-icon-style {
|
||||
cursor: auto;
|
||||
}
|
||||
.ant-tree-title {
|
||||
display: block;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
.sider-left,
|
||||
.sider-right {
|
||||
flex: 1;
|
||||
height: 500px;
|
||||
border: 1px solid #d9d9d9;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
.list-item-title {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&::-webkit-scrollbar-track-piece {
|
||||
background-color: #ededed;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
height: 50px;
|
||||
background-color: #a1a1a1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.sider-right {
|
||||
margin-left: 15px;
|
||||
.list-item {
|
||||
padding-left: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 14px 0 0;
|
||||
height: 32px;
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
&.active {
|
||||
.check-icon-style {
|
||||
cursor: auto;
|
||||
color: @primary-color;
|
||||
color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
.list-item-title {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.check-icon-style {
|
||||
color: #d9d9d9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
<a-descriptions-item label="发布时间">{{ noticeDetail.publishTime }}</a-descriptions-item>
|
||||
<a-descriptions-item label="定时发布">{{ noticeDetail.publishFlag ? '已发布' : '待发布' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="删除状态">{{ noticeDetail.deletedFlag ? '已删除' : '未删除' }}</a-descriptions-item>
|
||||
<a-descriptions-item v-if="!$lodash.isEmpty(noticeDetail.attachmentFile)" label="附件">
|
||||
<a-descriptions-item v-if="!$lodash.isEmpty(noticeDetail.attachment)" label="附件">
|
||||
<div class="file-list">
|
||||
<a class="file-item" v-for="item in noticeDetail.attachmentFile" :key="item.fileId" @click="onPrevFile(item)">{{ item.fileName }}</a>
|
||||
<a class="file-item" v-for="item in noticeDetail.attachment" :key="item.fileId" @click="onPrevFile(item)">{{ item.fileName }}</a>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="可见范围" :span="2">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<a-form class="smart-query-form" v-privilege="'notice:query'">
|
||||
<a-form class="smart-query-form" v-privilege="'oa:notice:query'">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="分类" class="smart-query-form-item">
|
||||
<a-select v-model:value="queryForm.noticeTypeId" style="width: 100px" :showSearch="true" :allowClear="true" placeholder="分类">
|
||||
@@ -36,16 +36,16 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="发布时间" class="smart-query-form-item">
|
||||
<a-range-picker v-model:value="publishDate" :ranges="defaultTimeRanges" @change="publishDateChange" style="width: 220px" />
|
||||
<a-range-picker v-model:value="publishDate" :presets="defaultTimeRanges" @change="publishDateChange" style="width: 220px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="创建时间" class="smart-query-form-item">
|
||||
<a-range-picker v-model:value="createDate" :ranges="defaultTimeRanges" @change="createDateChange" style="width: 220px" />
|
||||
<a-range-picker v-model:value="createDate" :presets="defaultTimeRanges" @change="createDateChange" style="width: 220px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button-group>
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<a-button type="primary" @click="onSearch" class="smart-margin-right10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -65,7 +65,7 @@
|
||||
<a-card size="small" :bordered="false">
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button type="primary" size="small" @click="addOrUpdate()" v-privilege="'notice:add'">
|
||||
<a-button type="primary" size="small" @click="addOrUpdate()" v-privilege="'oa:notice:add'">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
@@ -101,8 +101,8 @@
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button type="link" @click="addOrUpdate(record.noticeId)" v-privilege="'notice:edit'">编辑</a-button>
|
||||
<a-button type="link" @click="onDelete(record.noticeId)" v-privilege="'notice:delete'" danger>删除</a-button>
|
||||
<a-button type="link" @click="addOrUpdate(record.noticeId)" v-privilege="'oa:notice:update'">编辑</a-button>
|
||||
<a-button type="link" @click="onDelete(record.noticeId)" v-privilege="'oa:notice:delete'" danger>删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
<!--
|
||||
* 接口加密、解密
|
||||
*
|
||||
* @Author: 1024创新实验室-主任-卓大
|
||||
* @Date: 2023-10-17 22:02:37
|
||||
* @Copyright 1024创新实验室
|
||||
-->
|
||||
<template>
|
||||
<a-alert closable>
|
||||
<template v-slot:message>
|
||||
<h4>接口加解密:</h4>
|
||||
</template>
|
||||
<template v-slot:description>
|
||||
<pre>
|
||||
简介:接口加解密分为: 前端请求参数加解密 和 后端返回结果加解密。
|
||||
|
||||
- 支持国密SM、AES加密算法。前端修改:/lib/encrypt.js文件,后端:启动 ApiEncryptServiceAesImpl 或者 ApiEncryptServiceSmImpl
|
||||
- 前端请看:/lib/encrypt.js、/lib/axios.js /api/support/api-encrypt/api-encrypt-api.js 等文件
|
||||
- 后端请看:@ApiEncrypt 和 @ApiDecrypt 注解,具体请看 sa-common项目中的 net.lab1024.sa.common.module.support.apiencrypt 包
|
||||
- demo请看:前端:/views/support/api-encrypt 目录,后端 请看:sa-admin项目的:net.lab1024.sa.admin.module.system.support.AdminApiEncryptController
|
||||
</pre
|
||||
>
|
||||
</template>
|
||||
</a-alert>
|
||||
<br />
|
||||
<a-alert
|
||||
message="当前加密算法为:SM2,若想改为 AES,前端请修改 'lib/encrypt.js'文件中的EncryptObject,后端请修改 ApiEncryptService 的实现类"
|
||||
type="error"
|
||||
/>
|
||||
<br />
|
||||
<!---------- 请求参数加密 begin ----------->
|
||||
<a-card title="一、请求加密 Demo">
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="姓名" class="smart-query-form-item">
|
||||
<a-input v-model:value="requestEncryptForm.name" placeholder="姓名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="年龄" class="smart-query-form-item">
|
||||
<a-input-number v-model:value="requestEncryptForm.age" placeholder="年龄" />
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="testRequestEncrypt"> 测试:请求加密</a-button>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="requestEncryptFormStr">请求参数:{{ requestEncryptFormStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="requestEncryptFormEncryptStr">请求参数加密:{{ requestEncryptFormEncryptStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="requestEncryptResponse">返回结果(不加密):{{ requestEncryptResponse }}</div>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<!---------- 请求参数加密 end ----------->
|
||||
<br />
|
||||
<!---------- 返回结果解密 begin ----------->
|
||||
<a-card title="二、返回加密 Demo">
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="姓名" class="smart-query-form-item">
|
||||
<a-input v-model:value="responseEncryptForm.name" placeholder="姓名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="年龄" class="smart-query-form-item">
|
||||
<a-input-number v-model:value="responseEncryptForm.age" placeholder="年龄" />
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="testResponseEncrypt"> 测试:返回加密 </a-button>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="responseEncryptFormStr">请求参数: {{ responseEncryptFormStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="responseEncryptStr">返回结果:{{ responseEncryptStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="responseStr">返回结果 解密:{{ responseStr }}</div>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<!---------- 返回结果解密 end ----------->
|
||||
|
||||
<br />
|
||||
<!---------- 请求和返回都加密 begin ----------->
|
||||
<a-card title="三、请求和返回都加密 Demo">
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="姓名" class="smart-query-form-item">
|
||||
<a-input v-model:value="form.name" placeholder="姓名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="年龄" class="smart-query-form-item">
|
||||
<a-input-number v-model:value="form.age" placeholder="年龄" />
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="testBoth"> 测试:请求和返回都加密 </a-button>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="formStr">请求参数: {{ formStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="formEncryptStr">请求参数加密: {{ formEncryptStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="responseEncrypt">返回结果:{{ responseEncrypt }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="responseDecryptStr">返回结果 解密:{{ responseDecryptStr }}</div>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<!---------- 返回结果解密 end ----------->
|
||||
|
||||
<br />
|
||||
<!---------- 测试数组 begin ----------->
|
||||
<a-card title="四、测试数组 Demo">
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="testArray"> 测试:数组加解密 </a-button>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="arrayFormStr">请求参数: {{ arrayFormStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="arrayFormEncryptStr">请求参数加密: {{ arrayFormEncryptStr }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="arrayFormResponseEncrypt">返回结果:{{ arrayFormResponseEncrypt }}</div>
|
||||
</a-row>
|
||||
<a-row class="smart-query-form-row">
|
||||
<div v-if="arrayFormResponseDecryptStr">返回结果 解密:{{ arrayFormResponseDecryptStr }}</div>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-card>
|
||||
<!---------- 返回结果解密 end ----------->
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { encryptApi } from '/@/api/support/api-encrypt-api';
|
||||
import { encryptData } from '/@/lib/encrypt';
|
||||
|
||||
// ---------------------------- 第一种:请求参数加密 ----------------------------
|
||||
|
||||
//请求参数加密
|
||||
const requestEncryptForm = reactive({
|
||||
age: 100, // 年龄
|
||||
name: '卓大', //姓名
|
||||
});
|
||||
|
||||
// 参数字符串
|
||||
const requestEncryptFormStr = ref('');
|
||||
// 参数字符串 加密
|
||||
const requestEncryptFormEncryptStr = ref('');
|
||||
// 返回结果
|
||||
const requestEncryptResponse = ref('');
|
||||
|
||||
async function testRequestEncrypt() {
|
||||
// 参数加密
|
||||
requestEncryptFormStr.value = JSON.stringify(requestEncryptForm);
|
||||
requestEncryptFormEncryptStr.value = encryptData(requestEncryptForm);
|
||||
|
||||
// 发送请求
|
||||
const result = await encryptApi.testRequestEncrypt(requestEncryptForm);
|
||||
requestEncryptResponse.value = JSON.stringify(result.data);
|
||||
}
|
||||
|
||||
// ---------------------------- 第二种:返回结果解密 ----------------------------
|
||||
|
||||
const responseEncryptForm = reactive({
|
||||
age: 100, // 年龄
|
||||
name: '卓大', //姓名
|
||||
});
|
||||
|
||||
const responseEncryptFormStr = ref('');
|
||||
const responseEncryptStr = ref('');
|
||||
const responseStr = ref('');
|
||||
|
||||
async function testResponseEncrypt() {
|
||||
responseEncryptFormStr.value = JSON.stringify(responseEncryptForm);
|
||||
const result = await encryptApi.testResponseEncrypt(responseEncryptForm);
|
||||
responseEncryptStr.value = result.encryptData;
|
||||
responseStr.value = JSON.stringify(result.data);
|
||||
}
|
||||
|
||||
// ---------------------------- 第三种:请求加密、返回解密 ----------------------------
|
||||
|
||||
const form = reactive({
|
||||
age: 100, // 年龄
|
||||
name: '卓大', //姓名
|
||||
});
|
||||
|
||||
const formStr = ref('');
|
||||
const formEncryptStr = ref('');
|
||||
const responseEncrypt = ref('');
|
||||
const responseDecryptStr = ref('');
|
||||
|
||||
async function testBoth() {
|
||||
formStr.value = JSON.stringify(form);
|
||||
formEncryptStr.value = encryptData(form);
|
||||
const result = await encryptApi.testDecryptAndEncrypt(form);
|
||||
responseEncrypt.value = result.encryptData;
|
||||
responseDecryptStr.value = JSON.stringify(result.data);
|
||||
}
|
||||
|
||||
// ---------------------------- 第四种:测试数组 ----------------------------
|
||||
|
||||
const arrayForm = reactive([
|
||||
{
|
||||
age: 1, // 年龄
|
||||
name: '卓1', //姓名
|
||||
},
|
||||
{
|
||||
age: 2, // 年龄
|
||||
name: '卓2', //姓名
|
||||
},
|
||||
{
|
||||
age: 3, // 年龄
|
||||
name: '卓3', //姓名
|
||||
},
|
||||
]);
|
||||
|
||||
const arrayFormStr = ref('');
|
||||
const arrayFormEncryptStr = ref('');
|
||||
const arrayFormResponseEncrypt = ref('');
|
||||
const arrayFormResponseDecryptStr = ref('');
|
||||
|
||||
async function testArray() {
|
||||
arrayFormStr.value = JSON.stringify(arrayForm);
|
||||
arrayFormEncryptStr.value = encryptData(arrayForm);
|
||||
const result = await encryptApi.testArray(arrayForm);
|
||||
arrayFormResponseEncrypt.value = result.encryptData;
|
||||
arrayFormResponseDecryptStr.value = JSON.stringify(result.data);
|
||||
}
|
||||
</script>
|
||||
@@ -40,7 +40,7 @@ Caffeine :
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { onMounted, reactive, ref, h } from 'vue';
|
||||
import { cacheApi } from '/@/api/support/cache/cache-api';
|
||||
import { cacheApi } from '/@/api/support/cache-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:title="form.changeLogId ? '编辑' : '添加'"
|
||||
width="600px"
|
||||
:closable="true"
|
||||
:visible="visibleFlag"
|
||||
:open="visibleFlag"
|
||||
@close="onClose"
|
||||
:onCancel="onClose"
|
||||
:maskClosable="false"
|
||||
@@ -50,7 +50,7 @@
|
||||
import _ from 'lodash';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { changeLogApi } from '/@/api/support/change-log/change-log-api';
|
||||
import { changeLogApi } from '/@/api/support/change-log-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-->
|
||||
<template>
|
||||
<!---------- 查询表单form begin ----------->
|
||||
<a-form class="smart-query-form" v-privilege="'changeLog:query'">
|
||||
<a-form class="smart-query-form" v-privilege="'support:changeLog:query'">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="更新类型" class="smart-query-form-item">
|
||||
<SmartEnumSelect width="200px" v-model:value="queryForm.type" enumName="CHANGE_LOG_TYPE_ENUM" placeholder="更新类型" />
|
||||
@@ -16,13 +16,13 @@
|
||||
<a-input style="width: 200px" v-model:value="queryForm.keyword" placeholder="关键字" />
|
||||
</a-form-item>
|
||||
<a-form-item label="发布日期" class="smart-query-form-item">
|
||||
<a-range-picker v-model:value="queryForm.publicDate" :ranges="defaultTimeRanges" style="width: 240px" @change="onChangePublicDate" />
|
||||
<a-range-picker v-model:value="queryForm.publicDate" :presets="defaultTimeRanges" style="width: 240px" @change="onChangePublicDate" />
|
||||
</a-form-item>
|
||||
<a-form-item label="创建时间" class="smart-query-form-item">
|
||||
<a-date-picker valueFormat="YYYY-MM-DD" v-model:value="queryForm.createTime" style="width: 150px" />
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="queryData">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -43,13 +43,19 @@
|
||||
<!---------- 表格操作行 begin ----------->
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button @click="showForm" type="primary" size="small" v-privilege="'changeLog:add'">
|
||||
<a-button @click="showForm" type="primary" size="small" v-privilege="'support:changeLog:add'">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
新建
|
||||
</a-button>
|
||||
<a-button @click="confirmBatchDelete" type="danger" size="small" :disabled="selectedRowKeyList.length == 0" v-privilege="'changeLog:batchDelete'">
|
||||
<a-button
|
||||
@click="confirmBatchDelete"
|
||||
danger
|
||||
size="small"
|
||||
:disabled="selectedRowKeyList.length === 0"
|
||||
v-privilege="'support:changeLog:batchDelete'"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
@@ -74,7 +80,7 @@
|
||||
>
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'version'">
|
||||
<a-button @click="showModal(record)" type="link">{{text}}</a-button>
|
||||
<a-button @click="showModal(record)" type="link">{{ text }}</a-button>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'type'">
|
||||
<a-tag color="success">
|
||||
@@ -86,8 +92,8 @@
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="showForm(record)" type="link" v-privilege="'changeLog:update'">编辑</a-button>
|
||||
<a-button @click="onDelete(record)" danger type="link" v-privilege="'changeLog:delete'">删除</a-button>
|
||||
<a-button @click="showForm(record)" type="link" v-privilege="'support:changeLog:update'">编辑</a-button>
|
||||
<a-button @click="onDelete(record)" danger type="link" v-privilege="'support:changeLog:delete'">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -119,7 +125,7 @@
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { changeLogApi } from '/@/api/support/change-log/change-log-api';
|
||||
import { changeLogApi } from '/@/api/support/change-log-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
@@ -209,6 +215,12 @@
|
||||
queryData();
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryData();
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
async function queryData() {
|
||||
tableLoading.value = true;
|
||||
@@ -264,9 +276,6 @@
|
||||
async function requestDelete(data) {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
let deleteForm = {
|
||||
goodsIdList: selectedRowKeyList.value,
|
||||
};
|
||||
await changeLogApi.delete(data.changeLogId);
|
||||
message.success('删除成功');
|
||||
queryData();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @Copyright 1024创新实验室
|
||||
-->
|
||||
<template>
|
||||
<a-modal title="更新日志" width="700px" :visible="visibleFlag" @close="onClose" >
|
||||
<a-modal title="更新日志" width="700px" :open="visibleFlag" @close="onClose" >
|
||||
|
||||
<div>
|
||||
<pre>{{ content }}</pre>
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery">
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -69,13 +69,13 @@
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<CodeGeneratorTableConfigForm ref="codeGeneratorTableConfigFormRef" @reloadList="ajaxQuery"/>
|
||||
<CodeGeneratorTableConfigForm ref="codeGeneratorTableConfigFormRef" @reloadList="ajaxQuery" />
|
||||
<CodeGeneratorPreviewModal ref="codeGeneratorPreviewModalRef" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, nextTick } from 'vue';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator/code-generator-api';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import CodeGeneratorTableConfigForm from './components/form/code-generator-table-config-form.vue';
|
||||
@@ -140,6 +140,12 @@
|
||||
Object.assign(queryForm, queryFormState);
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
@@ -169,7 +175,7 @@
|
||||
}
|
||||
|
||||
// ------------------------- 下载 ------------------------------
|
||||
|
||||
|
||||
function download(rowData) {
|
||||
codeGeneratorApi.downloadCode(rowData.tableName);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-alert :closable="true" message="默认数据库表名前缀为:t_, 如果想修改默认前缀,请修改前端 code-generator-table-config-form-basic.vue 文件的 tablePrefix 变量" type="success" show-icon>
|
||||
<a-alert
|
||||
:closable="true"
|
||||
message="默认数据库表名前缀为:t_, 如果想修改默认前缀,请修改前端 code-generator-table-config-form-basic.vue 文件的 tablePrefix 变量"
|
||||
type="success"
|
||||
show-icon
|
||||
>
|
||||
<template #icon><smile-outlined /></template>
|
||||
</a-alert>
|
||||
<a-row type="flex" class="smart-margin-top10">
|
||||
@@ -133,7 +138,7 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import dayjs from 'dayjs';
|
||||
import lodash from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import { computed, inject, reactive, ref } from 'vue';
|
||||
import { convertLowerHyphen, convertUpperCamel } from '/@/utils/str-util';
|
||||
|
||||
@@ -176,8 +181,8 @@
|
||||
|
||||
//命名
|
||||
let removePrefixTableName = tableInfo.tableName;
|
||||
if (lodash.startsWith(tableInfo.tableName, tablePrefix.value)) {
|
||||
removePrefixTableName = lodash.trim(removePrefixTableName, tablePrefix.value);
|
||||
if (_.startsWith(tableInfo.tableName, tablePrefix.value)) {
|
||||
removePrefixTableName = _.trim(removePrefixTableName, tablePrefix.value);
|
||||
}
|
||||
formData.moduleName = basic && basic.moduleName ? basic.moduleName : removePrefixTableName;
|
||||
formData.moduleName = convertUpperCamel(formData.moduleName);
|
||||
@@ -197,10 +202,10 @@
|
||||
formData.copyright = basic && basic.copyright ? basic.copyright : null;
|
||||
}
|
||||
|
||||
function onChangeTablePrefix(e){
|
||||
function onChangeTablePrefix(e) {
|
||||
let removePrefixTableName = tableInfo.tableName;
|
||||
if (lodash.startsWith(tableInfo.tableName, tablePrefix.value)) {
|
||||
removePrefixTableName = lodash.trim(removePrefixTableName, tablePrefix.value);
|
||||
if (_.startsWith(tableInfo.tableName, tablePrefix.value)) {
|
||||
removePrefixTableName = _.trim(removePrefixTableName, tablePrefix.value);
|
||||
}
|
||||
formData.moduleName = convertUpperCamel(removePrefixTableName);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import lodash from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import { inject, reactive, ref } from 'vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { CODE_DELETE_ENUM } from '/@/constants/support/code-generator-const';
|
||||
@@ -73,7 +73,7 @@
|
||||
let deleteInfo = config.delete;
|
||||
|
||||
formData.isSupportDelete = deleteInfo && deleteInfo.isSupportDelete ? deleteInfo.isSupportDelete : true;
|
||||
formData.isPhysicallyDeleted = deleteInfo && deleteInfo.isPhysicallyDeleted ? deleteInfo.isPhysicallyDeleted : deletedFlagColumn ? false : true;
|
||||
formData.isPhysicallyDeleted = deleteInfo && deleteInfo.isPhysicallyDeleted ? deleteInfo.isPhysicallyDeleted : !deletedFlagColumn;
|
||||
formData.deleteEnum = deleteInfo && deleteInfo.deleteEnum ? deleteInfo.deleteEnum : CODE_DELETE_ENUM.SINGLE_AND_BATCH.value;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
let result = configFields.filter((e) => lodash.startsWith(e.columnName, 'deleted_flag' || lodash.startsWith(e.columnName, 'delete_flag')));
|
||||
let result = configFields.filter((e) => _.startsWith(e.columnName, 'deleted_flag' || _.startsWith(e.columnName, 'delete_flag')));
|
||||
return result && result.length > 0 ? result[0] : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
import { checkExistEnum, convertJavaEnumName, getJavaType, getJsType, JavaTypeList, JsTypeList } from '../../code-generator-util';
|
||||
import DictKeySelect from '/@/components/support/dict-key-select/index.vue';
|
||||
import { convertUpperCamel, convertLowerCamel } from '/@/utils/str-util';
|
||||
import lodash from 'lodash';
|
||||
import _ from 'lodash';
|
||||
|
||||
//------------------------ 全局数据 ---------------------
|
||||
const tableInfo = inject('tableInfo');
|
||||
@@ -154,8 +154,8 @@
|
||||
|
||||
//命名
|
||||
let removePrefixTableName = tableInfo.tableName;
|
||||
if (lodash.startsWith(tableInfo.tableName, 't_')) {
|
||||
removePrefixTableName = lodash.trim(removePrefixTableName, '_t');
|
||||
if (_.startsWith(tableInfo.tableName, 't_')) {
|
||||
removePrefixTableName = _.trim(removePrefixTableName, '_t');
|
||||
}
|
||||
let moduleName = basic && basic.moduleName ? basic.moduleName : removePrefixTableName;
|
||||
moduleName = convertUpperCamel(moduleName);
|
||||
@@ -167,9 +167,9 @@
|
||||
columnName: column.columnName,
|
||||
columnComment: column.columnComment,
|
||||
dataType: column.dataType,
|
||||
nullableFlag: column.isNullable === 'NO' ? true : false,
|
||||
primaryKeyFlag: column.columnKey === 'PRI' ? true : false,
|
||||
autoIncreaseFlag: column.extra === 'auto_increment' ? true : false,
|
||||
nullableFlag: column.isNullable === 'NO',
|
||||
primaryKeyFlag: column.columnKey === 'PRI',
|
||||
autoIncreaseFlag: column.extra === 'auto_increment',
|
||||
//表单
|
||||
fieldName: configField ? configField.fieldName : convertLowerCamel(column.columnName),
|
||||
label: configField ? configField.label : column.columnComment,
|
||||
@@ -203,7 +203,7 @@
|
||||
return tableData.value.map((e) => {
|
||||
return {
|
||||
columnName: e.columnName,
|
||||
columnComment:e.columnComment,
|
||||
columnComment: e.columnComment,
|
||||
label: e.label,
|
||||
fieldName: e.fieldName,
|
||||
javaType: e.javaType,
|
||||
|
||||
@@ -19,11 +19,16 @@
|
||||
</a-form-item>
|
||||
<a-form-item label="页面方式" name="pageType" v-if="formData.isSupportInsertAndUpdate">
|
||||
<a-radio-group v-model:value="formData.pageType" button-style="solid">
|
||||
<a-radio-button :value="CODE_INSERT_AND_UPDATE_PAGE_ENUM.MODAL.value">{{CODE_INSERT_AND_UPDATE_PAGE_ENUM.MODAL.desc}}</a-radio-button>
|
||||
<a-radio-button :value="CODE_INSERT_AND_UPDATE_PAGE_ENUM.DRAWER.value">{{CODE_INSERT_AND_UPDATE_PAGE_ENUM.DRAWER.desc}}</a-radio-button>
|
||||
<a-radio-button :value="CODE_INSERT_AND_UPDATE_PAGE_ENUM.MODAL.value">{{ CODE_INSERT_AND_UPDATE_PAGE_ENUM.MODAL.desc }}</a-radio-button>
|
||||
<a-radio-button :value="CODE_INSERT_AND_UPDATE_PAGE_ENUM.DRAWER.value">{{ CODE_INSERT_AND_UPDATE_PAGE_ENUM.DRAWER.desc }}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="页面宽度" v-show="formData.pageType !== CODE_INSERT_AND_UPDATE_PAGE_ENUM.PAGE.value" name="width" v-if="formData.isSupportInsertAndUpdate">
|
||||
<a-form-item
|
||||
label="页面宽度"
|
||||
v-show="formData.pageType !== CODE_INSERT_AND_UPDATE_PAGE_ENUM.PAGE.value"
|
||||
name="width"
|
||||
v-if="formData.isSupportInsertAndUpdate"
|
||||
>
|
||||
<a-input v-model:value="formData.width" placeholder="Modal或者Drawer的width属性 " />
|
||||
</a-form-item>
|
||||
<a-form-item label="每行数量" name="countPerLine" v-if="formData.isSupportInsertAndUpdate">
|
||||
@@ -52,7 +57,16 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-table size="small" bordered class="smart-margin-top10" :dataSource="tableData" :columns="columns" rowKey="columnName" :pagination="false" v-if="formData.isSupportInsertAndUpdate">
|
||||
<a-table
|
||||
size="small"
|
||||
bordered
|
||||
class="smart-margin-top10"
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="columnName"
|
||||
:pagination="false"
|
||||
v-if="formData.isSupportInsertAndUpdate"
|
||||
>
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<template v-if="column.dataIndex === 'no'">
|
||||
{{ index + 1 }}
|
||||
@@ -95,13 +109,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, ref, reactive, computed } from 'vue';
|
||||
import { computed, inject, reactive, ref } from 'vue';
|
||||
import { checkExistEnum, getFrontComponent } from '../../code-generator-util';
|
||||
import SmartEnumRadio from '/@/components/framework/smart-enum-radio/index.vue';
|
||||
import { CODE_INSERT_AND_UPDATE_PAGE_ENUM } from '/@/constants/support/code-generator-const';
|
||||
import { CODE_FRONT_COMPONENT_ENUM, CODE_INSERT_AND_UPDATE_PAGE_ENUM } from '/@/constants/support/code-generator-const';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { CODE_FRONT_COMPONENT_ENUM } from '/@/constants/support/code-generator-const';
|
||||
|
||||
//------------------------ 全局数据 ---------------------
|
||||
const tableInfo = inject('tableInfo');
|
||||
@@ -203,9 +215,9 @@
|
||||
columnName: column.columnName,
|
||||
columnComment: column.columnComment,
|
||||
dataType: column.dataType,
|
||||
nullableFlag: column.isNullable === 'NO' ? true : false,
|
||||
primaryKeyFlag: column.columnKey === 'PRI' ? true : false,
|
||||
autoIncreaseFlag: column.extra === 'auto_increment' ? true : false,
|
||||
nullableFlag: column.isNullable === 'NO',
|
||||
primaryKeyFlag: column.columnKey === 'PRI',
|
||||
autoIncreaseFlag: column.extra === 'auto_increment',
|
||||
};
|
||||
|
||||
//表单
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
rowKey="rowKey"
|
||||
:pagination="false"
|
||||
>
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<template #bodyCell="{ record, index, column }">
|
||||
<template v-if="column.dataIndex === 'drag'">
|
||||
<a-button type="text" class="handle" size="small" style="width: 100%; text-align: left">
|
||||
<template #icon> <drag-outlined /> </template>
|
||||
@@ -75,7 +75,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import lodash from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import Sortable from 'sortablejs';
|
||||
import { inject, nextTick, ref } from 'vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
@@ -103,7 +103,7 @@
|
||||
title: '查询列',
|
||||
dataIndex: 'columnNameList',
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
title: '条件名称',
|
||||
dataIndex: 'label',
|
||||
@@ -161,7 +161,7 @@
|
||||
}
|
||||
|
||||
function onDelete(index) {
|
||||
lodash.pullAt(tableData.value, index);
|
||||
_.pullAt(tableData.value, index);
|
||||
}
|
||||
|
||||
//初始化拖拽
|
||||
|
||||
@@ -11,8 +11,17 @@
|
||||
<a-alert :closable="true" message="请务必将每一个字段的 “ 字段名词 ” 填写完整!!!" type="success" show-icon>
|
||||
<template #icon><smile-outlined /></template>
|
||||
</a-alert>
|
||||
<a-table size="small" bordered :scroll="{ x: 1000 }" class="smart-margin-top10" :dataSource="tableData" :columns="columns" rowKey="columnName" :pagination="false">
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<a-table
|
||||
size="small"
|
||||
bordered
|
||||
:scroll="{ x: 1000 }"
|
||||
class="smart-margin-top10"
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="columnName"
|
||||
:pagination="false"
|
||||
>
|
||||
<template #bodyCell="{ record, index, column }">
|
||||
<template v-if="column.dataIndex === 'no'">
|
||||
{{ index + 1 }}
|
||||
</template>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<a-drawer
|
||||
title="代码配置"
|
||||
style=""
|
||||
:visible="visibleFlag"
|
||||
:open="visibleFlag"
|
||||
:width="1000"
|
||||
:footerStyle="{ textAlign: 'right' }"
|
||||
@close="onClose"
|
||||
@@ -89,7 +89,7 @@
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import CodeGeneratorTableConfigFormBasic from './code-generator-table-config-form-basic.vue';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator/code-generator-api';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator-api';
|
||||
import CodeGeneratorTableConfigFormField from './code-generator-table-config-form-field.vue';
|
||||
import CodeGeneratorTableConfigFormInsertAndUpdate from './code-generator-table-config-form-insert-and-update.vue';
|
||||
import CodeGeneratorTableConfigFormDelete from './code-generator-table-config-form-delete.vue';
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
title="代码预览"
|
||||
:visible="visibleFlag"
|
||||
:open="visibleFlag"
|
||||
:width="1200"
|
||||
:footerStyle="{ textAlign: 'right' }"
|
||||
:bodyStyle="{ padding: '8px 24px' }"
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator/code-generator-api';
|
||||
import { codeGeneratorApi } from '/@/api/support/code-generator-api';
|
||||
import { JAVA_FILE_LIST, LANGUAGE_LIST, JS_FILE_LIST,TS_FILE_LIST, JAVA_DOMAIN_FILE_LIST } from '../../code-generator-util';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { lineNumbersBlock } from '/@/lib/highlight-line-number';
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.configId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.configId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
|
||||
<a-form-item label="参数Key" name="configKey">
|
||||
<a-input v-model:value="form.configKey" placeholder="请输入参数Key" />
|
||||
@@ -28,12 +28,12 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { configApi } from '/@/api/support/config/config-api';
|
||||
import { configApi } from '/@/api/support/config-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
// emit
|
||||
const emit = defineEmits('reloadList');
|
||||
const emit = defineEmits(['reloadList']);
|
||||
|
||||
// 组件
|
||||
const formRef = ref();
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery" v-privilege="'support:config:query'">
|
||||
<a-button type="primary" @click="onSearch" v-privilege="'support:config:query'">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery" v-privilege="'support:config:query'">
|
||||
<a-button @click="resetQuery" v-privilege="'support:config:query'" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -40,8 +40,8 @@
|
||||
</a-form>
|
||||
|
||||
<a-card size="small" :bordered="false" :hoverable="true">
|
||||
<a-row justify="end" >
|
||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.CONFIG" :refresh="ajaxQuery" />
|
||||
<a-row justify="end">
|
||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.CONFIG" :refresh="ajaxQuery" />
|
||||
</a-row>
|
||||
|
||||
<a-table size="small" :loading="tableLoading" bordered :dataSource="tableData" :columns="columns" rowKey="configId" :pagination="false">
|
||||
@@ -75,7 +75,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { configApi } from '/@/api/support/config/config-api';
|
||||
import { configApi } from '/@/api/support/config-api';
|
||||
import ConfigFormModal from './config-form-modal.vue';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
@@ -145,6 +145,12 @@
|
||||
Object.assign(queryForm, queryFormState);
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.dictKeyId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.dictKeyId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item label="编码" name="keyCode">
|
||||
<a-input v-model:value="form.keyCode" placeholder="请输入编码" />
|
||||
@@ -27,7 +27,7 @@
|
||||
import { ref, reactive } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { dictApi } from '/@/api/support/dict/dict-api';
|
||||
import { dictApi } from '/@/api/support/dict-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
// emit
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-drawer :width="800" :visible="visible" :body-style="{ paddingBottom: '80px' }" title="字典值" @close="onClose">
|
||||
<a-drawer :width="800" :open="visible" :body-style="{ paddingBottom: '80px' }" title="字典值" @close="onClose">
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="关键字" class="smart-query-form-item">
|
||||
@@ -42,7 +42,7 @@
|
||||
新建
|
||||
</a-button>
|
||||
|
||||
<a-button @click="confirmBatchDelete" type="danger" size="small" :disabled="selectedRowKeyList.length == 0">
|
||||
<a-button @click="confirmBatchDelete" type="text" danger size="small" :disabled="selectedRowKeyList.length == 0">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
@@ -91,7 +91,7 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import DictValueOperateModal from './dict-value-operate-modal.vue';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { dictApi } from '/@/api/support/dict/dict-api';
|
||||
import { dictApi } from '/@/api/support/dict-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" :title="form.dictValueId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" :title="form.dictValueId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<a-form-item label="编码" name="valueCode">
|
||||
<a-input v-model:value="form.valueCode" placeholder="请输入编码" />
|
||||
@@ -29,7 +29,7 @@
|
||||
import { ref, reactive } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { dictApi } from '/@/api/support/dict/dict-api';
|
||||
import { dictApi } from '/@/api/support/dict-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
// emit
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery">
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -41,7 +41,14 @@
|
||||
新建
|
||||
</a-button>
|
||||
|
||||
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:batch:delete'" type="danger" size="small" :disabled="selectedRowKeyList.length == 0">
|
||||
<a-button
|
||||
@click="confirmBatchDelete"
|
||||
v-privilege="'support:dict:batchDelete'"
|
||||
type="text"
|
||||
danger
|
||||
size="small"
|
||||
:disabled="selectedRowKeyList.length === 0"
|
||||
>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
@@ -76,7 +83,7 @@
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="addOrUpdateKey(record)" v-privilege="'support:dict:update'" type="link">编辑</a-button>
|
||||
<a-button @click="addOrUpdateKey(record)" v-privilege="'support:dict:edit'" type="link">编辑</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -109,7 +116,7 @@
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { dictApi } from '/@/api/support/dict/dict-api';
|
||||
import { dictApi } from '/@/api/support/dict-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
@@ -169,7 +176,7 @@
|
||||
Object.assign(queryForm, queryFormState);
|
||||
ajaxQuery();
|
||||
}
|
||||
function onSearch(){
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<a-range-picker
|
||||
v-model:value="chooseTimeRange"
|
||||
@change="changeCreateDate"
|
||||
:ranges="defaultTimeRanges"
|
||||
:presets="defaultTimeRanges"
|
||||
format="YYYY-MM-DD"
|
||||
style="width: 240px"
|
||||
/>
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<a-card size="small">
|
||||
<a-table rowKey="feedbackId" :dataSource="tableData" :columns="tableColumns" :pagination="false" :loading="tableLoading" size="small" bordered>
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template #bodyCell="{ text, column }">
|
||||
<template v-if="column.dataIndex === 'feedbackAttachment'">
|
||||
<FilePreview :fileList="text" />
|
||||
</template>
|
||||
@@ -75,7 +75,7 @@
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
|
||||
import { feedbackApi } from '/@/api/support/feedback/feedback-api';
|
||||
import { feedbackApi } from '/@/api/support/feedback-api';
|
||||
import FilePreview from '/@/components/support/file-preview/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<a-input style="width: 150px" v-model:value="queryForm.creatorName" placeholder="创建人" />
|
||||
</a-form-item>
|
||||
<a-form-item label="创建时间" class="smart-query-form-item">
|
||||
<a-range-picker v-model:value="queryForm.createTime" :ranges="defaultTimeRanges" style="width: 220px" @change="onChangeCreateTime" />
|
||||
<a-range-picker v-model:value="queryForm.createTime" :presets="defaultTimeRanges" style="width: 220px" @change="onChangeCreateTime" />
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="queryData">
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
<FilePreviewModal ref="filePreviewModalRef" />
|
||||
|
||||
<a-modal v-model:visible="uploadModalFlag" title="上传文件" @onCancel="hideUploadModal" @ok="hideUploadModal">
|
||||
<a-modal v-model:open="uploadModalFlag" title="上传文件" @onCancel="hideUploadModal" @ok="hideUploadModal">
|
||||
<FileUpload
|
||||
list-type="text"
|
||||
:maxUploadSize="5"
|
||||
@@ -113,7 +113,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { fileApi } from '/@/api/support/file/file-api';
|
||||
import { fileApi } from '/@/api/support/file-api';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
@@ -217,6 +217,12 @@
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
|
||||
function onSearch(){
|
||||
queryForm.pageNum = 1;
|
||||
queryData();
|
||||
}
|
||||
|
||||
async function queryData() {
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="心跳时间" class="smart-query-form-item">
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :ranges="defaultChooseTimeRange" style="width: 240px" />
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :presets="defaultChooseTimeRange" style="width: 240px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch" class="smart-margin-right10">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -53,39 +53,39 @@
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<a-row justify="end">
|
||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.HEART_BEAT" :refresh="ajaxQuery" />
|
||||
</a-row>
|
||||
<a-table
|
||||
size="small"
|
||||
bordered
|
||||
:loading="tableLoading"
|
||||
class="smart-margin-top10"
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="goodsId"
|
||||
:pagination="false"
|
||||
<a-row justify="end">
|
||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.HEART_BEAT" :refresh="ajaxQuery" />
|
||||
</a-row>
|
||||
<a-table
|
||||
size="small"
|
||||
bordered
|
||||
:loading="tableLoading"
|
||||
class="smart-margin-top10"
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="goodsId"
|
||||
:pagination="false"
|
||||
/>
|
||||
<div class="smart-query-table-page">
|
||||
<a-pagination
|
||||
showSizeChanger
|
||||
showQuickJumper
|
||||
show-less-items
|
||||
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
||||
:defaultPageSize="queryForm.pageSize"
|
||||
v-model:current="queryForm.pageNum"
|
||||
v-model:pageSize="queryForm.pageSize"
|
||||
:total="total"
|
||||
@change="ajaxQuery"
|
||||
@showSizeChange="ajaxQuery"
|
||||
:show-total="(total) => `共${total}条`"
|
||||
/>
|
||||
<div class="smart-query-table-page">
|
||||
<a-pagination
|
||||
showSizeChanger
|
||||
showQuickJumper
|
||||
show-less-items
|
||||
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
||||
:defaultPageSize="queryForm.pageSize"
|
||||
v-model:current="queryForm.pageNum"
|
||||
v-model:pageSize="queryForm.pageSize"
|
||||
:total="total"
|
||||
@change="ajaxQuery"
|
||||
@showSizeChange="ajaxQuery"
|
||||
:show-total="(total) => `共${total}条`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { heartBeatApi } from '/@/api/support/heart-beat/heart-beat-api';
|
||||
import { heartBeatApi } from '/@/api/support/heart-beat-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
@@ -117,17 +117,17 @@
|
||||
{
|
||||
title: '进程号',
|
||||
dataIndex: 'processNo',
|
||||
width:100
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '进程开启时间',
|
||||
dataIndex: 'processStartTime',
|
||||
width:150
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '心跳当前时间',
|
||||
dataIndex: 'heartBeatTime',
|
||||
width:150
|
||||
width: 150,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -148,6 +148,12 @@
|
||||
createDateRange.value = [];
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :title="formState.helpDocCatalogId ? '编辑目录' : '添加目录'" @ok="handleOk" destroyOnClose>
|
||||
<a-modal v-model:open="visible" :title="formState.helpDocCatalogId ? '编辑目录' : '添加目录'" @ok="handleOk" destroyOnClose>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
|
||||
<a-form-item label="上级目录" name="parentId" v-if="formState.parentId != 0">
|
||||
<a-form-item label="上级目录" name="parentId" v-if="formState.parentId !== 0">
|
||||
<HelpDocCatalogTreeSelect ref="helpDocCatalogTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false" width="100%" />
|
||||
</a-form-item>
|
||||
<a-form-item label="目录名称" name="name">
|
||||
@@ -22,13 +22,13 @@
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import message from 'ant-design-vue/lib/message';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc/help-doc-catalog-api';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc-catalog-api';
|
||||
import HelpDocCatalogTreeSelect from './help-doc-catalog-tree-select.vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
// ----------------------- 对外暴漏 ---------------------
|
||||
|
||||
@@ -116,7 +116,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
async function updateHelpDocCatalog() {
|
||||
SmartLoading.show();
|
||||
try {
|
||||
if (formState.parentId == formState.helpDocCatalogId) {
|
||||
if (formState.parentId === formState.helpDocCatalogId) {
|
||||
message.warning('上级菜单不能为自己');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc/help-doc-catalog-api';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc-catalog-api';
|
||||
|
||||
const props = defineProps({
|
||||
// 绑定值
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<template v-if="showSortFlag"> (越小越靠前) </template>
|
||||
:<a-switch v-model:checked="showSortFlag" />
|
||||
</span>
|
||||
<a-button type="primary" @click="addTop" size="small" v-privilege="'helpDocCatalog:addCategory'">新建</a-button>
|
||||
<a-button type="primary" @click="addTop" size="small" v-privilege="'support:helpDocCatalog:addCategory'">新建</a-button>
|
||||
</a-row>
|
||||
<a-tree
|
||||
v-if="!_.isEmpty(helpDocCatalogTreeData)"
|
||||
@@ -40,13 +40,13 @@
|
||||
<a-popover placement="right" v-if="props.showMenu">
|
||||
<template #content>
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<a-button type="text" @click="addHelpDocCatalog(item.dataRef)" v-privilege="'helpDocCatalog:addCategory'">添加下级</a-button>
|
||||
<a-button type="text" @click="updateHelpDocCatalog(item.dataRef)" v-privilege="'helpDocCatalog:edit'">修改</a-button>
|
||||
<a-button type="text" @click="addHelpDocCatalog(item.dataRef)" v-privilege="'support:helpDocCatalog:addCategory'">添加下级</a-button>
|
||||
<a-button type="text" @click="updateHelpDocCatalog(item.dataRef)" v-privilege="'support:helpDocCatalog:edit'">修改</a-button>
|
||||
<a-button
|
||||
type="text"
|
||||
v-if="item.helpDocCatalogId != topHelpDocCatalogId"
|
||||
v-if="item.helpDocCatalogId !== topHelpDocCatalogId"
|
||||
@click="deleteHelpDocCatalog(item.helpDocCatalogId)"
|
||||
v-privilege="'helpDocCatalog:delete'"
|
||||
v-privilege="'support:helpDocCatalog:delete'"
|
||||
>删除</a-button
|
||||
>
|
||||
</div>
|
||||
@@ -65,7 +65,7 @@
|
||||
<HelpDocCatalogFormModal ref="helpDocCatalogFormModal" @refresh="refresh" />
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { ref } from 'vue';
|
||||
import { onUnmounted, watch } from 'vue';
|
||||
@@ -73,10 +73,10 @@
|
||||
import _ from 'lodash';
|
||||
import { createVNode, onMounted } from 'vue';
|
||||
import HelpDocCatalogFormModal from './help-doc-catalog-form-modal.vue';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc/help-doc-catalog-api';
|
||||
import { helpDocCatalogApi } from '/@/api/support/help-doc-catalog-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import helpDocCatalogEmitter from '../help-doc-mitt';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const HELP_DOC_CATALOG_PARENT_ID = 0;
|
||||
|
||||
@@ -194,7 +194,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
return;
|
||||
}
|
||||
let id = idList[0];
|
||||
selectedHelpDocCatalogChildren.value = helpDocCatalogList.value.filter((e) => e.parentId == id);
|
||||
selectedHelpDocCatalogChildren.value = helpDocCatalogList.value.filter((e) => e.parentId === id);
|
||||
let filterHelpDocCatalogList = [];
|
||||
recursionFilterHelpDocCatalog(filterHelpDocCatalogList, id, true);
|
||||
breadcrumb.value = filterHelpDocCatalogList.map((e) => e.name);
|
||||
@@ -233,7 +233,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
// 根据ID递归筛选目录
|
||||
function recursionFilterHelpDocCatalog(resList, id, unshift) {
|
||||
let info = idInfoMap.value.get(id);
|
||||
if (!info || resList.some((e) => e.helpDocCatalogId == id)) {
|
||||
if (!info || resList.some((e) => e.helpDocCatalogId === id)) {
|
||||
return;
|
||||
}
|
||||
if (unshift) {
|
||||
@@ -241,7 +241,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
} else {
|
||||
resList.push(info);
|
||||
}
|
||||
if (info.parentId && info.parentId != 0) {
|
||||
if (info.parentId && info.parentId !== 0) {
|
||||
recursionFilterHelpDocCatalog(resList, info.parentId, unshift);
|
||||
}
|
||||
}
|
||||
@@ -289,8 +289,8 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
let selectedKey = null;
|
||||
if (!_.isEmpty(selectedKeys.value)) {
|
||||
selectedKey = selectedKeys.value[0];
|
||||
if (selectedKey == id) {
|
||||
let selectInfo = helpDocCatalogList.value.find((e) => e.helpDocCatalogId == id);
|
||||
if (selectedKey === id) {
|
||||
let selectInfo = helpDocCatalogList.value.find((e) => e.helpDocCatalogId === id);
|
||||
if (selectInfo && selectInfo.parentId) {
|
||||
selectedKey = selectInfo.parentId;
|
||||
}
|
||||
@@ -345,7 +345,6 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
.sort-span {
|
||||
margin-left: 5px;
|
||||
color: @success-color;
|
||||
}
|
||||
.no-data {
|
||||
margin: 10px;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:title="formData.helpDocId ? '编辑系统手册' : '新建系统手册'"
|
||||
:visible="visibleFlag"
|
||||
:open="visibleFlag"
|
||||
:width="1000"
|
||||
:footerStyle="{ textAlign: 'right' }"
|
||||
@close="onClose"
|
||||
@@ -64,17 +64,16 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import lodash from 'lodash';
|
||||
import { nextTick, reactive, ref } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
|
||||
import { helpDocApi } from '/@/api/support/help-doc/help-doc-api';
|
||||
import { helpDocApi } from '/@/api/support/help-doc-api';
|
||||
import Wangeditor from '/@/components/framework/wangeditor/index.vue';
|
||||
import Upload from '/@/components/support/file-upload/index.vue';
|
||||
import HelpDocCatalogTreeSelect from './help-doc-catalog-tree-select.vue';
|
||||
import MenuTreeSelect from '/@/components/system/menu-tree-select/index.vue';
|
||||
import _ from 'lodash';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const emits = defineEmits(['reloadList']);
|
||||
@@ -104,7 +103,6 @@
|
||||
|
||||
const formRef = ref();
|
||||
const contentRef = ref();
|
||||
const noticeFormVisibleModal = ref();
|
||||
const relateHomeFlag = ref(false);
|
||||
|
||||
const defaultFormData = {
|
||||
@@ -135,7 +133,7 @@
|
||||
SmartLoading.show();
|
||||
const result = await helpDocApi.getDetail(helpDocId);
|
||||
const attachment = result.data.attachment;
|
||||
if (!lodash.isEmpty(attachment)) {
|
||||
if (!_.isEmpty(attachment)) {
|
||||
defaultFileList.value = attachment;
|
||||
} else {
|
||||
defaultFileList.value = [];
|
||||
@@ -160,7 +158,7 @@
|
||||
formData.contentHtml = contentRef.value.getHtml();
|
||||
formData.contentText = contentRef.value.getText();
|
||||
await formRef.value.validateFields();
|
||||
save();
|
||||
await save();
|
||||
} catch (err) {
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
}
|
||||
@@ -206,7 +204,7 @@
|
||||
const defaultFileList = ref([]);
|
||||
function changeAttachment(fileList) {
|
||||
defaultFileList.value = fileList;
|
||||
formData.attachment = lodash.isEmpty(fileList) ? [] : fileList;
|
||||
formData.attachment = _.isEmpty(fileList) ? [] : fileList;
|
||||
}
|
||||
|
||||
// ----------------------- 以下是暴露的方法内容 ------------------------
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-form class="smart-query-form" v-privilege="'helpDoc:query'">
|
||||
<a-form class="smart-query-form" v-privilege="'support:helpDoc:query'">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="关键字" class="smart-query-form-item">
|
||||
<a-input style="width: 300px" v-model:value="queryForm.keywords" placeholder="标题、作者" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="创建时间" class="smart-query-form-item">
|
||||
<a-range-picker :ranges="defaultTimeRanges" v-model:value="createDate" @change="createDateChange" style="width: 220px" />
|
||||
<a-range-picker :presets="defaultTimeRanges" v-model:value="createDate" @change="createDateChange" style="width: 220px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
@@ -40,7 +40,7 @@
|
||||
<a-card size="small" :bordered="false">
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button type="primary" size="small" @click="addOrUpdate()" v-privilege="'helpDoc:add'">
|
||||
<a-button type="primary" size="small" @click="addOrUpdate()" v-privilege="'support:helpDoc:add'">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
@@ -70,8 +70,8 @@
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button type="link" @click="addOrUpdate(record.helpDocId)" v-privilege="'helpDoc:update'">编辑</a-button>
|
||||
<a-button type="link" danger @click="onDelete(record.helpDocId)" v-privilege="'helpDoc:delete'">删除</a-button>
|
||||
<a-button type="link" @click="addOrUpdate(record.helpDocId)" v-privilege="'support:helpDoc:update'">编辑</a-button>
|
||||
<a-button type="link" danger @click="onDelete(record.helpDocId)" v-privilege="'support:helpDoc:delete'">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -101,7 +101,7 @@
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import HelpDocFormDrawer from './help-doc-form-drawer.vue';
|
||||
import { helpDocApi } from '/@/api/support/help-doc/help-doc-api';
|
||||
import { helpDocApi } from '/@/api/support/help-doc-api';
|
||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { helpDocApi } from '/@/api/support/help-doc/help-doc-api';
|
||||
import { helpDocApi } from '/@/api/support/help-doc-api';
|
||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import uaparser from 'ua-parser-js';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import HelpDocViewRecordList from './components/help-doc-view-record-list.vue';
|
||||
import { helpDocApi } from '/@/api/support/help-doc/help-doc-api';
|
||||
import { helpDocApi } from '/@/api/support/help-doc-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import FilePreview from '/@/components/support/file-preview/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
<!--
|
||||
* 登录失败锁定
|
||||
*
|
||||
* @Author: 1024创新实验室-主任-卓大
|
||||
* @Date: 2023-10-17 18:02:37
|
||||
* @Copyright 1024创新实验室
|
||||
-->
|
||||
<template>
|
||||
<!---------- 查询表单form begin ----------->
|
||||
<a-form class="smart-query-form">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="登录名" class="smart-query-form-item">
|
||||
<a-input style="width: 300px" v-model:value="queryForm.loginName" placeholder="登录名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="快速筛选" class="smart-query-form-item">
|
||||
<a-radio-group v-model:value="queryForm.lockFlag" @change="onSearch" button-style="solid">
|
||||
<a-radio-button :value="undefined">全部</a-radio-button>
|
||||
<a-radio-button :value="true">已锁定</a-radio-button>
|
||||
<a-radio-button :value="false">未锁定</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="锁定时间" class="smart-query-form-item">
|
||||
<a-range-picker
|
||||
v-model:value="queryForm.loginLockBeginTime"
|
||||
:presets="defaultTimeRanges"
|
||||
style="width: 220px"
|
||||
@change="onChangeLoginLockBeginTime"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item class="smart-query-form-item">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<!---------- 查询表单form end ----------->
|
||||
|
||||
<a-card size="small" :bordered="false" :hoverable="true">
|
||||
<!---------- 表格操作行 begin ----------->
|
||||
<a-row class="smart-table-btn-block">
|
||||
<div class="smart-table-operate-block">
|
||||
<a-button @click="confirmBatchDelete" danger size="small" :disabled="selectedRowKeyList.length === 0">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
解除锁定
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="smart-table-setting-block">
|
||||
<TableOperator v-model="columns" :tableId="null" :refresh="queryData" />
|
||||
</div>
|
||||
</a-row>
|
||||
<!---------- 表格操作行 end ----------->
|
||||
|
||||
<!---------- 表格 begin ----------->
|
||||
<a-table
|
||||
size="small"
|
||||
:dataSource="tableData"
|
||||
:columns="columns"
|
||||
rowKey="loginFailId"
|
||||
bordered
|
||||
:loading="tableLoading"
|
||||
:pagination="false"
|
||||
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
|
||||
>
|
||||
<template #bodyCell="{ text, column }">
|
||||
<template v-if="column.dataIndex === 'userType'">
|
||||
<span>{{ $smartEnumPlugin.getDescByValue('USER_TYPE_ENUM', text) }}</span>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'lockFlag'">
|
||||
<template v-if="text">
|
||||
<a-tag color="error">已锁定</a-tag>
|
||||
</template>
|
||||
<template v-if="!text">
|
||||
<a-tag color="success">未锁定</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<!---------- 表格 end ----------->
|
||||
|
||||
<div class="smart-query-table-page">
|
||||
<a-pagination
|
||||
showSizeChanger
|
||||
showQuickJumper
|
||||
show-less-items
|
||||
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
||||
:defaultPageSize="queryForm.pageSize"
|
||||
v-model:current="queryForm.pageNum"
|
||||
v-model:pageSize="queryForm.pageSize"
|
||||
:total="total"
|
||||
@change="onSearch"
|
||||
@showSizeChange="onSearch"
|
||||
:show-total="(total) => `共${total}条`"
|
||||
/>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { loginFailApi } from '/@/api/support/login-fail-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
|
||||
|
||||
// ---------------------------- 表格列 ----------------------------
|
||||
|
||||
const columns = ref([
|
||||
{
|
||||
title: '登录名',
|
||||
dataIndex: 'loginName',
|
||||
},
|
||||
{
|
||||
title: '用户类型',
|
||||
dataIndex: 'userType',
|
||||
},
|
||||
{
|
||||
title: '登录失败次数',
|
||||
dataIndex: 'loginFailCount',
|
||||
},
|
||||
{
|
||||
title: '锁定状态',
|
||||
dataIndex: 'lockFlag',
|
||||
},
|
||||
{
|
||||
title: '锁定开始时间',
|
||||
dataIndex: 'loginLockBeginTime',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updateTime',
|
||||
},
|
||||
]);
|
||||
|
||||
// ---------------------------- 查询数据表单和方法 ----------------------------
|
||||
|
||||
const queryFormState = {
|
||||
loginName: undefined, //登录名
|
||||
lockFlag: true, // 锁定状态
|
||||
loginLockBeginTime: [], //登录失败锁定时间
|
||||
loginLockBeginTimeBegin: undefined, //登录失败锁定时间 开始
|
||||
loginLockBeginTimeEnd: undefined, //登录失败锁定时间 结束
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
// 查询表单form
|
||||
const queryForm = reactive({ ...queryFormState });
|
||||
// 表格加载loading
|
||||
const tableLoading = ref(false);
|
||||
// 表格数据
|
||||
const tableData = ref([]);
|
||||
// 总数
|
||||
const total = ref(0);
|
||||
|
||||
// 重置查询条件
|
||||
function resetQuery() {
|
||||
let pageSize = queryForm.pageSize;
|
||||
Object.assign(queryForm, queryFormState);
|
||||
queryForm.pageSize = pageSize;
|
||||
queryForm.lockFlag = undefined;
|
||||
queryData();
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
queryData();
|
||||
}
|
||||
|
||||
async function queryData() {
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
let queryResult = await loginFailApi.queryPage(queryForm);
|
||||
tableData.value = queryResult.data.list;
|
||||
total.value = queryResult.data.total;
|
||||
} catch (e) {
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onChangeLoginLockBeginTime(dates, dateStrings) {
|
||||
queryForm.loginLockBeginTimeBegin = dateStrings[0];
|
||||
queryForm.loginLockBeginTimeEnd = dateStrings[1];
|
||||
}
|
||||
|
||||
onMounted(queryData);
|
||||
|
||||
// ---------------------------- 批量解除锁定 ----------------------------
|
||||
|
||||
// 选择表格行
|
||||
const selectedRowKeyList = ref([]);
|
||||
|
||||
function onSelectChange(selectedRowKeys) {
|
||||
selectedRowKeyList.value = selectedRowKeys;
|
||||
}
|
||||
|
||||
// 批量解除锁定
|
||||
function confirmBatchDelete() {
|
||||
Modal.confirm({
|
||||
title: '提示',
|
||||
content: '确定要批量解除锁定这些数据吗?',
|
||||
okText: '解锁',
|
||||
okType: 'danger',
|
||||
onOk() {
|
||||
requestBatchDelete();
|
||||
},
|
||||
cancelText: '取消',
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
|
||||
//请求批量删除
|
||||
async function requestBatchDelete() {
|
||||
try {
|
||||
SmartLoading.show();
|
||||
await loginFailApi.batchDelete(selectedRowKeyList.value);
|
||||
message.success('解锁成功');
|
||||
queryData();
|
||||
} catch (e) {
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-form class="smart-query-form" v-privilege="'loginLog:query'" ref="queryFormRef">
|
||||
<a-form class="smart-query-form" v-privilege="'support:loginLog:query'" ref="queryFormRef">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="用户名称" class="smart-query-form-item">
|
||||
<a-input style="width: 300px" v-model:value="queryForm.userName" placeholder="用户名称" />
|
||||
@@ -19,17 +19,17 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="时间" class="smart-query-form-item">
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :ranges="defaultChooseTimeRange" style="width: 240px" />
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :presets="defaultChooseTimeRange" style="width: 240px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="onSearch">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
查询
|
||||
</a-button>
|
||||
<a-button @click="resetQuery">
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -99,7 +99,7 @@
|
||||
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
|
||||
import uaparser from 'ua-parser-js';
|
||||
import { LOGIN_RESULT_ENUM } from '/@/constants/support/login-log-const';
|
||||
import { loginLogApi } from '/@/api/support/login-log/login-log-api';
|
||||
import { loginLogApi } from '/@/api/support/login-log-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
||||
@@ -127,6 +127,11 @@
|
||||
dataIndex: 'loginIp',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'IP地区',
|
||||
dataIndex: 'loginIpRegion',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '设备信息',
|
||||
dataIndex: 'userAgent',
|
||||
@@ -175,6 +180,12 @@
|
||||
createDateRange.value = [];
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,37 +8,42 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" title="请求详情" width="60%" :footer="null" @cancel="close">
|
||||
<a-modal :open="visible" title="请求详情" width="60%" :footer="null" @cancel="close">
|
||||
<div class="info-box">
|
||||
<a-row class="smart-margin-top10">
|
||||
<a-col :span="16">
|
||||
<a-row class="detail-info">
|
||||
<a-col :span="12"> 请求地址: {{ detail.url }}</a-col>
|
||||
<a-col :span="12"> 请求url: {{ detail.url }}</a-col>
|
||||
<a-col :span="12"> 请求日期: {{ detail.createTime }}</a-col>
|
||||
</a-row>
|
||||
<a-row class="detail-info">
|
||||
<a-col> 请求方法: {{ detail.method }}</a-col>
|
||||
<a-col :span="12"> 请求IP: {{ detail.ip }}</a-col>
|
||||
<a-col :span="12"> IP地区: {{ detail.ipRegion }}</a-col>
|
||||
</a-row>
|
||||
<a-row class="detail-info">
|
||||
<a-col :span="12"> 用户id:{{ detail.operateUserId }}</a-col>
|
||||
<a-col :span="12"> 用户名称: {{ detail.operateUserName }}</a-col>
|
||||
<a-col :span="24"> 请求内容: {{ detail.module }} - {{ detail.content }}</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<p class="detail-right-title">请求状态</p>
|
||||
<p :class="['detail-right', detail.successFlag ? 'success' : 'error']">
|
||||
<a-typography-text class="detail-right" :type="detail.successFlag ? 'success' : 'danger'">
|
||||
{{ detail.successFlag ? '成功' : '失败' }}
|
||||
</p>
|
||||
</a-typography-text>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div class="info-box">
|
||||
<h4>请求明细:</h4>
|
||||
<a-col :span="24"> 方法: {{ detail.method }}</a-col>
|
||||
<a-col :span="24"> 说明: {{ detail.module }} - {{ detail.content }}</a-col>
|
||||
</div>
|
||||
<div class="info-box">
|
||||
<h4>请求参数:</h4>
|
||||
<JsonViewer :value="detail.param ? JSON.parse(detail.param) : ''" theme="jv-dark" copyable boxed sort />
|
||||
</div>
|
||||
<div class="info-box">
|
||||
<h4>请求参数:</h4>
|
||||
<div class="info-box" v-if="detail.failReason">
|
||||
<h4>请求失败原因:</h4>
|
||||
<div>
|
||||
{{ detail.failReason }}
|
||||
</div>
|
||||
@@ -49,8 +54,8 @@
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { JsonViewer } from 'vue3-json-viewer';
|
||||
import { operateLogApi } from '/@/api/support/operate-log/operate-log-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { operateLogApi } from '/@/api/support/operate-log-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
defineExpose({
|
||||
@@ -127,13 +132,6 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: @success-color;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: @error-color;
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-form class="smart-query-form" v-privilege="'operateLog:query'">
|
||||
<a-form class="smart-query-form" v-privilege="'support:operateLog:query'">
|
||||
<a-row class="smart-query-form-row">
|
||||
<a-form-item label="用户名称" class="smart-query-form-item">
|
||||
<a-input style="width: 300px" v-model:value="queryForm.userName" placeholder="用户名称" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="请求时间" class="smart-query-form-item">
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :ranges="defaultChooseTimeRange" style="width: 240px" />
|
||||
<a-range-picker @change="changeCreateDate" v-model:value="createDateRange" :presets="defaultChooseTimeRange" style="width: 240px" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="快速筛选" class="smart-query-form-item">
|
||||
<a-radio-group v-model:value="queryForm.successFlag" @change="ajaxQuery">
|
||||
<a-radio-group v-model:value="queryForm.successFlag" @change="onSearch">
|
||||
<a-radio-button :value="undefined">全部</a-radio-button>
|
||||
<a-radio-button :value="true">成功</a-radio-button>
|
||||
<a-radio-button :value="false">失败</a-radio-button>
|
||||
@@ -27,7 +27,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="smart-query-form-item smart-margin-left10">
|
||||
<a-button type="primary" @click="ajaxQuery">
|
||||
<a-button type="primary" @click="ajaxQuery" class="smart-margin-right10">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
@@ -43,11 +43,11 @@
|
||||
</a-row>
|
||||
</a-form>
|
||||
|
||||
<a-card size="small" :bordered="false" :hoverable="true" style="height:100%">
|
||||
<a-card size="small" :bordered="false" :hoverable="true" style="height: 100%">
|
||||
<a-row justify="end">
|
||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.CONFIG" :refresh="ajaxQuery" />
|
||||
</a-row>
|
||||
<a-table size="small" :loading="tableLoading" :dataSource="tableData" :columns="columns" bordered rowKey="operateLogId" :pagination="false" >
|
||||
<a-table size="small" :loading="tableLoading" :dataSource="tableData" :columns="columns" bordered rowKey="operateLogId" :pagination="false">
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'successFlag'">
|
||||
<a-tag :color="text ? 'success' : 'error'">{{ text ? '成功' : '失败' }}</a-tag>
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="showDetail(record.operateLogId)" type="link" v-privilege="'operateLog:detail'">详情</a-button>
|
||||
<a-button @click="showDetail(record.operateLogId)" type="link" v-privilege="'support:operateLog:detail'">详情</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -91,7 +91,7 @@
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import OperateLogDetailModal from './operate-log-detail-modal.vue';
|
||||
import { operateLogApi } from '/@/api/support/operate-log/operate-log-api';
|
||||
import { operateLogApi } from '/@/api/support/operate-log-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { defaultTimeRanges } from '/@/lib/default-time-ranges';
|
||||
import uaparser from 'ua-parser-js';
|
||||
@@ -131,6 +131,11 @@
|
||||
dataIndex: 'ip',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'IP地区',
|
||||
dataIndex: 'ipRegion',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '客户端',
|
||||
dataIndex: 'userAgent',
|
||||
@@ -185,6 +190,12 @@
|
||||
createDateRange.value = [];
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
queryForm.pageNum = 1;
|
||||
ajaxQuery();
|
||||
}
|
||||
|
||||
async function ajaxQuery() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" title="执行Reload" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" title="执行Reload" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
|
||||
<a-form-item label="标签">
|
||||
<a-input v-model:value="form.tag" :disabled="true" />
|
||||
@@ -25,7 +25,7 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { reloadApi } from '/@/api/support/reload/reload-api';
|
||||
import { reloadApi } from '/@/api/support/reload-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
rowKey="tag"
|
||||
:pagination="false"
|
||||
>
|
||||
<template #bodyCell="{ text, record, index, column }">
|
||||
<template #bodyCell="{ record, column }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="doReload(record.tag)" v-privilege="'reload:execute'" type="link">执行</a-button>
|
||||
<a-button @click="showResultList(record.tag)" v-privilege="'reload:result'" type="link">查看结果</a-button>
|
||||
<a-button @click="doReload(record.tag)" v-privilege="'support:reload:execute'" type="link">执行</a-button>
|
||||
<a-button @click="showResultList(record.tag)" v-privilege="'support:reload:result'" type="link">查看结果</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -59,10 +59,10 @@
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import DoReloadForm from './do-reload-form-modal.vue';
|
||||
import ReloadResultList from './reload-result-list.vue';
|
||||
import { reloadApi } from '/@/api/support/reload/reload-api';
|
||||
import { reloadApi } from '/@/api/support/reload-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" title="reload结果列表" width="60%" :footer="null" @cancel="onClose">
|
||||
<a-modal :open="visible" title="reload结果列表" width="60%" :footer="null" @cancel="onClose">
|
||||
<a-button type="primary" @click="ajaxQuery" size="small">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { reloadApi } from '/@/api/support/reload/reload-api';
|
||||
import { reloadApi } from '/@/api/support/reload-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
defineExpose({
|
||||
showModal,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" title="生成单号" ok-text="生成" cancel-text="关闭" @ok="onSubmit" @cancel="onClose">
|
||||
<a-modal :open="visible" title="生成单号" ok-text="生成" cancel-text="关闭" @ok="onSubmit" @cancel="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }">
|
||||
<a-form-item label="业务">
|
||||
<a-input v-model:value="form.businessName" :disabled="true" />
|
||||
@@ -34,7 +34,7 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number/serial-number-api';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import _ from 'lodash';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
</a-alert>
|
||||
|
||||
<a-row justify="end">
|
||||
<TableOperator class="smart-margin-bottom5 smart-margin-top5" v-model="columns" :tableId="TABLE_ID_CONST.SUPPORT.SERIAL_NUMBER" :refresh="ajaxQuery" />
|
||||
<TableOperator
|
||||
class="smart-margin-bottom5 smart-margin-top5"
|
||||
v-model="columns"
|
||||
:tableId="TABLE_ID_CONST.SUPPORT.SERIAL_NUMBER"
|
||||
:refresh="ajaxQuery"
|
||||
/>
|
||||
</a-row>
|
||||
|
||||
<a-table
|
||||
@@ -41,8 +46,8 @@
|
||||
<template #bodyCell="{ record, column }">
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button @click="generate(record)" v-privilege="'support:serial:number:generate'" type="link">生成</a-button>
|
||||
<a-button @click="showRecord(record.serialNumberId)" v-privilege="'support:serial:number:record'" type="link">查看记录</a-button>
|
||||
<a-button @click="generate(record)" v-privilege="'support:serialNumber:generate'" type="link">生成</a-button>
|
||||
<a-button @click="showRecord(record.serialNumberId)" v-privilege="'support:serialNumber:record'" type="link">查看记录</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -55,14 +60,13 @@
|
||||
<SerialNumberRecordList ref="recordList" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import SerialNumberGenerateFormModal from './serial-number-generate-form-modal.vue';
|
||||
import SerialNumberRecordList from './serial-number-record-list.vue';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number/serial-number-api';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
import SerialNumberGenerateFormModal from './serial-number-generate-form-modal.vue';
|
||||
import SerialNumberRecordList from './serial-number-record-list.vue';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number-api';
|
||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
//------------------------ 表格渲染 ---------------------
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal :visible="visible" title="每日生成结果记录" width="60%" :footer="null" @cancel="onClose">
|
||||
<a-modal :open="visible" title="每日生成结果记录" width="60%" :footer="null" @cancel="onClose">
|
||||
<a-table size="small" :dataSource="tableData" :columns="columns" bordered :pagination="false">
|
||||
<template #bodyCell="{ text, record, column }">
|
||||
<template v-if="column.dataIndex === 'successFlag'">
|
||||
@@ -40,7 +40,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number/serial-number-api';
|
||||
import { serialNumberApi } from '/@/api/support/serial-number-api';
|
||||
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
|
||||
|
||||
const router = useRouter();
|
||||
function goHome() {
|
||||
useRouter().push({ name: HOME_PAGE_NAME });
|
||||
router.push({ name: HOME_PAGE_NAME });
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-result status="404 title="对不起,您访问的内容不存在!">
|
||||
<a-result status="404" title="对不起,您访问的内容不存在!">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="goHome">返回首页</a-button>
|
||||
</template>
|
||||
@@ -18,7 +18,8 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
|
||||
|
||||
const router = useRouter();
|
||||
function goHome() {
|
||||
useRouter().push({ name: HOME_PAGE_NAME });
|
||||
router.push({ name: HOME_PAGE_NAME });
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import emitter from '/@/views/system/employee/department/department-mitt';
|
||||
import emitter from '../../department-mitt';
|
||||
|
||||
const props = defineProps({
|
||||
breadcrumb: Array,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
|
||||
<a-modal v-model:open="visible" :title="formState.departmentId ? '编辑部门' : '添加部门'" @ok="handleOk" destroyOnClose>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" layout="vertical">
|
||||
<a-form-item label="上级部门" name="parentId" v-if="formState.parentId != 0">
|
||||
<DepartmentTreeSelect ref="departmentTreeSelect" v-model:value="formState.parentId" :defaultValueFlag="false" width="100%" />
|
||||
@@ -28,7 +28,7 @@
|
||||
<script setup lang="ts">
|
||||
import message from 'ant-design-vue/lib/message';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { departmentApi } from '/@/api/system/department/department-api';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import EmployeeSelect from '/@/components/system/employee-select/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
import _ from 'lodash';
|
||||
import { createVNode, onMounted } from 'vue';
|
||||
import DepartmentFormModal from '../department-form-modal/index.vue';
|
||||
import { departmentApi } from '/@/api/system/department/department-api';
|
||||
import { departmentApi } from '/@/api/system/department-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import departmentEmitter from '/@/views/system/employee/department/department-mitt';
|
||||
import departmentEmitter from '../../department-mitt';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const DEPARTMENT_PARENT_ID = 0;
|
||||
@@ -330,7 +330,6 @@
|
||||
|
||||
.sort-span {
|
||||
margin-left: 5px;
|
||||
color: @success-color;
|
||||
}
|
||||
.no-data {
|
||||
margin: 10px;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" title="调整部门" :footer="null" destroyOnClose>
|
||||
<a-modal v-model:open="visible" title="调整部门" :footer="null" destroyOnClose>
|
||||
<DepartmentTree ref="departmentTree" :height="400" :showMenu="false" />
|
||||
<div class="footer">
|
||||
<a-button style="margin-right: 8px" @click="closeModal">取消</a-button>
|
||||
@@ -18,12 +18,12 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { ref } from 'vue';
|
||||
import DepartmentTree from '../department-tree/index.vue';
|
||||
import { employeeApi } from '/@/api/system/employee/employee-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import _ from 'lodash';
|
||||
import { ref } from 'vue';
|
||||
import DepartmentTree from '../department-tree/index.vue';
|
||||
import { employeeApi } from '/@/api/system/employee-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
// ----------------------- 以下是字段定义 emits props ---------------------
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<a-drawer
|
||||
:title="form.employeeId ? '编辑' : '添加'"
|
||||
:width="600"
|
||||
:visible="visible"
|
||||
:open="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
destroyOnClose
|
||||
@@ -56,8 +56,8 @@
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { nextTick, reactive, ref } from 'vue';
|
||||
import { employeeApi } from '/@/api/system/employee/employee-api';
|
||||
import { roleApi } from '/@/api/system/role/role-api';
|
||||
import { employeeApi } from '/@/api/system/employee-api';
|
||||
import { roleApi } from '/@/api/system/role-api';
|
||||
import DepartmentTreeSelect from '/@/components/system/department-tree-select/index.vue';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { GENDER_ENUM } from '/@/constants/common-const';
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { computed, createVNode, reactive, ref, watch } from 'vue';
|
||||
import { employeeApi } from '/@/api/system/employee/employee-api';
|
||||
import { employeeApi } from '/@/api/system/employee-api';
|
||||
import { PAGE_SIZE } from '/@/constants/common-const';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import EmployeeFormModal from '../employee-form-modal/index.vue';
|
||||
@@ -202,7 +202,7 @@
|
||||
params.departmentId = props.departmentId;
|
||||
let res = await employeeApi.queryEmployee(params);
|
||||
for (const item of res.data.list) {
|
||||
item.roleNameList = _.join(item.roleNameList,',');
|
||||
item.roleNameList = _.join(item.roleNameList, ',');
|
||||
}
|
||||
tableData.value = res.data.list;
|
||||
total.value = res.data.total;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||
-->
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" :zIndex="9999" :width="500" title="提示" :closable="false" :maskClosable="false">
|
||||
<a-modal v-model:open="visible" :zIndex="9999" :width="500" title="提示" :closable="false" :maskClosable="false">
|
||||
<!-- -->
|
||||
<ul>
|
||||
<li>登录名: {{ showLoginName }}</li>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div>
|
||||
<div class="btn-group">
|
||||
<a-button class="button-style" type="primary" @click="updateDataScope" v-privilege="'system:role:dataScope:update'"> 保存 </a-button>
|
||||
<a-button class="button-style" @click="getDataScope" v-privilege="'role:query'"> 刷新 </a-button>
|
||||
<a-button class="button-style" @click="getDataScope" > 刷新 </a-button>
|
||||
</div>
|
||||
<a-row class="header">
|
||||
<a-col class="tab-margin" :span="4">业务单据</a-col>
|
||||
@@ -46,7 +46,7 @@
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { inject, onMounted, ref, watch } from 'vue';
|
||||
import { roleApi } from '/@/api/system/role/role-api';
|
||||
import { roleApi } from '/@/api/system/role-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div>
|
||||
关键字:
|
||||
<a-input style="width: 250px" v-model:value="queryForm.keywords" placeholder="姓名/手机号/登录账号" />
|
||||
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="queryRoleEmployee">搜索</a-button>
|
||||
<a-button class="button-style" v-if="selectRoleId" type="primary" @click="onSearch">搜索</a-button>
|
||||
<a-button class="button-style" v-if="selectRoleId" type="default" @click="resetQueryRoleEmployee">重置</a-button>
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { computed, inject, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { roleApi } from '/@/api/system/role/role-api';
|
||||
import { roleApi } from '/@/api/system/role-api';
|
||||
import { PAGE_SIZE, showTableTotal, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import EmployeeTableSelectModal from '/@/components/system/employee-table-select-modal/index.vue';
|
||||
@@ -110,6 +110,11 @@
|
||||
queryRoleEmployee();
|
||||
}
|
||||
|
||||
function onSearch(){
|
||||
queryForm.pageNum = 1;
|
||||
queryRoleEmployee();
|
||||
}
|
||||
|
||||
async function queryRoleEmployee() {
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<a-modal :title="form.roleId ? '编辑角色' : '添加角色'" :width="600" :visible="modalVisible" @cancel="onClose" :footer="null">
|
||||
<a-modal :title="form.roleId ? '编辑角色' : '添加角色'" :width="600" :open="modalVisible" @cancel="onClose" :footer="null">
|
||||
<a-form ref="formRef" :model="form" :rules="rules" :labelCol="{ span: 4 }">
|
||||
<a-form-item label="角色名称" name="roleName">
|
||||
<a-input style="width: 100%" placeholder="请输入角色名称" v-model:value="form.roleName" />
|
||||
</a-form-item>
|
||||
<a-form-item label="角色编码" name="roleCode">
|
||||
<a-input style="width: 100%" placeholder="请输入角色编码" v-model:value="form.roleCode" />
|
||||
</a-form-item>
|
||||
<a-form-item label="角色备注">
|
||||
<a-input style="width: 100%" placeholder="请输入角色备注" v-model:value="form.remark" />
|
||||
</a-form-item>
|
||||
@@ -29,8 +32,8 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { roleApi } from '/@/api/system/role/role-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { roleApi } from '/@/api/system/role-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
// ----------------------- 以下是字段定义 emits props ---------------------
|
||||
let emits = defineEmits(['refresh']);
|
||||
@@ -62,6 +65,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
const formDefault = {
|
||||
id: undefined,
|
||||
remark: undefined,
|
||||
roleCode: undefined,
|
||||
roleName: undefined,
|
||||
};
|
||||
|
||||
@@ -70,6 +74,7 @@ import { smartSentry } from '/@/lib/smart-sentry';
|
||||
// 表单规则
|
||||
const rules = {
|
||||
roleName: [{ required: true, message: '请输入角色名称' }],
|
||||
roleCode: [{ required: true, message: '请输入角色编码' }],
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { roleApi } from '/@/api/system/role/role-api';
|
||||
import { roleApi } from '/@/api/system/role-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import RoleFormModal from '../role-form-modal/index.vue';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import RoleTreeCheckbox from './role-tree-checkbox.vue';
|
||||
import { roleMenuApi } from '/@/api/system/role-menu/role-menu-api';
|
||||
import { roleMenuApi } from '/@/api/system/role-menu-api';
|
||||
import { useRoleStore } from '/@/store/modules/system/role';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<div style="height: 542px; overflow: auto">
|
||||
<div style="overflow: auto">
|
||||
<a-checkbox-group v-model:value="checkedData">
|
||||
<div class="checked-box">
|
||||
<ul>
|
||||
@@ -32,7 +32,7 @@
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
defineEmits('update:value');
|
||||
defineEmits(['update:value']);
|
||||
|
||||
let roleStore = useRoleStore();
|
||||
let checkedData = ref();
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
defineEmits('update:value');
|
||||
defineEmits(['update:value']);
|
||||
let roleStore = useRoleStore();
|
||||
function selectCheckbox(module) {
|
||||
if (!module.menuId) {
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
let emits = defineEmits('selectCheckbox');
|
||||
let emits = defineEmits(['selectCheckbox']);
|
||||
</script>
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
defineProps({
|
||||
value: Object,
|
||||
});
|
||||
defineEmits('update:value');
|
||||
defineEmits(['update:value']);
|
||||
|
||||
let roleList = ref();
|
||||
const selectRoleId = computed(() => {
|
||||
@@ -42,7 +42,7 @@
|
||||
.height100 {
|
||||
height: 100%;
|
||||
}
|
||||
.role-setting{
|
||||
width:calc(100% - 250px)
|
||||
.role-setting {
|
||||
width: calc(100% - 250px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { changeLogApi } from '/@/api/support/change-log/change-log-api';
|
||||
import { changeLogApi } from '/@/api/support/change-log-api';
|
||||
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
|
||||
import ChangeLogForm from '/@/views/support/change-log/change-log-modal.vue';
|
||||
|
||||
@@ -88,20 +88,7 @@
|
||||
|
||||
.time {
|
||||
flex-shrink: 0;
|
||||
color: @text-color-secondary;
|
||||
min-width: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
ul li :hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.un-read a {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.read a {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<default-home-card icon="ProfileTwoTone" title="【1024创新实验室】人员饭量">
|
||||
<default-home-card icon="ProfileTwoTone" title="销量统计">
|
||||
<div class="echarts-box">
|
||||
<div class="category-main" id="category-main"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<default-home-card icon="FundTwoTone" title="【1024创新实验室】代码提交量">
|
||||
<default-home-card icon="FundTwoTone" title="代码提交量">
|
||||
<div class="echarts-box">
|
||||
<div class="gradient-main" id="gradient-main"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<default-home-card icon="PieChartTwoTone" title="【1024创新实验室】上班摸鱼次数">
|
||||
<default-home-card icon="PieChartTwoTone" title="加班统计">
|
||||
<div class="echarts-box">
|
||||
<div class="pie-main" id="pie-main"></div>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@ function init(){
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '摸鱼次数',
|
||||
name: '加班次数',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<default-home-card icon="SmileTwoTone" title="添加微信,关注【小镇程序员】、【1024创新实验室】">
|
||||
<default-home-card icon="SmileTwoTone" title="联系我们">
|
||||
<div class="app-qr-box">
|
||||
<div class="app-qr">
|
||||
<img :src="zhuoda" />
|
||||
@@ -18,22 +18,16 @@
|
||||
</div>
|
||||
<div class="app-qr">
|
||||
<img :src="xiaozhen" />
|
||||
<span class="qr-desc strong"> 小镇程序员 </span>
|
||||
<span class="qr-desc"> 代码与生活,还有钱途 </span>
|
||||
</div>
|
||||
<div class="app-qr">
|
||||
<img :src="lab1024" />
|
||||
<span class="qr-desc strong"> 1024创新实验室 </span>
|
||||
<span class="qr-desc"> 官方账号 </span>
|
||||
<span class="qr-desc strong"> 六边形工程师 </span>
|
||||
<span class="qr-desc"> 赚钱、代码、生活 </span>
|
||||
</div>
|
||||
</div>
|
||||
</default-home-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
|
||||
import lab1024 from '/@/assets/images/1024lab/1024lab-gzh.jpg';
|
||||
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
|
||||
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg';
|
||||
import xiaozhen from '/@/assets/images/1024lab/gzh.jpg';
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.app-qr-box {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="visible" title="新建快捷入口" @close="onClose">
|
||||
<a-modal v-model:open="visible" title="新建快捷入口" @close="onClose">
|
||||
<a-form ref="formRef" :model="form" :rules="rules">
|
||||
<a-form-item label="图标" name="icon">
|
||||
<IconSelect @updateIcon="selectIcon">
|
||||
<template #iconSelect>
|
||||
<a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px"/>
|
||||
<component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px"/>
|
||||
<a-input v-model:value="form.icon" placeholder="请输入菜单图标" style="width: 200px" />
|
||||
<component :is="$antIcons[form.icon]" class="smart-margin-left15" style="font-size: 20px" />
|
||||
</template>
|
||||
</IconSelect>
|
||||
</a-form-item>
|
||||
<a-form-item label="标题" name="title">
|
||||
<a-input v-model:value="form.title" placeholder="请输入标题"/>
|
||||
<a-input v-model:value="form.title" placeholder="请输入标题" />
|
||||
</a-form-item>
|
||||
<a-form-item label="路径" name="path">
|
||||
<a-input v-model:value="form.path" placeholder="请输入路径"/>
|
||||
<a-input v-model:value="form.path" placeholder="请输入路径" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
@@ -23,59 +23,58 @@
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import {reactive, ref} from "vue";
|
||||
import {message} from "ant-design-vue";
|
||||
import IconSelect from '/@/components/framework/icon-select/index.vue';
|
||||
import _ from "lodash";
|
||||
import { reactive, ref } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import IconSelect from '/@/components/framework/icon-select/index.vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
defineExpose({
|
||||
showModal
|
||||
})
|
||||
defineExpose({
|
||||
showModal,
|
||||
});
|
||||
|
||||
const emit = defineEmits("addQuickEntry");
|
||||
const emit = defineEmits(['addQuickEntry']);
|
||||
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
// 组件ref
|
||||
const formRef = ref();
|
||||
|
||||
const formDefault = {
|
||||
icon: undefined,
|
||||
title: "",
|
||||
path: "",
|
||||
};
|
||||
let form = reactive({...formDefault});
|
||||
const rules = {
|
||||
icon: [{required: true, message: "请选择图标"}],
|
||||
title: [{required: true, message: "标题不能为空"}],
|
||||
path: [{required: true, message: "路径不能为空"}],
|
||||
};
|
||||
const formDefault = {
|
||||
icon: undefined,
|
||||
title: '',
|
||||
path: '',
|
||||
};
|
||||
let form = reactive({ ...formDefault });
|
||||
const rules = {
|
||||
icon: [{ required: true, message: '请选择图标' }],
|
||||
title: [{ required: true, message: '标题不能为空' }],
|
||||
path: [{ required: true, message: '路径不能为空' }],
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const visible = ref(false);
|
||||
|
||||
function showModal() {
|
||||
visible.value = true;
|
||||
}
|
||||
function showModal() {
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
function selectIcon(icon) {
|
||||
form.icon = icon;
|
||||
}
|
||||
function selectIcon(icon) {
|
||||
form.icon = icon;
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
visible.value = false;
|
||||
}
|
||||
function onClose() {
|
||||
Object.assign(form, formDefault);
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
formRef.value
|
||||
function onSubmit() {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
emit("addQuickEntry", _.cloneDeep(form));
|
||||
emit('addQuickEntry', _.cloneDeep(form));
|
||||
onClose();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("error", error);
|
||||
message.error("参数验证错误,请仔细填写表单数据!");
|
||||
console.log('error', error);
|
||||
message.error('参数验证错误,请仔细填写表单数据!');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang='less' scoped></style>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
export default [
|
||||
'每个人的一生好比一根蜡烛,看似不经意间散发的光和热,都可能照亮和温暖他人。这是生活赋予我们的智慧,也让我们在寻常的日子成为一个温暖善良的人。',
|
||||
'立规矩的目的,不是禁锢、限制,而是教育;孩子犯了错,父母不能帮孩子逃避,而应该让孩子学会承担责任。让孩子有面对错误的诚实和勇气,这才是立规矩的意义所在。',
|
||||
'人这一辈子,格局大了、善良有了,成功自然也就近了。格局越大,人生越宽。你的人生会是什么样,与你在为人处世时的表现有很大关系。世间美好都是环环相扣的,善良的人总不会被亏待。',
|
||||
'平日里的千锤百炼,才能托举出光彩时刻;逆境中的亮剑、失败后的奋起,才能让梦想成真。哪有什么一战成名,其实都是百炼成钢。“天才”都是汗水浇灌出来的,天赋或许可以决定起点,但唯有坚持和努力才能达到终点。',
|
||||
'家,不在于奢华,而在于温馨;家,不在于大小,而在于珍惜。在家里,有父母的呵护,有爱人的陪伴,有子女的欢笑。一家人整整齐齐、和和睦睦,就是人生最大的幸福!',
|
||||
'每一个不向命运低头、努力生活的人,都值得被尊重。',
|
||||
'青年的肩上,从不只有清风明月,更有责任担当。岁月因青春慨然以赴而更加美好,世间因少年挺身向前而更加瑰丽。请相信,不会有人永远年轻,但永远有人年轻。',
|
||||
'人生路上,总有人走得比你快,但不必介意,也不必着急。一味羡慕别人的成绩,只会给自己平添压力、徒增烦恼。不盲从别人的脚步,坚定目标,才能找到自己的节奏,进而逢山开路、遇水搭桥。',
|
||||
'如果你真的在乎一个人,首先要学会的就是感恩对方的好。这样,对方才会在和你的相处中找到价值感,相处起来也会更加舒适愉悦。',
|
||||
'一个人只有心里装得下别人,有换位思考的品质,有为他人谋幸福的信念,才能真正做到慷慨施予。同样,也只有赠人玫瑰而无所求时,你才会手有余香、真有所得。',
|
||||
];
|
||||
@@ -10,26 +10,23 @@
|
||||
-->
|
||||
<template>
|
||||
<div class="user-header">
|
||||
<a-page-header :title="welcomeSentence" :sub-title="departmentName" >
|
||||
<template #tags>
|
||||
<a-tag color="blue">努力工作</a-tag>
|
||||
<a-tag color="success">主动 / 皮实 / 可靠 </a-tag>
|
||||
<a-tag color="error">自省 / 精进 / 创新</a-tag>
|
||||
<a-page-header :title="welcomeSentence">
|
||||
<template #subTitle>
|
||||
<span style="color: #666; margin-left: 20px;">所属部门:{{ departmentName }} </span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<p>{{ dayInfo }}</p>
|
||||
<p style="color: #333">{{ dayInfo }}</p>
|
||||
</template>
|
||||
<a-row class="content">
|
||||
<span class="heart-sentence">
|
||||
<h3>{{ heartSentence }}</h3>
|
||||
<p class="last-login-info">{{ lastLoginInfo }}</p>
|
||||
<div></div>
|
||||
<span class="left-content">
|
||||
<p class="last-login-info"><AlertOutlined />{{ lastLoginInfo }}</p>
|
||||
<a class="sentence" href="https://sentence.1024lab.net/" target="_blank"> <smile-outlined spin /> {{ heartSentence }} </a>
|
||||
</span>
|
||||
<div class="weather">
|
||||
<iframe
|
||||
width="100%"
|
||||
scrolling="no"
|
||||
height="60"
|
||||
height="50"
|
||||
frameborder="0"
|
||||
allowtransparency="true"
|
||||
src="//i.tianqi.com/index.php?c=code&id=12&icon=1&num=3&site=12"
|
||||
@@ -45,10 +42,11 @@
|
||||
import uaparser from 'ua-parser-js';
|
||||
import { Solar, Lunar } from 'lunar-javascript';
|
||||
import _ from 'lodash';
|
||||
import heartSentenceArray from './heart-sentence';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const departmentName = computed(() => useUserStore.departmentName);
|
||||
const departmentName = computed(() => userStore.departmentName);
|
||||
|
||||
// 欢迎语
|
||||
const welcomeSentence = computed(() => {
|
||||
@@ -74,9 +72,7 @@
|
||||
if (userStore.$state.lastLoginTime) {
|
||||
info = info + '上次登录:' + userStore.$state.lastLoginTime;
|
||||
}
|
||||
if (userStore.$state.lastLoginIp) {
|
||||
info = info + '; IP:' + userStore.$state.lastLoginIp;
|
||||
}
|
||||
|
||||
if (userStore.$state.lastLoginUserAgent) {
|
||||
let ua = uaparser(userStore.$state.lastLoginUserAgent);
|
||||
info = info + '; 设备:';
|
||||
@@ -88,9 +84,16 @@
|
||||
}
|
||||
let device = ua.device.vendor ? ua.device.vendor + ua.device.model : null;
|
||||
if (device) {
|
||||
info = info + ' ' + device;
|
||||
info = info + ' ' + device + ';';
|
||||
}
|
||||
}
|
||||
|
||||
if (userStore.$state.lastLoginIpRegion) {
|
||||
info = info + '; ' + userStore.$state.lastLoginIpRegion;
|
||||
}
|
||||
if (userStore.$state.lastLoginIp) {
|
||||
info = info + '; ' + userStore.$state.lastLoginIp;
|
||||
}
|
||||
return info;
|
||||
});
|
||||
|
||||
@@ -113,18 +116,6 @@
|
||||
});
|
||||
|
||||
// 毒鸡汤
|
||||
const heartSentenceArray = [
|
||||
'每个人的一生好比一根蜡烛,看似不经意间散发的光和热,都可能照亮和温暖他人。这是生活赋予我们的智慧,也让我们在寻常的日子成为一个温暖善良的人。',
|
||||
'立规矩的目的,不是禁锢、限制,而是教育;孩子犯了错,父母不能帮孩子逃避,而应该让孩子学会承担责任。让孩子有面对错误的诚实和勇气,这才是立规矩的意义所在。',
|
||||
'人这一辈子,格局大了、善良有了,成功自然也就近了。格局越大,人生越宽。你的人生会是什么样,与你在为人处世时的表现有很大关系。世间美好都是环环相扣的,善良的人总不会被亏待。',
|
||||
'平日里的千锤百炼,才能托举出光彩时刻;逆境中的亮剑、失败后的奋起,才能让梦想成真。哪有什么一战成名,其实都是百炼成钢。“天才”都是汗水浇灌出来的,天赋或许可以决定起点,但唯有坚持和努力才能达到终点。',
|
||||
'家,不在于奢华,而在于温馨;家,不在于大小,而在于珍惜。在家里,有父母的呵护,有爱人的陪伴,有子女的欢笑。一家人整整齐齐、和和睦睦,就是人生最大的幸福!',
|
||||
'每一个不向命运低头、努力生活的人,都值得被尊重。',
|
||||
'青年的肩上,从不只有清风明月,更有责任担当。岁月因青春慨然以赴而更加美好,世间因少年挺身向前而更加瑰丽。请相信,不会有人永远年轻,但永远有人年轻。',
|
||||
'人生路上,总有人走得比你快,但不必介意,也不必着急。一味羡慕别人的成绩,只会给自己平添压力、徒增烦恼。不盲从别人的脚步,坚定目标,才能找到自己的节奏,进而逢山开路、遇水搭桥。',
|
||||
'如果你真的在乎一个人,首先要学会的就是感恩对方的好。这样,对方才会在和你的相处中找到价值感,相处起来也会更加舒适愉悦。',
|
||||
'一个人只有心里装得下别人,有换位思考的品质,有为他人谋幸福的信念,才能真正做到慷慨施予。同样,也只有赠人玫瑰而无所求时,你才会手有余香、真有所得。',
|
||||
];
|
||||
const heartSentence = computed(() => {
|
||||
return heartSentenceArray[_.random(0, heartSentenceArray.length - 1)];
|
||||
});
|
||||
@@ -135,7 +126,7 @@
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.heart-sentence {
|
||||
.left-content {
|
||||
width: calc(100% - 420px);
|
||||
h3 {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
@@ -152,8 +143,23 @@
|
||||
|
||||
.last-login-info {
|
||||
font-size: 13px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
color: #333;
|
||||
overflow-wrap: break-word;
|
||||
padding: 0;
|
||||
margin: 1px 0 0 0;
|
||||
}
|
||||
|
||||
.sentence {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #acacac;
|
||||
overflow-wrap: break-word;
|
||||
padding: 5px 0 0 0;
|
||||
margin: 6px 0 0 0;
|
||||
}
|
||||
.sentence:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,32 +11,36 @@
|
||||
<template>
|
||||
<default-home-card extra="更多" icon="SoundTwoTone" title="通知公告" @extraClick="onMore">
|
||||
<a-spin :spinning="loading">
|
||||
<div class="content-wrapper">
|
||||
<a-empty v-if="$lodash.isEmpty(data)" />
|
||||
<ul v-else>
|
||||
<li v-for="(item, index) in data" :key="index" :class="[item.viewFlag ? 'read' : 'un-read']">
|
||||
<a-tooltip placement="top">
|
||||
<template #title>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<a class="content" @click="toDetail(item.noticeId)">
|
||||
<a-badge :status="item.viewFlag ? 'default' : 'error'" />
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<span class="time"> {{ item.publishDate }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="content-wrapper">
|
||||
<a-empty v-if="$lodash.isEmpty(data)" />
|
||||
<ul v-else>
|
||||
<li v-for="(item, index) in data" :key="index" :class="[item.viewFlag ? 'read' : 'un-read']">
|
||||
<a-tooltip placement="top">
|
||||
<template #title>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<a class="content" @click="toDetail(item.noticeId)">
|
||||
<a-badge :status="item.viewFlag ? 'default' : 'error'" />
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<span class="time"> {{ item.publishDate }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a-spin>
|
||||
</default-home-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { noticeApi } from '/@/api/business/oa/notice-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { noticeApi } from '/@/api/business/oa/notice-api';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import DefaultHomeCard from '/@/views/system/home/components/default-home-card.vue';
|
||||
import { theme } from 'ant-design-vue';
|
||||
const { useToken } = theme;
|
||||
const { token } = useToken();
|
||||
const colorPrimary = token.value.colorPrimary;
|
||||
|
||||
const props = defineProps({
|
||||
noticeTypeId: {
|
||||
@@ -90,7 +94,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@read-color: #666;
|
||||
.content-wrapper{
|
||||
.content-wrapper {
|
||||
height: 150px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
@@ -106,6 +110,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
margin-right: 5px;
|
||||
color: v-bind(colorPrimary);
|
||||
}
|
||||
|
||||
.time {
|
||||
@@ -115,15 +120,7 @@ import DefaultHomeCard from '/@/views/system/home/components/default-home-card.v
|
||||
}
|
||||
}
|
||||
|
||||
ul li :hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.un-read a {
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.read a {
|
||||
color: @read-color;
|
||||
color: @read-color !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
margin: 40px 0 60px 0;
|
||||
line-height: 21px;
|
||||
|
||||
.setence {
|
||||
font-size: 13px;
|
||||
@@ -106,7 +107,7 @@
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-220%);
|
||||
transform: translateX(-30%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
animation: marquee 15s linear infinite;
|
||||
animation: marquee 5s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,10 +129,9 @@
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
color: #1e1e1e;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
.login-form {
|
||||
margin-top: 37px;
|
||||
|
||||
.captcha-input {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
<div class="login-container">
|
||||
<div class="box-item desc">
|
||||
<div class="welcome">
|
||||
<p>欢迎登录 SmartAdmin V2</p>
|
||||
<p>欢迎登录 SmartAdmin V3</p>
|
||||
<p class="desc">
|
||||
SmartAdmin 是由 河南·洛阳
|
||||
<a target="_blank" href="https://www.1024lab.net"
|
||||
style="color: white; weight: bolder; font-size: 15px; text-decoration: underline">1024创新实验室(1024Lab)</a>
|
||||
使用SpringBoot2.x 和 Vue3.2 Setup语法糖、 Composition Api (同时支持JavaScript和TypeScript双版本) ,开发出的一套简洁、易用的中后台解决方案!
|
||||
<a target="_blank" href="https://www.1024lab.net" style="color: white; weight: bolder; font-size: 15px; text-decoration: underline"
|
||||
>1024创新实验室(1024Lab)</a
|
||||
>
|
||||
基于SpringBoot + Sa-Token + Mybatis-Plus 和 Vue3 + Vite5 + Ant Design Vue 4 (同时支持JavaScript和TypeScript双版本)
|
||||
以「高质量代码」为核心,「简洁、高效、安全」的快速开发平台。
|
||||
<br />
|
||||
<br />
|
||||
<span class="setence">
|
||||
@@ -28,9 +30,8 @@
|
||||
保持谦逊,保持学习,热爱代码,更热爱生活 !<br />
|
||||
永远年轻,永远前行 !<br />
|
||||
<span class="author">
|
||||
<a target="_blank" href="https://zhuoda.vip"
|
||||
style="color: white; font-size: 13px; text-decoration: underline">
|
||||
1024创新实验室-主任:卓大
|
||||
<a target="_blank" href="https://zhuoda.vip" style="color: white; font-size: 13px; text-decoration: underline">
|
||||
1024创新实验室-主任:卓大
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
@@ -42,8 +43,12 @@
|
||||
<span class="qr-desc"> 加微信,骚扰卓大 :) </span>
|
||||
</div>
|
||||
<div class="app-qr">
|
||||
<img :src="xiaozhen" />
|
||||
<div class="qr-desc-marquee"><div class="marquee"><span>关注:小镇程序员,了解二三线城市程序员的代码与“钱途”,技术与生活,城市可能无法选择,但未来可以拼搏。</span></div></div>
|
||||
<img :src="gzh" />
|
||||
<div class="qr-desc-marquee">
|
||||
<div class="marquee">
|
||||
<span>关注:六边形工程师,分享:赚钱、代码、生活</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,8 +60,12 @@
|
||||
<a-input v-model:value.trim="loginForm.loginName" placeholder="请输入用户名" />
|
||||
</a-form-item>
|
||||
<a-form-item name="password">
|
||||
<a-input-password v-model:value="loginForm.password" autocomplete="on"
|
||||
:type="showPassword ? 'text' : 'password'" placeholder="请输入密码" />
|
||||
<a-input-password
|
||||
v-model:value="loginForm.password"
|
||||
autocomplete="on"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
placeholder="请输入密码:至少三种字符,最小 8 位"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item name="captchaCode">
|
||||
<a-input class="captcha-input" v-model:value.trim="loginForm.captchaCode" placeholder="请输入验证码" />
|
||||
@@ -84,117 +93,124 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { loginApi } from '/@/api/system/login/login-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
||||
import { useUserStore } from '/@/store/modules/system/user';
|
||||
import { saveTokenToCookie } from '/@/utils/cookie-util';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { loginApi } from '/@/api/system/login-api';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
||||
import { useUserStore } from '/@/store/modules/system/user';
|
||||
import { saveTokenToCookie } from '/@/utils/cookie-util';
|
||||
|
||||
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg';
|
||||
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
|
||||
import loginQR from '/@/assets/images/login/login-qr.png';
|
||||
import xiaozhen from '/@/assets/images/1024lab/xiaozhen-gzh.jpg';
|
||||
import gongzhonghao from '/@/assets/images/1024lab/1024lab-gzh.jpg';
|
||||
import zhuoda from '/@/assets/images/1024lab/zhuoda-wechat.jpg';
|
||||
import loginQR from '/@/assets/images/login/login-qr.png';
|
||||
import gzh from '/@/assets/images/1024lab/gzh.jpg';
|
||||
|
||||
import aliLogin from '/@/assets/images/login/ali-icon.png';
|
||||
import googleLogin from '/@/assets/images/login/google-icon.png';
|
||||
import qqLogin from '/@/assets/images/login/qq-icon.png';
|
||||
import weiboLogin from '/@/assets/images/login/weibo-icon.png';
|
||||
import aliLogin from '/@/assets/images/login/ali-icon.png';
|
||||
import googleLogin from '/@/assets/images/login/google-icon.png';
|
||||
import qqLogin from '/@/assets/images/login/qq-icon.png';
|
||||
import weiboLogin from '/@/assets/images/login/weibo-icon.png';
|
||||
|
||||
import { buildRoutes } from '/@/router/index';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { buildRoutes } from '/@/router/index';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { encryptData } from '/@/lib/encrypt';
|
||||
|
||||
//--------------------- 登录表单 ---------------------------------
|
||||
//--------------------- 登录表单 ---------------------------------
|
||||
|
||||
const loginForm = reactive({
|
||||
loginName: 'admin',
|
||||
password: '',
|
||||
captchaCode: '',
|
||||
captchaUuid: '',
|
||||
loginDevice: LOGIN_DEVICE_ENUM.PC.value,
|
||||
});
|
||||
const rules = {
|
||||
loginName: [{ required: true, message: '用户名不能为空' }],
|
||||
password: [{ required: true, message: '密码不能为空' }],
|
||||
captchaCode: [{ required: true, message: '验证码不能为空' }],
|
||||
};
|
||||
|
||||
const showPassword = ref(false);
|
||||
const router = useRouter();
|
||||
const formRef = ref();
|
||||
const rememberPwd = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
document.onkeyup = (e) => {
|
||||
if (e.keyCode == 13) {
|
||||
onLogin();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.onkeyup = null;
|
||||
});
|
||||
|
||||
//登录
|
||||
async function onLogin() {
|
||||
formRef.value.validate().then(async () => {
|
||||
try {
|
||||
SmartLoading.show();
|
||||
const res = await loginApi.login(loginForm);
|
||||
stopRefrestCaptchaInterval();
|
||||
saveTokenToCookie(res.data.token ? res.data.token : '');
|
||||
message.success('登录成功');
|
||||
//更新用户信息到pinia
|
||||
useUserStore().setUserLoginInfo(res.data);
|
||||
//构建系统的路由
|
||||
buildRoutes();
|
||||
router.push('/home');
|
||||
} catch (e) {
|
||||
if (e.data && e.data.code === 30001) {
|
||||
loginForm.captchaCode = '';
|
||||
getCaptcha();
|
||||
}
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
const loginForm = reactive({
|
||||
loginName: 'admin',
|
||||
password: '',
|
||||
captchaCode: '',
|
||||
captchaUuid: '',
|
||||
loginDevice: LOGIN_DEVICE_ENUM.PC.value,
|
||||
});
|
||||
}
|
||||
const rules = {
|
||||
loginName: [{ required: true, message: '用户名不能为空' }],
|
||||
password: [{ required: true, message: '密码不能为空' }],
|
||||
captchaCode: [{ required: true, message: '验证码不能为空' }],
|
||||
};
|
||||
|
||||
//--------------------- 验证码 ---------------------------------
|
||||
const showPassword = ref(false);
|
||||
const router = useRouter();
|
||||
const formRef = ref();
|
||||
const rememberPwd = ref(false);
|
||||
|
||||
const captchaBase64Image = ref('');
|
||||
async function getCaptcha() {
|
||||
try {
|
||||
let captchaResult = await loginApi.getCaptcha();
|
||||
captchaBase64Image.value = captchaResult.data.captchaBase64Image;
|
||||
loginForm.captchaUuid = captchaResult.data.captchaUuid;
|
||||
beginRefrestCaptchaInterval(captchaResult.data.expireSeconds);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
onMounted(() => {
|
||||
document.onkeyup = (e) => {
|
||||
if (e.keyCode == 13) {
|
||||
onLogin();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.onkeyup = null;
|
||||
});
|
||||
|
||||
//登录
|
||||
async function onLogin() {
|
||||
formRef.value.validate().then(async () => {
|
||||
try {
|
||||
SmartLoading.show();
|
||||
// 密码加密
|
||||
let encryptPasswordForm = Object.assign({}, loginForm, {
|
||||
password: encryptData(loginForm.password),
|
||||
});
|
||||
const res = await loginApi.login(encryptPasswordForm);
|
||||
stopRefrestCaptchaInterval();
|
||||
saveTokenToCookie(res.data.token ? res.data.token : '');
|
||||
message.success('登录成功');
|
||||
//更新用户信息到pinia
|
||||
useUserStore().setUserLoginInfo(res.data);
|
||||
//构建系统的路由
|
||||
buildRoutes();
|
||||
router.push('/home');
|
||||
} catch (e) {
|
||||
if (e.data && e.data.code !== 0) {
|
||||
loginForm.captchaCode = '';
|
||||
getCaptcha();
|
||||
}
|
||||
smartSentry.captureError(e);
|
||||
} finally {
|
||||
SmartLoading.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let refrestCaptchaInterval = null;
|
||||
function beginRefrestCaptchaInterval(expireSeconds) {
|
||||
if (refrestCaptchaInterval === null) {
|
||||
refrestCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
|
||||
//--------------------- 验证码 ---------------------------------
|
||||
|
||||
const captchaBase64Image = ref('');
|
||||
async function getCaptcha() {
|
||||
try {
|
||||
let captchaResult = await loginApi.getCaptcha();
|
||||
captchaBase64Image.value = captchaResult.data.captchaBase64Image;
|
||||
loginForm.captchaUuid = captchaResult.data.captchaUuid;
|
||||
beginRefrestCaptchaInterval(captchaResult.data.expireSeconds);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stopRefrestCaptchaInterval() {
|
||||
if (refrestCaptchaInterval != null) {
|
||||
clearInterval(refrestCaptchaInterval);
|
||||
refrestCaptchaInterval = null;
|
||||
let refrestCaptchaInterval = null;
|
||||
function beginRefrestCaptchaInterval(expireSeconds) {
|
||||
if (refrestCaptchaInterval === null) {
|
||||
refrestCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(getCaptcha);
|
||||
function stopRefrestCaptchaInterval() {
|
||||
if (refrestCaptchaInterval != null) {
|
||||
clearInterval(refrestCaptchaInterval);
|
||||
refrestCaptchaInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(getCaptcha);
|
||||
</script>
|
||||
<style lang="less" scoped>@import './login.less';</style>
|
||||
<style lang="less" scoped>
|
||||
@import './login.less';
|
||||
</style>
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
:maskClosable="true"
|
||||
:title="form.menuId ? '编辑' : '添加'"
|
||||
:visible="visible"
|
||||
:width="550"
|
||||
:open="visible"
|
||||
:width="600"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form ref="formRef" :labelCol="{ span: labelColSpan }" :labelWrap="true" :model="form" :rules="rules">
|
||||
@@ -28,7 +28,7 @@
|
||||
<MenuTreeSelect ref="parentMenuTreeSelect" v-model:value="form.parentId" />
|
||||
</a-form-item>
|
||||
<!-- 目录 菜单 start -->
|
||||
<template v-if="form.menuType == MENU_TYPE_ENUM.CATALOG.value || form.menuType == MENU_TYPE_ENUM.MENU.value">
|
||||
<template v-if="form.menuType === MENU_TYPE_ENUM.CATALOG.value || form.menuType === MENU_TYPE_ENUM.MENU.value">
|
||||
<a-form-item label="菜单名称" name="menuName">
|
||||
<a-input v-model:value="form.menuName" placeholder="请输入菜单名称" />
|
||||
</a-form-item>
|
||||
@@ -40,14 +40,10 @@
|
||||
</template>
|
||||
</IconSelect>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="路由地址" name="path">
|
||||
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="路由地址" name="path">
|
||||
<a-input v-model:value="form.path" placeholder="请输入路由地址" />
|
||||
</a-form-item>
|
||||
<a-form-item label="排序" name="sort">
|
||||
<a-input-number v-model:value="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||
<h6 style="color: #ababab">值越小越靠前</h6>
|
||||
</a-form-item>
|
||||
<template v-if="form.menuType == MENU_TYPE_ENUM.MENU.value">
|
||||
<template v-if="form.menuType === MENU_TYPE_ENUM.MENU.value">
|
||||
<a-form-item v-if="form.frameFlag" label="外链地址" name="frameUrl">
|
||||
<a-input v-model:value="form.frameUrl" placeholder="请输入外链地址" />
|
||||
</a-form-item>
|
||||
@@ -55,11 +51,10 @@
|
||||
<a-input v-model:value="form.component" placeholder="请输入组件地址 默认带有开头/@/views" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="是否缓存" name="cacheFlag">
|
||||
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="是否缓存" name="cacheFlag">
|
||||
<a-switch v-model:checked="form.cacheFlag" checked-children="开启缓存" un-checked-children="不缓存" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.menuType == MENU_TYPE_ENUM.MENU.value" label="是否外链" name="frameFlag">
|
||||
<a-form-item v-if="form.menuType === MENU_TYPE_ENUM.MENU.value" label="是否外链" name="frameFlag">
|
||||
<a-switch v-model:checked="form.frameFlag" checked-children="是外链" un-checked-children="不是外链" />
|
||||
</a-form-item>
|
||||
<a-form-item label="显示状态" name="frameFlag">
|
||||
@@ -71,7 +66,7 @@
|
||||
</template>
|
||||
<!-- 目录 菜单 end -->
|
||||
<!-- 按钮 start -->
|
||||
<template v-if="form.menuType == MENU_TYPE_ENUM.POINTS.value">
|
||||
<template v-if="form.menuType === MENU_TYPE_ENUM.POINTS.value">
|
||||
<a-form-item label="功能点名称" name="menuName">
|
||||
<a-input v-model:value="form.menuName" placeholder="请输入功能点名称" />
|
||||
</a-form-item>
|
||||
@@ -82,22 +77,24 @@
|
||||
<a-switch v-model:checked="form.disabledFlag" checked-children="启用" un-checked-children="禁用" />
|
||||
</a-form-item>
|
||||
<a-form-item label="权限类型" name="permsType">
|
||||
<a-radio-group v-model:value="form.permsType" >
|
||||
<a-radio-group v-model:value="form.permsType">
|
||||
<a-radio v-for="item in MENU_PERMS_TYPE_ENUM" :key="item.value" :value="item.value">
|
||||
{{ item.desc }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item :label="form.permsType === MENU_PERMS_TYPE_ENUM.SPRING_SECURITY.value ? '权限字符' : '前端权限字符'" name="webPerms">
|
||||
<a-input v-model:value="form.webPerms" placeholder="请输入权限字符" />
|
||||
<a-form-item label="前端权限" name="webPerms" help="用于前端按钮等功能的展示和隐藏,搭配v-privilege使用">
|
||||
<a-input v-model:value="form.webPerms" placeholder="请输入前端权限" />
|
||||
</a-form-item>
|
||||
<a-form-item label="权限URL" name="apiPermsList" v-if="form.permsType === MENU_PERMS_TYPE_ENUM.URL.value">
|
||||
<a-select v-model:value="form.apiPermsList" mode="multiple" placeholder="请选择接口权限" style="width: 100%">
|
||||
<a-select-option v-for="item in allUrlData" :key="item.name">{{ item.url }} </a-select-option>
|
||||
</a-select>
|
||||
<a-form-item label="后端权限" name="apiPerms" help="后端@SaCheckPermission中的权限字符串,多个以英文逗号,分割">
|
||||
<a-input v-model:value="form.apiPerms" placeholder="请输入后端权限" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<!-- 按钮 end -->
|
||||
<a-form-item label="排序" name="sort">
|
||||
<a-input-number v-model:value="form.sort" :min="0" placeholder="请输入排序" style="width: 100px" />
|
||||
<h6 style="color: #ababab">值越小越靠前</h6>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="footer">
|
||||
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
|
||||
@@ -109,11 +106,11 @@
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import _ from 'lodash';
|
||||
import { computed, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { computed, nextTick, reactive, ref } from 'vue';
|
||||
import MenuTreeSelect from './menu-tree-select.vue';
|
||||
import { menuApi } from '/@/api/system/menu/menu-api';
|
||||
import { menuApi } from '/@/api/system/menu-api';
|
||||
import IconSelect from '/@/components/framework/icon-select/index.vue';
|
||||
import { MENU_DEFAULT_PARENT_ID, MENU_TYPE_ENUM, MENU_PERMS_TYPE_ENUM } from '/@/constants/system/menu-const';
|
||||
import { MENU_DEFAULT_PARENT_ID, MENU_PERMS_TYPE_ENUM, MENU_TYPE_ENUM } from '/@/constants/system/menu-const';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
|
||||
@@ -127,18 +124,12 @@
|
||||
const visible = ref(false);
|
||||
|
||||
const labelColSpan = computed(() => {
|
||||
if (form.menuType == MENU_TYPE_ENUM.POINTS.value) {
|
||||
if (form.menuType === MENU_TYPE_ENUM.POINTS.value) {
|
||||
return 6;
|
||||
}
|
||||
return 4;
|
||||
});
|
||||
|
||||
watch(visible, (e) => {
|
||||
if (e) {
|
||||
getAuthUrl();
|
||||
}
|
||||
});
|
||||
|
||||
const contextMenuTreeSelect = ref();
|
||||
const parentMenuTreeSelect = ref();
|
||||
|
||||
@@ -173,16 +164,6 @@
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
// ----------------------- 预加载数据 ------------------------
|
||||
|
||||
let allUrlData = ref([]);
|
||||
|
||||
// url数据
|
||||
async function getAuthUrl() {
|
||||
let res = await menuApi.getAuthUrl();
|
||||
allUrlData.value = res.data;
|
||||
}
|
||||
|
||||
// ----------------------- form表单相关操作 ------------------------
|
||||
|
||||
const formRef = ref();
|
||||
@@ -193,12 +174,12 @@
|
||||
icon: undefined,
|
||||
parentId: undefined,
|
||||
path: undefined,
|
||||
permsType: MENU_PERMS_TYPE_ENUM.SPRING_SECURITY.value,
|
||||
permsType: MENU_PERMS_TYPE_ENUM.SA_TOKEN.value,
|
||||
webPerms: undefined,
|
||||
apiPermsList: undefined,
|
||||
apiPerms: undefined,
|
||||
sort: undefined,
|
||||
visibleFlag: true,
|
||||
cacheFlag: false,
|
||||
cacheFlag: true,
|
||||
component: undefined,
|
||||
contextMenuId: undefined,
|
||||
disabledFlag: false,
|
||||
@@ -237,7 +218,6 @@
|
||||
{ required: true, message: '路由地址不能为空' },
|
||||
{ max: 100, message: '路由地址不能大于100个字符', trigger: 'blur' },
|
||||
],
|
||||
webPerms: [{ required: true, message: '前端权限字符不能为空' }],
|
||||
};
|
||||
|
||||
function validateForm(formRef) {
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
/>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { menuApi } from '/@/api/system/menu/menu-api';
|
||||
import _ from 'lodash';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { menuApi } from '/@/api/system/menu-api';
|
||||
|
||||
const props = defineProps({
|
||||
value: Number,
|
||||
|
||||
@@ -35,11 +35,6 @@ export const columns = ref([
|
||||
dataIndex: 'component',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '权限模式',
|
||||
dataIndex: 'permsType',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '后端权限',
|
||||
dataIndex: 'apiPerms',
|
||||
@@ -50,26 +45,6 @@ export const columns = ref([
|
||||
dataIndex: 'webPerms',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '外链',
|
||||
dataIndex: 'frameFlag',
|
||||
width: 45,
|
||||
},
|
||||
{
|
||||
title: '缓存',
|
||||
dataIndex: 'cacheFlag',
|
||||
width: 45,
|
||||
},
|
||||
{
|
||||
title: '显示',
|
||||
dataIndex: 'visibleFlag',
|
||||
width: 45,
|
||||
},
|
||||
{
|
||||
title: '禁用',
|
||||
dataIndex: 'disabledFlag',
|
||||
width: 45,
|
||||
},
|
||||
{
|
||||
title: '顺序',
|
||||
dataIndex: 'sort',
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
查询
|
||||
</a-button>
|
||||
|
||||
<a-button @click="resetQuery">
|
||||
<a-button @click="resetQuery" class="smart-margin-left10">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
@@ -71,7 +71,7 @@
|
||||
添加菜单
|
||||
</a-button>
|
||||
|
||||
<a-button v-privilege="'system:menu:batch:delete'" type="primary" danger size="small" @click="batchDelete" :disabled="!hasSelected">
|
||||
<a-button v-privilege="'system:menu:batchDelete'" type="primary" danger size="small" @click="batchDelete" :disabled="!hasSelected">
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
@@ -79,7 +79,7 @@
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="smart-table-setting-block">
|
||||
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.SYSTEM.MENU" :refresh="query" />
|
||||
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.SYSTEM.MENU" :refresh="query" />
|
||||
</div>
|
||||
</a-row>
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
<template v-if="column.dataIndex === 'operate'">
|
||||
<div class="smart-table-operate">
|
||||
<a-button v-privilege="'system:menu:update'" type="link" size="small" @click="showDrawer(record)">编辑</a-button>
|
||||
<a-button v-privilege="'system:menu:delete'" danger type="link" @click="singleDelete(record)">删除</a-button>
|
||||
<a-button v-privilege="'system:menu:batchDelete'" danger type="link" @click="singleDelete(record)">删除</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
@@ -148,7 +148,7 @@
|
||||
import MenuOperateModal from './components/menu-operate-modal.vue';
|
||||
import { buildMenuTableTree, filterMenuByQueryForm } from './menu-data-handler';
|
||||
import { columns } from './menu-list-table-columns';
|
||||
import { menuApi } from '/@/api/system/menu/menu-api';
|
||||
import { menuApi } from '/@/api/system/menu-api';
|
||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||
import { smartSentry } from '/@/lib/smart-sentry';
|
||||
|
||||
Reference in New Issue
Block a user