This commit is contained in:
zhuoda
2024-01-08 19:52:39 +08:00
parent 8dc663d885
commit 192e959d14
1126 changed files with 13783 additions and 68273 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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;

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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: {

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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;
}
// ----------------------- 以下是暴露的方法内容 ------------------------

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>
简介接口加解密分为 前端请求参数加解密 后端返回结果加解密
- 支持国密SMAES加密算法前端修改:/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>

View File

@@ -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';

View File

@@ -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';

View File

@@ -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();

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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',
};
//表单

View File

@@ -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);
}
//初始化拖拽

View File

@@ -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>

View File

@@ -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';

View File

@@ -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';

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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';

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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';

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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({
// 绑定值

View File

@@ -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;

View File

@@ -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;
}
// ----------------------- 以下是暴露的方法内容 ------------------------

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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>

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;

View File

@@ -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';

View File

@@ -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';

View File

@@ -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,

View File

@@ -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';

View File

@@ -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';
//------------------------ 表格渲染 ---------------------

View File

@@ -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';

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,

View File

@@ -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';

View File

@@ -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;

View File

@@ -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 ---------------------

View File

@@ -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';

View File

@@ -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;

View File

@@ -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>

View File

@@ -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({

View File

@@ -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;

View File

@@ -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: '请输入角色编码' }],
};
// 提交表单

View File

@@ -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';

View File

@@ -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';

View File

@@ -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();

View File

@@ -37,7 +37,7 @@
default: 0,
},
});
defineEmits('update:value');
defineEmits(['update:value']);
let roleStore = useRoleStore();
function selectCheckbox(module) {
if (!module.menuId) {

View File

@@ -28,6 +28,6 @@
default: 0,
},
});
let emits = defineEmits('selectCheckbox');
let emits = defineEmits(['selectCheckbox']);
</script>
<style scoped lang="less"></style>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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>

View File

@@ -0,0 +1,12 @@
export default [
'每个人的一生好比一根蜡烛,看似不经意间散发的光和热,都可能照亮和温暖他人。这是生活赋予我们的智慧,也让我们在寻常的日子成为一个温暖善良的人。',
'立规矩的目的,不是禁锢、限制,而是教育;孩子犯了错,父母不能帮孩子逃避,而应该让孩子学会承担责任。让孩子有面对错误的诚实和勇气,这才是立规矩的意义所在。',
'人这一辈子,格局大了、善良有了,成功自然也就近了。格局越大,人生越宽。你的人生会是什么样,与你在为人处世时的表现有很大关系。世间美好都是环环相扣的,善良的人总不会被亏待。',
'平日里的千锤百炼,才能托举出光彩时刻;逆境中的亮剑、失败后的奋起,才能让梦想成真。哪有什么一战成名,其实都是百炼成钢。“天才”都是汗水浇灌出来的,天赋或许可以决定起点,但唯有坚持和努力才能达到终点。',
'家,不在于奢华,而在于温馨;家,不在于大小,而在于珍惜。在家里,有父母的呵护,有爱人的陪伴,有子女的欢笑。一家人整整齐齐、和和睦睦,就是人生最大的幸福!',
'每一个不向命运低头、努力生活的人,都值得被尊重。',
'青年的肩上,从不只有清风明月,更有责任担当。岁月因青春慨然以赴而更加美好,世间因少年挺身向前而更加瑰丽。请相信,不会有人永远年轻,但永远有人年轻。',
'人生路上,总有人走得比你快,但不必介意,也不必着急。一味羡慕别人的成绩,只会给自己平添压力、徒增烦恼。不盲从别人的脚步,坚定目标,才能找到自己的节奏,进而逢山开路、遇水搭桥。',
'如果你真的在乎一个人,首先要学会的就是感恩对方的好。这样,对方才会在和你的相处中找到价值感,相处起来也会更加舒适愉悦。',
'一个人只有心里装得下别人,有换位思考的品质,有为他人谋幸福的信念,才能真正做到慷慨施予。同样,也只有赠人玫瑰而无所求时,你才会手有余香、真有所得。',
];

View File

@@ -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>

View File

@@ -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>

View File

@@ -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%;
}

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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',

View File

@@ -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';