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>