新版发布,支持低代码模块: online表单、online报表
parent
8e93c1f943
commit
870892c346
|
@ -29,3 +29,5 @@ pnpm-debug.log*
|
|||
*.sln
|
||||
*.sw?
|
||||
/os_del.cmd
|
||||
/.vscode/
|
||||
/.history/
|
||||
|
|
|
@ -259,3 +259,15 @@ INSERT INTO `sys_permission` VALUES ('d7d6e2e4e2934f2c9385a623fd98c6f3', '', '
|
|||
delete from sys_permission where id = '1449995470942593026';
|
||||
|
||||
-- 角色授权vue3的菜单
|
||||
|
||||
|
||||
-- online低代码菜单(online表单、online报表)
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1455100420297859074', '', '在线开发', '/online', 'layouts/default/index', 1, NULL, '/online/cgform', 0, NULL, '0', 2.00, 0, 'ant-design:cloud-outlined', 0, 0, 0, 0, NULL, 'admin', '2021-11-01 17:12:29', 'admin', '2022-05-11 16:38:26', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1455101470794850305', '1455100420297859074', 'Online表单开发', '/online/cgform', 'super/online/cgform/index', 1, NULL, NULL, 1, NULL, '0', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2021-11-01 17:16:40', 'admin', '2022-04-04 18:36:25', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1457678003102879745', '1455100420297859074', '系统编码规则', '/system/fillrule', 'system/fillRule/index', 1, NULL, NULL, 1, NULL, '0', 9.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2021-11-08 19:54:53', 'admin', '2021-11-18 10:49:40', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1458353686530232321', '1455100420297859074', '系统校验规则', '/system/checkrule', 'system/checkRule/index', 1, NULL, NULL, 1, NULL, '0', 15.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2021-11-10 16:39:48', 'admin', '2021-11-18 10:49:48', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1460888189937176577', '1455100420297859074', 'Online报表配置', '/online/cgreport', 'super/online/cgreport/index', 1, NULL, NULL, 1, NULL, '0', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '2021-11-17 16:31:01', 'admin', '2021-12-08 10:55:32', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1461270075543347202', '1455100420297859074', 'Online表单视图', '/online/copyform/:code', 'super/online/cgform/CgformCopyList', 1, NULL, NULL, 1, NULL, '0', 99.00, 0, NULL, 1, 0, 1, 0, NULL, 'admin', '2021-11-18 17:48:30', NULL, NULL, 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1461291438825558017', '1455100420297859074', 'AUTO在线报表', '/online/cgreport/:id', 'super/online/cgreport/auto/OnlCgReportList', 1, NULL, NULL, 1, NULL, '0', 2.00, 0, NULL, 1, 0, 1, 0, NULL, 'admin', '2021-11-18 19:13:23', 'admin', '2021-11-19 20:16:13', 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1465686870713782273', '1455100420297859074', 'AUTO在线表单', '/online/cgformList/:id', 'super/online/cgform/auto/default/OnlineAutoList', 1, NULL, NULL, 1, NULL, '0', 5.00, 0, NULL, 1, 0, 1, 0, NULL, 'admin', '2021-11-30 22:19:16', NULL, NULL, 0, 0, NULL, 0);
|
||||
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES ('1509417558230999041', '1455100420297859074', 'AUTO树表单列表', '/online/cgformTreeList/:id', 'super/online/cgform/auto/tree/OnlineAutoTreeList', 1, NULL, NULL, 1, NULL, '0', 5.00, 0, NULL, 1, 0, 1, 0, NULL, 'admin', '2022-03-31 14:29:24', NULL, NULL, 0, 0, NULL, 0);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"bootstrap": "yarn install",
|
||||
"serve": "npm run dev",
|
||||
"dev": "vite",
|
||||
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 vite build && esno ./build/script/postBuild.ts",
|
||||
"build:test": "cross-env vite build --mode test && esno ./build/script/postBuild.ts",
|
||||
"build:no-cache": "yarn clean:cache && npm run build",
|
||||
|
@ -18,7 +19,6 @@
|
|||
"preview": "npm run build && vite preview",
|
||||
"preview:dist": "vite preview",
|
||||
"log": "conventional-changelog -p angular -i CHANGELOG.md -s",
|
||||
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
|
||||
"clean:lib": "rimraf node_modules",
|
||||
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
|
||||
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
|
@ -34,6 +34,7 @@
|
|||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jeecg/online": "1.0.1",
|
||||
"@iconify/iconify": "^2.0.4",
|
||||
"@fullcalendar/core": "^5.10.1",
|
||||
"@fullcalendar/daygrid": "^5.10.1",
|
||||
|
@ -191,6 +192,7 @@
|
|||
"@fullcalendar/interaction",
|
||||
"@fullcalendar/timegrid",
|
||||
"@fullcalendar/vue3",
|
||||
"@jeecg/online",
|
||||
"@vueuse/core",
|
||||
"@vueuse/shared",
|
||||
"@zxcvbn-ts/core",
|
||||
|
|
|
@ -58,6 +58,7 @@ import JSearchSelect from './jeecg/components/JSearchSelect.vue'
|
|||
import JAddInput from './jeecg/components/JAddInput.vue'
|
||||
import {Time} from '/@/components/Time';
|
||||
import JOnlineSelectCascade from './jeecg/components/JOnlineSelectCascade.vue'
|
||||
import JRangeNumber from './jeecg/components/JRangeNumber.vue'
|
||||
|
||||
const componentMap = new Map<ComponentType, Component>();
|
||||
|
||||
|
@ -125,6 +126,7 @@ componentMap.set('JUpload', JUpload);
|
|||
componentMap.set('JSearchSelect', JSearchSelect);
|
||||
componentMap.set('JAddInput', JAddInput);
|
||||
componentMap.set('JOnlineSelectCascade', JOnlineSelectCascade)
|
||||
componentMap.set('JRangeNumber', JRangeNumber)
|
||||
|
||||
export function add(compName: ComponentType, component: Component) {
|
||||
componentMap.set(compName, component);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<a-input-group>
|
||||
<a-input :value="beginValue" style="width: calc( 50% - 15px )" placeholder="请输入最小值" @change="handleChangeBegin"/>
|
||||
<a-input style="width: 30px; border-left: 0; pointer-events: none; background-color: #fff" placeholder="~" disabled/>
|
||||
<a-input :value="endValue" style="width: calc( 50% - 15px );border-left: 0" placeholder="请输入最大值" @change="handleChangeEnd"/>
|
||||
</a-input-group>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
/**
|
||||
* 查询条件用-数值范围查询
|
||||
*/
|
||||
import {ref, watch} from 'vue'
|
||||
export default {
|
||||
name: "JRangeNumber",
|
||||
props:{
|
||||
value: {
|
||||
type: Array,
|
||||
default: ['','']
|
||||
}
|
||||
},
|
||||
emits: ['change'],
|
||||
setup(props, {emit}){
|
||||
const beginValue = ref('')
|
||||
const endValue = ref('')
|
||||
|
||||
function handleChangeBegin(e) {
|
||||
beginValue.value = e.target.value
|
||||
emitArray()
|
||||
}
|
||||
|
||||
function handleChangeEnd(e) {
|
||||
endValue.value = e.target.value
|
||||
emitArray()
|
||||
}
|
||||
|
||||
function emitArray(){
|
||||
let arr = []
|
||||
let begin = beginValue.value || ''
|
||||
let end = endValue.value || ''
|
||||
arr.push(begin)
|
||||
arr.push(end)
|
||||
emit('change', arr)
|
||||
}
|
||||
|
||||
watch(()=>props.value, (val)=>{
|
||||
if(val.length==2){
|
||||
beginValue.value = val[0]
|
||||
endValue.value = val[1]
|
||||
}else{
|
||||
beginValue.value = ''
|
||||
endValue.value = ''
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
beginValue,
|
||||
endValue,
|
||||
handleChangeBegin,
|
||||
handleChangeEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -142,4 +142,5 @@ export type ComponentType =
|
|||
| 'JAddInput'
|
||||
| 'Time'
|
||||
| 'JOnlineSelectCascade'
|
||||
| 'JRangeNumber'
|
||||
;
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="jeecg-basic-table-form-container" v-if="showSearchFlag">
|
||||
<a-form ref="formRef" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol" @keyup.enter.native="searchQuery">
|
||||
<a-row :gutter="24">
|
||||
<template v-for="(item,index) in queryInfo">
|
||||
<template v-if=" item.hidden==='1' ">
|
||||
<a-col :md="8" :sm="24" :key=" 'query'+index " v-show="toggleSearchStatus">
|
||||
<SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
|
||||
</a-col>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-col :md="8" :sm="24" :key=" 'query'+index ">
|
||||
<SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
|
||||
</a-col>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<a-col :md="8" :sm="8">
|
||||
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
|
||||
<a-col :lg="6">
|
||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset">重置</a-button>
|
||||
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery" style="margin-left: 8px">查询</a-button>
|
||||
<a @click="handleToggleSearch" style="margin-left: 8px">
|
||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'"/>
|
||||
</a>
|
||||
</a-col>
|
||||
</span>
|
||||
</a-col>
|
||||
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:canResize="true"
|
||||
:bordered="true"
|
||||
:loading="loading"
|
||||
:rowKey="combineRowKey"
|
||||
:columns="columns"
|
||||
:showIndexColumn="false"
|
||||
:dataSource="dataSource"
|
||||
:pagination="pagination"
|
||||
:rowSelection="rowSelection"
|
||||
@row-click="clickThenCheck"
|
||||
@change="handleChangeInTable"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<!-- 跳转Href的动态组件方式 -->
|
||||
<a-modal v-bind="hrefComponent.model" v-on="hrefComponent.on">
|
||||
<component :is="hrefComponent.is" v-bind="hrefComponent.params"/>
|
||||
</a-modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, unref, ref, watch, watchEffect, reactive, computed } from 'vue';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { usePopBiz } from '/@/components/jeecg/OnLine/hooks/usePopBiz';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JPopupOnlReport',
|
||||
components: {
|
||||
SearchFormItem: createAsyncComponent(() => import('/@/components/jeecg/OnLine/SearchFormItem.vue'), { loading: true }),
|
||||
BasicTable: createAsyncComponent(() => import('/@/components/Table/src/BasicTable.vue'), { loading: true }),
|
||||
},
|
||||
props: ['multi', 'code','id', 'sorter', 'groupId', 'param', 'clickToRowSelect'],
|
||||
emits: ['ok', 'register'],
|
||||
setup(props, { emit, refs }) {
|
||||
const { createMessage } = useMessage();
|
||||
const labelCol = reactive({
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
});
|
||||
const wrapperCol = reactive({
|
||||
xs: { span: 24 },
|
||||
sm: { span: 18 },
|
||||
});
|
||||
const formRef = ref();
|
||||
const tableRef = ref();
|
||||
const toggleSearchStatus = ref(false);
|
||||
const attrs = useAttrs();
|
||||
const tableScroll = ref({ x: true });
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
const [{ visibleChange, loadColumnsInfo, dynamicParamHandler, loadData,loadColumnsAndData, handleChangeInTable, combineRowKey, clickThenCheck, filterUnuseSelect, handleExport },
|
||||
{ hrefComponent,visible, rowSelection, checkedKeys, selectRows, pagination, dataSource, columns, loading, title, iSorter, queryInfo, queryParam, dictOptions }] = usePopBiz(getBindValue);
|
||||
|
||||
const showSearchFlag = computed(() => unref(queryInfo) && unref(queryInfo).length > 0);
|
||||
/**
|
||||
*监听code
|
||||
*/
|
||||
watch(
|
||||
() => props.code,
|
||||
() => {
|
||||
loadColumnsAndData();
|
||||
},
|
||||
{immediate: true}
|
||||
);
|
||||
/**
|
||||
*监听popup动态参数 支持系统变量语法
|
||||
*/
|
||||
watch(
|
||||
() => props.param,
|
||||
() => {
|
||||
if (visible) {
|
||||
dynamicParamHandler();
|
||||
//loadData();
|
||||
}
|
||||
},
|
||||
);
|
||||
/**
|
||||
*监听sorter排序字段
|
||||
*/
|
||||
watchEffect(() => {
|
||||
if (props.sorter) {
|
||||
let arr = props.sorter.split('=');
|
||||
if (arr.length === 2 && ['asc', 'desc'].includes(arr[1].toLowerCase())) {
|
||||
iSorter.value = { column: arr[0], order: arr[1].toLowerCase() };
|
||||
// 排序字段受控
|
||||
unref(columns).forEach(col => {
|
||||
if (col.dataIndex === unref(iSorter).column) {
|
||||
col['sortOrder'] = unref(iSorter).order === 'asc' ? 'ascend' : 'descend';
|
||||
} else {
|
||||
col['sortOrder'] = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('【JPopup】sorter参数不合法');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleToggleSearch() {
|
||||
toggleSearchStatus.value = !unref(toggleSearchStatus);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*/
|
||||
function onExportXls() {
|
||||
handleExport!()
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
*/
|
||||
function searchQuery() {
|
||||
loadData(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置
|
||||
*/
|
||||
function searchReset() {
|
||||
queryParam.value = {};
|
||||
loadData(1);
|
||||
}
|
||||
|
||||
return {
|
||||
attrs,
|
||||
|
||||
tableScroll,
|
||||
dataSource,
|
||||
pagination,
|
||||
columns,
|
||||
rowSelection,
|
||||
checkedKeys,
|
||||
loading,
|
||||
title,
|
||||
hrefComponent,
|
||||
|
||||
clickThenCheck,
|
||||
loadData,
|
||||
combineRowKey,
|
||||
handleChangeInTable,
|
||||
visibleChange,
|
||||
queryInfo,
|
||||
queryParam,
|
||||
tableRef,
|
||||
formRef,
|
||||
labelCol,
|
||||
wrapperCol,
|
||||
dictOptions,
|
||||
showSearchFlag,
|
||||
toggleSearchStatus,
|
||||
handleToggleSearch,
|
||||
searchQuery,
|
||||
searchReset,
|
||||
onExportXls
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.jeecg-basic-table-form-container {
|
||||
padding: 0px;
|
||||
|
||||
.table-page-search-submitButtons {
|
||||
display: block;
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
:deep .jeecg-basic-table .ant-table-wrapper .ant-table-title {
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,289 @@
|
|||
<template>
|
||||
<a-form-item v-if="item.view===DateTypeEnum.Date" :labelCol="labelCol" :class="'jeecg-online-search'" >
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<template v-if="single_mode===item.mode">
|
||||
<a-date-picker :showTime="false" valueFormat="YYYY-MM-DD" :placeholder=" '请选择'+item.label " v-model:value="queryParam[item.field]"></a-date-picker>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-date-picker :showTime="false" valueFormat="YYYY-MM-DD" placeholder="开始日期" v-model:value="queryParam[item.field+'_begin']" style="width: calc(50% - 15px);"></a-date-picker>
|
||||
<span class="group-query-strig">~</span>
|
||||
<a-date-picker :showTime="false" valueFormat="YYYY-MM-DD" placeholder="结束日期" v-model:value="queryParam[item.field+'_end']" style="width: calc(50% - 15px);"></a-date-picker>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if="item.view===DateTypeEnum.Datetime" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label :title="item.label">
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<template v-if="single_mode===item.mode">
|
||||
<a-date-picker :placeholder=" '请选择'+item.label " :show-time="true" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam[item.field]"></a-date-picker>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-date-picker placeholder="1选择开始时间" :show-time="true" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam[item.field+'_begin']" style="width: calc(50% - 9px);min-width: 60px;"></a-date-picker>
|
||||
<span class="group-query-strig" style="width: auto;padding: 0 4px;">~</span>
|
||||
<a-date-picker placeholder="2选择结束时间" :show-time="true" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam[item.field+'_end']" style="width: calc(50% - 9px);min-width: 60px;"></a-date-picker>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if="item.view===DateTypeEnum.Time" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<template v-if="single_mode===item.mode">
|
||||
<a-date-picker :placeholder=" '请选择'+item.label " mode="time" valueFormat="HH:mm:ss" v-model:value="queryParam[item.field]"></a-date-picker>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-date-picker placeholder="请选择开始时间" mode="time" valueFormat="HH:mm:ss" v-model:value="queryParam[item.field+'_begin']" style="width: calc(50% - 15px);"></a-date-picker>
|
||||
<span class="group-query-strig">~</span>
|
||||
<a-date-picker placeholder="请选择结束时间" mode="time" valueFormat="HH:mm:ss" v-model:value="queryParam[item.field+'_end']" style="width: calc(50% - 15px);"></a-date-picker>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.List || item.view===CompTypeEnum.Radio || item.view===CompTypeEnum.Switch" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JDictSelectTag
|
||||
v-if="item.config==='1'"
|
||||
:placeholder=" '请选择'+item.label "
|
||||
v-model="queryParam[item.field]"
|
||||
:dictCode="getDictCode(item)">
|
||||
</JDictSelectTag>
|
||||
<a-select v-else :placeholder=" '请选择'+item.label " v-model:value="queryParam[item.field]">
|
||||
<template v-for="(obj,index) in dictOptions[getDictOptionKey(item)]" :key="index" >
|
||||
<a-select-option :value="obj.value"> {{ obj.text }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.SelTree " :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JTreeSelect
|
||||
:placeholder=" '请选择'+item.label "
|
||||
v-model:value="queryParam[item.field]"
|
||||
:dict="item.dict"
|
||||
:pidField="item.pidField"
|
||||
:pidValue="item.pidValue"
|
||||
:hasChildField="item.hasChildField"
|
||||
load-triggle-change>
|
||||
</JTreeSelect>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.CatTree " :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JCategorySelect :pcode="item.pcode" v-model:value="queryParam[item.field]" :placeholder=" '请选择'+item.label "/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.SelSearch" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JDictSelectTag
|
||||
v-if="item.config==='1'"
|
||||
v-model:value="queryParam[item.field]"
|
||||
:placeholder=" '请选择'+item.label "
|
||||
:dict="getDictCode(item)">
|
||||
</JDictSelectTag>
|
||||
<!--TODO 新需要的组件-->
|
||||
<!-- <j-online-search-select
|
||||
v-else
|
||||
:ref="item.field+'_search'"
|
||||
v-model="queryParam[item.field]"
|
||||
:placeholder=" '请选择'+item.label "
|
||||
:sql="getSqlByDictCode(item)">
|
||||
</j-online-search-select>-->
|
||||
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.SelUser" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JSelectUserByDept v-model:value="queryParam[item.field]" :placeholder=" '请选择'+item.label " ></JSelectUserByDept>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view==CompTypeEnum.SelDepart" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JSelectDept v-model:value="queryParam[item.field]" :placeholder=" '请选择'+item.label "/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.Popup" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JPopup
|
||||
:placeholder=" '请选择'+item.label "
|
||||
v-model:value="queryParam[item.field]"
|
||||
:formElRef="formElRef"
|
||||
:code="item.dictTable"
|
||||
:field-config="item.dictCode"
|
||||
:multi="true"/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else-if=" item.view=== CompTypeEnum.Pca" :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<JAreaLinkage :placeholder=" '请选择'+item.label " v-model:value="queryParam[item.field]"/>
|
||||
</a-form-item>
|
||||
<!--TODO 缺少的组件-->
|
||||
<a-form-item v-else-if=" item.view===CompTypeEnum.Checkbox || item.view===CompTypeEnum.ListMulti" :labelCol="labelCol" :label="item.label" :class="'jeecg-online-search'">
|
||||
<!-- <j-select-multiple
|
||||
v-if="item.config==='1'"
|
||||
:placeholder=" '请选择'+item.label "
|
||||
v-model="queryParam[item.field]"
|
||||
:dictCode="getDictCode(item)">
|
||||
</j-select-multiple>
|
||||
<j-select-multiple
|
||||
v-else
|
||||
:placeholder=" '请选择'+item.label "
|
||||
:options="dictOptions[item.dbField]"
|
||||
v-model="queryParam[item.field]">
|
||||
</j-select-multiple>-->
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-else :labelCol="labelCol" :class="'jeecg-online-search'">
|
||||
<template #label>
|
||||
<span :title="item.label" class="label-text">{{ item.label }}</span>
|
||||
</template>
|
||||
<template v-if="single_mode===item.mode">
|
||||
<a-input :placeholder=" '请输入'+item.label " v-model:value="queryParam[item.field]"></a-input>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-input :placeholder=" '请输入开始'+item.label " v-model:value="queryParam[item.field+'_begin']" style="width: calc(50% - 15px);"></a-input>
|
||||
<span class="group-query-strig">~</span>
|
||||
<a-input :placeholder=" '请输入结束'+item.label " v-model:value="queryParam[item.field+'_end']" style="width: calc(50% - 15px);"></a-input>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
//import JOnlineSearchSelect from '@/components/online/autoform/comp/JOnlineSearchSelect'
|
||||
import {defineComponent, ref} from 'vue';
|
||||
import {DateTypeEnum} from '/@/enums/DateTypeEnum.ts';
|
||||
import {CompTypeEnum} from '/@/enums/CompTypeEnum.ts';
|
||||
import {
|
||||
JDictSelectTag,
|
||||
JTreeSelect,
|
||||
JCategorySelect,
|
||||
JSelectUserByDept,
|
||||
JSelectDept,
|
||||
JPopup,
|
||||
JAreaLinkage
|
||||
} from '/@/components/Form'
|
||||
export default defineComponent({
|
||||
name: 'JPopupOnlReport',
|
||||
components: {
|
||||
//JOnlineSearchSelect
|
||||
JDictSelectTag,
|
||||
JTreeSelect,
|
||||
JCategorySelect,
|
||||
JSelectUserByDept,
|
||||
JSelectDept,
|
||||
JPopup,
|
||||
JAreaLinkage
|
||||
},
|
||||
props: {
|
||||
formElRef: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
},
|
||||
},
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
},
|
||||
required: true
|
||||
},
|
||||
dictOptions: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
},
|
||||
required: true
|
||||
},
|
||||
queryParam: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
},
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const single_mode = ref("single");
|
||||
console.log("dictOptions===>",props.dictOptions)
|
||||
function getDictCode(item) {
|
||||
if (item.dictTable && item.dictTable.length > 0) {
|
||||
return item.dictTable + ',' + item.dictText + ',' + item.dictCode
|
||||
} else {
|
||||
return item.dictCode
|
||||
}
|
||||
}
|
||||
|
||||
function getSqlByDictCode(item) {
|
||||
let {dictTable, dictCode, dictText} = item;
|
||||
let temp = dictTable.toLowerCase();
|
||||
let arr = temp.split('where');
|
||||
let condition = '';
|
||||
if (arr.length > 1) {
|
||||
condition = ' where' + arr[1]
|
||||
}
|
||||
let sql = "select " + dictCode + " as 'value', " + dictText + " as 'text' from " + arr[0] + condition;
|
||||
console.log('sql', sql);
|
||||
return sql;
|
||||
}
|
||||
|
||||
function getDictOptionKey(item) {
|
||||
if(item.dbField){
|
||||
return item.dbField
|
||||
}else{
|
||||
return item.field
|
||||
}
|
||||
}
|
||||
|
||||
// 定义查询条件 文本label的最大宽度 比起单纯的控制字体个数更好
|
||||
const labelTextMaxWidth = '120px'
|
||||
const labelCol = {
|
||||
style:{
|
||||
'max-width': labelTextMaxWidth
|
||||
}
|
||||
}
|
||||
return {labelTextMaxWidth, labelCol, single_mode,getDictOptionKey,getDictCode, getSqlByDictCode,DateTypeEnum,CompTypeEnum}
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.group-query-strig {
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 查询条件左对齐样式设置 */
|
||||
.jeecg-online-search ::v-deep .ant-form-item-label{
|
||||
flex: 0 0 auto !important;
|
||||
width: auto;
|
||||
}
|
||||
.jeecg-online-search ::v-deep .ant-form-item-control{
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* label显示宽度 超出显示... */
|
||||
.jeecg-online-search ::v-deep .label-text{
|
||||
max-width: v-bind(labelTextMaxWidth);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,746 @@
|
|||
import {reactive, ref, unref, defineAsyncComponent } from "vue";
|
||||
import {httpGroupRequest} from "/@/components/Form/src/utils/GroupRequest";
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
import {filterMultiDictText} from '/@/utils/dict/JDictSelectUtil.js';
|
||||
import {useMessage} from '/@/hooks/web/useMessage';
|
||||
import { OnlineColumn } from '/@/components/jeecg/OnLine/types/onlineConfig'
|
||||
import { h } from 'vue'
|
||||
import { useRouter } from 'vue-router';
|
||||
import {useMethods} from '/@/hooks/system/useMethods';
|
||||
|
||||
export function usePopBiz(props,tableRef?) {
|
||||
|
||||
const {createMessage} = useMessage();
|
||||
//弹窗可视状态
|
||||
const visible = ref(false);
|
||||
//表格加载
|
||||
const loading = ref(false);
|
||||
//cgRpConfigId
|
||||
const cgRpConfigId = ref('');
|
||||
//标题
|
||||
const title = ref('列表');
|
||||
// 排序字段,默认无排序
|
||||
const iSorter = ref<any>('');
|
||||
// 查询对象
|
||||
const queryInfo = ref([]);
|
||||
// 查询参数
|
||||
const queryParam = ref<any>({});
|
||||
// 动态参数
|
||||
const dynamicParam = ref<any>({});
|
||||
//字典配置项
|
||||
const dictOptions = ref({});
|
||||
//数据集
|
||||
const dataSource = ref<Array<object>>([]);
|
||||
//定义表格信息
|
||||
const columns = ref<Array<object>>([]);
|
||||
//定义请求url信息
|
||||
const configUrl = reactive({
|
||||
//列表页加载column和data
|
||||
getColumnsAndData: '/online/cgreport/api/getColumnsAndData/',
|
||||
getColumns: '/online/cgreport/api/getRpColumns/',
|
||||
getData: '/online/cgreport/api/getData/',
|
||||
getQueryInfo: '/online/cgreport/api/getQueryInfo/',
|
||||
export: '/online/cgreport/api/exportXls/'
|
||||
});
|
||||
//已选择的值
|
||||
const checkedKeys = ref<Array<string | number>>([]);
|
||||
//选择的行记录
|
||||
const selectRows = ref<Array<any>>([]);
|
||||
// 点击单元格选中行 popup需要 但是报表预览不需要
|
||||
let clickThenCheckFlag = true
|
||||
if(props.clickToRowSelect===false){
|
||||
clickThenCheckFlag = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择列配置
|
||||
*/
|
||||
const rowSelection = {
|
||||
fixed: true,
|
||||
selectedRowKeys: checkedKeys,
|
||||
selectionRows: selectRows,
|
||||
onChange: onSelectChange
|
||||
}
|
||||
|
||||
/**
|
||||
* 序号列配置
|
||||
*/
|
||||
const indexColumnProps = {
|
||||
dataIndex: 'index',
|
||||
width: '15px',
|
||||
};
|
||||
/**
|
||||
* 分页配置
|
||||
*/
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
// showTotal: (total, range) => {
|
||||
// return range[0] + '-' + range[1] + ' 共' + total + '条'
|
||||
// },
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
total: 0,
|
||||
// 合计逻辑 [待优化 3.0]
|
||||
showTotal: (total) => onShowTotal(total),
|
||||
realPageSize: 10,
|
||||
realTotal: 0,
|
||||
// 是否有合计列,默认为"",在第一次获取到数据之后会设计为ture或者false
|
||||
isTotal: <string | boolean> '',
|
||||
onShowSizeChange: (current, pageSize) => onSizeChange(current, pageSize)
|
||||
});
|
||||
|
||||
/**
|
||||
* 表格选择事件
|
||||
* @param selectedRowKeys
|
||||
* @param selectRow
|
||||
*/
|
||||
function onSelectChange(selectedRowKeys: (string | number)[]) {
|
||||
if (!selectedRowKeys || selectedRowKeys.length == 0) {
|
||||
selectRows.value = []
|
||||
} else {
|
||||
for (let i = 0; i < selectedRowKeys.length; i++) {
|
||||
let combineKey = combineRowKey(getRowByKey(selectedRowKeys[i]));
|
||||
let keys = unref(checkedKeys);
|
||||
if (combineKey && keys.indexOf(combineKey) < 0) {
|
||||
let row = getRowByKey(selectedRowKeys[i]);
|
||||
row && selectRows.value.push(row)
|
||||
}
|
||||
}
|
||||
}
|
||||
checkedKeys.value = selectedRowKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤没用选项
|
||||
* @param selectedRowKeys
|
||||
*/
|
||||
function filterUnuseSelect() {
|
||||
selectRows.value = unref(selectRows).filter(item=>{
|
||||
let combineKey = combineRowKey(item);
|
||||
return unref(checkedKeys).indexOf(combineKey)>=0
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key获取row信息
|
||||
* @param key
|
||||
*/
|
||||
function getRowByKey(key) {
|
||||
let row = unref(dataSource).filter(record => combineRowKey(record) === key);
|
||||
return row&&row.length>0?row[0]:'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载rowKey
|
||||
*/
|
||||
function combineRowKey(record) {
|
||||
let res = record?.id || '';
|
||||
Object.keys(record).forEach(key => {
|
||||
res = (key =='rowIndex') ? (record[key] + res) : (res + record[key]);
|
||||
});
|
||||
res = res.length > 50 ? res.substring(0, 50) : res;
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载列信息
|
||||
*/
|
||||
function loadColumnsInfo() {
|
||||
let url = `${configUrl.getColumns}${props.code}`;
|
||||
//缓存key
|
||||
let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
|
||||
httpGroupRequest(() => defHttp.get({url}, {isTransformResponse: false, successMessageMode: 'none'}), groupIdKey).then(res => {
|
||||
if (res.success) {
|
||||
initDictOptionData(res.result.dictOptions);
|
||||
cgRpConfigId.value = res.result.cgRpConfigId;
|
||||
title.value = res.result.cgRpConfigName;
|
||||
let currColumns = res.result.columns;
|
||||
for (let a = 0; a < currColumns.length; a++) {
|
||||
if (currColumns[a].customRender) {
|
||||
let dictCode = currColumns[a].customRender;
|
||||
currColumns[a].customRender = ({text}) => {
|
||||
return filterMultiDictText(unref(dictOptions)[dictCode], text + "");
|
||||
}
|
||||
}
|
||||
// 排序字段受控
|
||||
if (unref(iSorter) && currColumns[a].dataIndex === unref(iSorter).column) {
|
||||
currColumns[a].sortOrder = unref(iSorter).order === 'asc' ? 'ascend' : 'descend'
|
||||
}
|
||||
}
|
||||
if (currColumns[0].key !== 'rowIndex') {
|
||||
currColumns.unshift({
|
||||
title: '序号',
|
||||
dataIndex: 'rowIndex',
|
||||
key:'rowIndex',
|
||||
width:60,
|
||||
align:"center",
|
||||
customRender:function ({text}) {
|
||||
return parseInt(text)+1;
|
||||
}
|
||||
});
|
||||
}
|
||||
columns.value = [...currColumns];
|
||||
initQueryInfo(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载列和数据[列表专用]
|
||||
*/
|
||||
function loadColumnsAndData() {
|
||||
// 第一次加载 置空isTotal 在这里调用确保 该方法只是进入页面后 加载一次 其余查询不走该方法
|
||||
pagination.isTotal = ''
|
||||
let url = `${configUrl.getColumnsAndData}${props.id}`;
|
||||
//缓存key
|
||||
let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
|
||||
httpGroupRequest(() => defHttp.get({url}, {isTransformResponse: false, successMessageMode: 'none'}), groupIdKey).then(res => {
|
||||
if (res.success) {
|
||||
initDictOptionData(res.result.dictOptions);
|
||||
cgRpConfigId.value = props.id;
|
||||
let { columns: metaColumnList, cgreportHeadName, fieldHrefSlots, isGroupTitle } = res.result;
|
||||
title.value = cgreportHeadName;
|
||||
// href 跳转
|
||||
const fieldHrefSlotKeysMap = {}
|
||||
fieldHrefSlots.forEach(item => fieldHrefSlotKeysMap[item.slotName] = item)
|
||||
let currColumns = handleColumnHrefAndDict(metaColumnList, fieldHrefSlotKeysMap)
|
||||
|
||||
// popup需要序号, 普通列表不需要
|
||||
if(clickThenCheckFlag===true){
|
||||
currColumns.unshift({
|
||||
title: '序号',
|
||||
dataIndex: 'rowIndex',
|
||||
key:'rowIndex',
|
||||
width:60,
|
||||
align:"center",
|
||||
customRender:function ({text}) {
|
||||
return parseInt(text)+1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 合并表头
|
||||
if(isGroupTitle === true){
|
||||
currColumns = handleGroupTitle(currColumns);
|
||||
}
|
||||
columns.value = [...currColumns];
|
||||
initQueryInfo(res.result.data)
|
||||
}else{
|
||||
//update-begin-author:taoyan date:20220401 for: VUEN-583【vue3】JeecgBootException: sql黑名单校验不通过,请联系管理员!,前台无提示
|
||||
createMessage.warning(res.message)
|
||||
//update-end-author:taoyan date:20220401 for: VUEN-583【vue3】JeecgBootException: sql黑名单校验不通过,请联系管理员!,前台无提示
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理求和的列 合计逻辑 [待优化 3.0]
|
||||
*/
|
||||
function handleSumColumn(metaColumnList: OnlineColumn[], dataTotal: number):void {
|
||||
// 获取需要合计列的dataIndex
|
||||
let sumColumnList = getNeedSumColumns(metaColumnList);
|
||||
// 判断是否为第一次获取数据,如果是的话,则需要重新设置pageSize
|
||||
if (pagination.isTotal == '') {
|
||||
if (sumColumnList.length > 0) {
|
||||
pagination.isTotal = true
|
||||
// 有合计字段时,每次最多查询原pageSize-1条记录,另外需要第一次时将查询的10条中删除最后一条
|
||||
// 删除最后一条数据 如果第一次得到的数据长度等于pageSize的话,则删除最后一条
|
||||
if (dataSource.value.length == pagination.pageSize) {
|
||||
let remove_data = dataSource.value.pop()
|
||||
}
|
||||
pagination.realPageSize = pagination.pageSize - 1
|
||||
} else {
|
||||
pagination.isTotal = false
|
||||
}
|
||||
}
|
||||
// 需要添加合计字段
|
||||
if (pagination.isTotal) {
|
||||
let totalRow = { }
|
||||
sumColumnList.forEach(dataIndex => {
|
||||
let count = 0
|
||||
dataSource.value.forEach(row => {
|
||||
// 统计去除null及空数据
|
||||
if(row[dataIndex] != null && row[dataIndex] != ''){
|
||||
count += parseFloat(row[dataIndex])
|
||||
}
|
||||
})
|
||||
totalRow[dataIndex] = isNaN(count) ? '包含非数字内容' : count.toFixed(2)
|
||||
|
||||
// 长整形时合计不显示.00后缀
|
||||
let v = metaColumnList.find(v=>v.dataIndex==dataIndex);
|
||||
if(v && v.fieldType == 'Long'){
|
||||
totalRow[dataIndex] = parseInt(totalRow[dataIndex]);
|
||||
}
|
||||
})
|
||||
dataSource.value.push(totalRow)
|
||||
pagination.realTotal = dataTotal
|
||||
pagination.total = Number(dataTotal) + Number(Math.floor(dataTotal/pagination.realPageSize))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要求和的列 dataIndex
|
||||
* @param columns
|
||||
*/
|
||||
function getNeedSumColumns(columns: OnlineColumn[]):string[]{
|
||||
let arr:string[] = []
|
||||
for(let column of columns){
|
||||
if (column.isTotal === '1') {
|
||||
arr.push(column.dataIndex!)
|
||||
if(column.children && column.children.length>0){
|
||||
let subArray = getNeedSumColumns(column.children)
|
||||
if(subArray.length>0){
|
||||
arr.push(...subArray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理列的href和字典翻译
|
||||
*/
|
||||
function handleColumnHrefAndDict(columns: OnlineColumn[], fieldHrefSlotKeysMap:{}):OnlineColumn[] {
|
||||
for(let column of columns){
|
||||
let { customRender, hrefSlotName, fieldType } = column
|
||||
// online 报表中类型配置为日期(yyyy-MM-dd ),但是实际展示为日期时间格式(yyyy-MM-dd HH:mm:ss) issues/3042
|
||||
if(fieldType=='Date'){
|
||||
column.customRender = ({text}) => {
|
||||
if(!text){
|
||||
return ''
|
||||
}
|
||||
if(text.length>10){
|
||||
return text.substring(0, 10)
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}else{
|
||||
if (!hrefSlotName && (column.scopedSlots && column.scopedSlots.customRender)) {
|
||||
//【Online报表】字典和href互斥 这里通过fieldHrefSlotKeysMap 先找到是href的列
|
||||
if (fieldHrefSlotKeysMap.hasOwnProperty(column.scopedSlots.customRender)) {
|
||||
hrefSlotName = column.scopedSlots.customRender
|
||||
}
|
||||
}
|
||||
// 如果 customRender 有值则代表使用了字典
|
||||
// 如果 hrefSlotName 有值则代表使用了href跳转
|
||||
// 两者可以兼容。兼容的具体思路为:先获取到字典替换的值,再添加href链接跳转
|
||||
if (customRender || hrefSlotName) {
|
||||
let dictCode = customRender as string
|
||||
let replaceFlag = '_replace_text_'
|
||||
column.customRender = ({text, record}) => {
|
||||
let value = text
|
||||
// 如果 dictCode 有值,就进行字典转换
|
||||
if (dictCode) {
|
||||
if (dictCode.startsWith(replaceFlag)) {
|
||||
let textFieldName = dictCode.replace(replaceFlag, '')
|
||||
value = record[textFieldName]
|
||||
} else {
|
||||
value = filterMultiDictText(unref(dictOptions)[dictCode], text + "");
|
||||
}
|
||||
}
|
||||
// 扩展参数设置列的内容长度
|
||||
if(column.showLength){
|
||||
if(value && value.length>column.showLength){
|
||||
value = value.substr(0, column.showLength)+'...'
|
||||
}
|
||||
}
|
||||
// 如果 hrefSlotName 有值,就生成一个 a 标签,包裹住字典替换后(或原生)的值
|
||||
if (hrefSlotName) {
|
||||
let field = fieldHrefSlotKeysMap[hrefSlotName]
|
||||
if (field) {
|
||||
return h('a', {
|
||||
onClick: ()=>handleClickFieldHref(field, record)
|
||||
}, value)
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理合并表头
|
||||
* @param columns
|
||||
*/
|
||||
function handleGroupTitle(columns: OnlineColumn[]):OnlineColumn[]{
|
||||
let newColumns:OnlineColumn[] = []
|
||||
for(let column of columns){
|
||||
//排序字段受控 ---- 此逻辑为新增逻辑 待
|
||||
if (unref(iSorter) && column.dataIndex === unref(iSorter).column) {
|
||||
column.sortOrder = unref(iSorter).order === 'asc' ? 'ascend' : 'descend'
|
||||
}
|
||||
//判断字段是否需要合并表头
|
||||
if (column.groupTitle) {
|
||||
let clIndex = newColumns.findIndex(im => im.title === column.groupTitle)
|
||||
if (clIndex !== -1) {
|
||||
//表头已存在直接push children
|
||||
newColumns[clIndex].children!.push(column)
|
||||
} else {
|
||||
//表头不存在组装表头信息
|
||||
let clGroup:OnlineColumn = {},child:OnlineColumn[] = []
|
||||
child.push(column)
|
||||
clGroup.title = column.groupTitle
|
||||
clGroup.align = 'center'
|
||||
clGroup.children = child
|
||||
newColumns.push(clGroup)
|
||||
}
|
||||
} else {
|
||||
newColumns.push(column)
|
||||
}
|
||||
}
|
||||
return newColumns;
|
||||
}
|
||||
|
||||
// 获取路由器对象 href跳转用到
|
||||
let router = useRouter();
|
||||
/**
|
||||
* href 点击事件
|
||||
* @param field
|
||||
* @param record
|
||||
*/
|
||||
function handleClickFieldHref(field, record) {
|
||||
let href = field.href
|
||||
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?/
|
||||
let compPattern = /\.vue(\?.*)?$/
|
||||
let jsPattern = /{{([^}]+)}}/g // {{ xxx }}
|
||||
if (typeof href === 'string') {
|
||||
href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2])
|
||||
// 执行 {{...}} JS增强语句
|
||||
if (jsPattern.test(href)) {
|
||||
href = href.replace(jsPattern, function (text, s0) {
|
||||
try {
|
||||
return eval(s0)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return text
|
||||
}
|
||||
})
|
||||
}
|
||||
if (urlPattern.test(href)) {
|
||||
window.open(href, '_blank')
|
||||
} else if (compPattern.test(href)) {
|
||||
// 处理弹框
|
||||
openHrefCompModal(href)
|
||||
} else {
|
||||
router.push(href)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*/
|
||||
function handleExport() {
|
||||
const {handleExportXls} = useMethods();
|
||||
let url = `${configUrl.export}${cgRpConfigId.value}`;
|
||||
let params = getQueryParams();//查询条件
|
||||
handleExportXls(title.value , url, params)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 合计逻辑 [待优化 3.0]
|
||||
* 分页 大小改变事件
|
||||
* @param _current
|
||||
* @param size
|
||||
*/
|
||||
function onSizeChange(_current, size){
|
||||
pagination.isTotal = '';
|
||||
pagination.pageSize = size;
|
||||
if(pagination.isTotal){
|
||||
pagination.realPageSize = size - 1;
|
||||
}else{
|
||||
pagination.realPageSize = size
|
||||
}
|
||||
pagination.current = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合计逻辑 [待优化 3.0]
|
||||
* 显示总条数
|
||||
* @param total
|
||||
*/
|
||||
function onShowTotal(total) {
|
||||
// 重新根据是否有合计计算每页显示的数据
|
||||
let start = (pagination.current - 1) * pagination.realPageSize + 1
|
||||
let end = start + (pagination.isTotal ? dataSource.value.length - 1 : dataSource.value.length) - 1
|
||||
let realTotal = pagination.isTotal ? pagination.realTotal : total
|
||||
return start + '-' + end + ' 共' + realTotal + '条'
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框显示隐藏触发事件
|
||||
*/
|
||||
async function visibleChange($event) {
|
||||
visible.value = $event;
|
||||
$event && loadColumnsInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化查询条件
|
||||
* @param data 数据结果集
|
||||
*/
|
||||
function initQueryInfo(data) {
|
||||
let url = `${configUrl.getQueryInfo}${unref(cgRpConfigId)}`
|
||||
//缓存key
|
||||
let groupIdKey = props.groupId ? `${props.groupId}${url}` : '';
|
||||
httpGroupRequest(() => defHttp.get({url}, {isTransformResponse: false, successMessageMode: 'none'}), groupIdKey).then((res) => {
|
||||
// console.log("获取查询条件", res);
|
||||
if (res.success) {
|
||||
dynamicParamHandler(res.result);
|
||||
queryInfo.value = res.result;
|
||||
console.log("queryInfo==>",queryInfo.value)
|
||||
//查询条件加载后再请求数据
|
||||
if(data){
|
||||
setDataSource(data)
|
||||
}else{
|
||||
//没有传递data时查询数据
|
||||
loadData(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
createMessage.warning(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载表格数据
|
||||
* @param arg
|
||||
*/
|
||||
function loadData(arg?) {
|
||||
if (arg == 1) {
|
||||
pagination.current = 1
|
||||
}
|
||||
let params = getQueryParams();//查询条件
|
||||
loading.value = true;
|
||||
let url = `${configUrl.getData}${unref(cgRpConfigId)}`
|
||||
//缓存key
|
||||
let groupIdKey = props.groupId ? `${props.groupId}${url}${JSON.stringify(params)}` : '';
|
||||
httpGroupRequest(() => defHttp.get({url, params}, {isTransformResponse: false, successMessageMode: 'none'}), groupIdKey).then(res => {
|
||||
loading.value = false;
|
||||
let data = res.result;
|
||||
console.log("表格信息:", data)
|
||||
setDataSource(data);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置dataSource
|
||||
*/
|
||||
function setDataSource(data) {
|
||||
if (data) {
|
||||
pagination.total = Number(data.total)
|
||||
let currentPage = pagination?.current??1;
|
||||
for (let a = 0; a < data.records.length; a++) {
|
||||
if (!data.records[a].rowIndex) {
|
||||
data.records[a].rowIndex = a+(currentPage-1)*10;
|
||||
}
|
||||
}
|
||||
dataSource.value = data.records
|
||||
} else {
|
||||
pagination.total = 0;
|
||||
dataSource.value = [];
|
||||
}
|
||||
// 合计逻辑 [待优化 3.0]
|
||||
handleSumColumn(columns.value, pagination.total)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询参数
|
||||
*/
|
||||
function getQueryParams() {
|
||||
let paramTarget = {};
|
||||
if (unref(dynamicParam)) {
|
||||
//处理自定义参数
|
||||
Object.keys(unref(dynamicParam)).map(key => {
|
||||
paramTarget['self_' + key] = unref(dynamicParam)[key]
|
||||
})
|
||||
}
|
||||
let param = Object.assign(paramTarget, unref(queryParam), unref(iSorter));
|
||||
param.pageNo = pagination.current;
|
||||
// 合计逻辑 [待优化 3.0]
|
||||
// 实际查询时不使用table组件的pageSize,而使用自定义的realPageSize,realPageSize会在第一次获取到数据后变化
|
||||
param.pageSize = pagination.realPageSize;
|
||||
return filterObj(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理动态参数
|
||||
*/
|
||||
function dynamicParamHandler(arr?) {
|
||||
if (arr && arr.length > 0) {
|
||||
//第一次加载查询条件前 初始化queryParam为空对象
|
||||
let queryTemp = {};
|
||||
for (let item of arr) {
|
||||
if (item.mode === 'single') {
|
||||
queryTemp[item.field] = ''
|
||||
}
|
||||
}
|
||||
queryParam.value = {...queryTemp}
|
||||
}
|
||||
let dynamicTemp = {};
|
||||
if (props.param) {
|
||||
Object.keys(props.param).map(key => {
|
||||
let str = props.param[key];
|
||||
if (key in queryParam) {
|
||||
if (str && str.startsWith("'") && str.endsWith("'")) {
|
||||
str = str.substring(1, str.length - 1)
|
||||
}
|
||||
//如果查询条件包含参数 设置值
|
||||
unref(queryParam)[key] = str
|
||||
}
|
||||
dynamicTemp[key] = props.param[key]
|
||||
})
|
||||
}
|
||||
dynamicParam.value = {...dynamicTemp}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页
|
||||
* @param page
|
||||
* @param filters
|
||||
* @param sorter
|
||||
*/
|
||||
function handleChangeInTable(page, filters, sorter) {
|
||||
console.log(page, filters, sorter);
|
||||
//分页、排序、筛选变化时触发
|
||||
if (Object.keys(sorter).length > 0) {
|
||||
iSorter.value = {
|
||||
column: sorter.field,
|
||||
order: 'ascend' === sorter.order ? 'asc' : 'desc'
|
||||
}
|
||||
// 排序字段受控
|
||||
unref(columns).forEach(col => {
|
||||
if (col['dataIndex'] === sorter.field) {
|
||||
col['sortOrder'] = sorter.order
|
||||
}
|
||||
})
|
||||
}
|
||||
pagination.current = page.current;
|
||||
pagination.pageSize = page.pageSize;
|
||||
loadData()
|
||||
}
|
||||
|
||||
/**
|
||||
* 行点击事件
|
||||
* @param record
|
||||
*/
|
||||
function clickThenCheck(record) {
|
||||
if(clickThenCheckFlag===true){
|
||||
let rowKey = combineRowKey(record);
|
||||
if (!unref(checkedKeys) || unref(checkedKeys).length == 0) {
|
||||
let arr1: any[] = [], arr2: any[] = [];
|
||||
arr1.push(record);
|
||||
arr2.push(rowKey);
|
||||
checkedKeys.value = arr2;
|
||||
selectRows.value = arr1
|
||||
} else {
|
||||
if (unref(checkedKeys).indexOf(rowKey) < 0) {
|
||||
//不存在就选中
|
||||
checkedKeys.value.push(rowKey);
|
||||
selectRows.value.push(record)
|
||||
} else {
|
||||
//已选中就取消
|
||||
let rowKey_index = unref(checkedKeys).indexOf(rowKey);
|
||||
checkedKeys.value.splice(rowKey_index, 1);
|
||||
selectRows.value.splice(rowKey_index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//防止字典中有垃圾数据
|
||||
function initDictOptionData(arr) {
|
||||
let obj = {};
|
||||
Object.keys(arr).map(k => {
|
||||
obj[k] = arr[k].filter(item => {
|
||||
return item != null
|
||||
});
|
||||
});
|
||||
dictOptions.value = obj
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤对象中为空的属性
|
||||
* @param obj
|
||||
* @returns {*}
|
||||
*/
|
||||
function filterObj(obj) {
|
||||
if (!(typeof obj == 'object')) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key)
|
||||
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
// 样式
|
||||
const dialogStyle = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
}
|
||||
|
||||
// 弹窗属性配置
|
||||
const hrefComponent = ref({
|
||||
model: {
|
||||
title: '',
|
||||
okText: '关闭',
|
||||
width: '100%',
|
||||
visible: false,
|
||||
destroyOnClose: true,
|
||||
style: dialogStyle,
|
||||
// dialogStyle: dialogStyle,
|
||||
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
|
||||
// 隐藏掉取消按钮
|
||||
cancelButtonProps: { style: { display: 'none' } }
|
||||
},
|
||||
on: {
|
||||
ok: () => hrefComponent.value.model.visible = false,
|
||||
cancel: () => hrefComponent.value.model.visible = false,
|
||||
},
|
||||
is: <any> null,
|
||||
params: {},
|
||||
});
|
||||
|
||||
// 超链点击事件--> 打开一个modal窗口
|
||||
function openHrefCompModal(href) {
|
||||
// 解析 href 参数
|
||||
let index = href.indexOf('?')
|
||||
let path = href
|
||||
if (index !== -1) {
|
||||
path = href.substring(0, index)
|
||||
let paramString = href.substring(index + 1, href.length)
|
||||
let paramArray = paramString.split('&')
|
||||
let params = {}
|
||||
paramArray.forEach(paramObject => {
|
||||
let paramItem = paramObject.split('=')
|
||||
params[paramItem[0]] = paramItem[1]
|
||||
})
|
||||
hrefComponent.value.params = params
|
||||
} else {
|
||||
hrefComponent.value.params = {}
|
||||
}
|
||||
hrefComponent.value.model.visible = true
|
||||
hrefComponent.value.model.title = '操作'
|
||||
hrefComponent.value.is = defineAsyncComponent(() => import(/* @vite-ignore */'/@/views/' + (path.startsWith('/') ? path.slice(1) : path)))
|
||||
}
|
||||
|
||||
return [{visibleChange, loadColumnsInfo,loadColumnsAndData, dynamicParamHandler, loadData, handleChangeInTable, combineRowKey, clickThenCheck,filterUnuseSelect, handleExport},
|
||||
{hrefComponent, visible, rowSelection, checkedKeys, selectRows, pagination, dataSource, columns, indexColumnProps, loading, title,iSorter,queryInfo,queryParam,dictOptions}];
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
interface ScopedSlots{
|
||||
customRender: string
|
||||
}
|
||||
|
||||
interface HrefSlots{
|
||||
// 链接地址
|
||||
href: string
|
||||
// fieldHref_字段名
|
||||
slotName: string
|
||||
}
|
||||
|
||||
interface OnlineColumn {
|
||||
dataIndex?: string;
|
||||
title?: string;
|
||||
key?: string;
|
||||
fieldType?: string;
|
||||
width?: number | string;
|
||||
align?: string;
|
||||
sorter?: string | boolean;
|
||||
isTotal?: string | number | boolean;
|
||||
groupTitle?: string;
|
||||
// 超链的时候 和HrefSlots中的slotName匹配
|
||||
scopedSlots? : ScopedSlots;
|
||||
// 一般用于字典 字典传过来的是字典编码字符串 后转函数
|
||||
customRender?: string | Function;
|
||||
// 这个类型不知道有什么用
|
||||
hrefSlotName?: string;
|
||||
showLength?: number | string;
|
||||
children?: OnlineColumn[];
|
||||
sortOrder?: string;
|
||||
// 插槽对应控件类型(列表)
|
||||
slots?:ScopedSlots,
|
||||
//超过宽度将自动省略,暂不支持和排序筛选一起使用。
|
||||
ellipsis?: boolean
|
||||
}
|
||||
|
||||
export{
|
||||
OnlineColumn,
|
||||
HrefSlots
|
||||
}
|
|
@ -18,6 +18,8 @@ import {setupI18n} from '/@/locales/setupI18n';
|
|||
import {registerGlobComp} from '/@/components/registerGlobComp';
|
||||
import {registerThirdComp} from '/@/settings/registerThirdComp';
|
||||
import {useSso} from '/@/hooks/web/useSso';
|
||||
import {registerPackages} from '/@/utils/monorepo/registerPackages';
|
||||
|
||||
// 在本地开发中引入的,以提高浏览器响应速度
|
||||
if (import.meta.env.DEV) {
|
||||
import('ant-design-vue/dist/antd.less');
|
||||
|
@ -35,6 +37,9 @@ async function bootstrap() {
|
|||
// 初始化内部系统配置
|
||||
initAppConfigStore();
|
||||
|
||||
// 注册外部模块路由
|
||||
registerPackages(app);
|
||||
|
||||
// 注册全局组件
|
||||
registerGlobComp(app);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { warn } from '/@/utils/log';
|
|||
import { createRouter, createWebHashHistory } from 'vue-router';
|
||||
import { getToken } from '/@/utils/auth';
|
||||
import {URL_HASH_TAB} from '/@/utils'
|
||||
import { packageViews } from '/@/utils/monorepo/dynamicRouter';
|
||||
|
||||
export type LayoutMapKey = 'LAYOUT';
|
||||
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
|
||||
|
@ -23,7 +24,11 @@ let dynamicViewsModules: Record<string, () => Promise<Recordable>>;
|
|||
|
||||
// Dynamic introduction
|
||||
function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
|
||||
dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}');
|
||||
if (!dynamicViewsModules) {
|
||||
dynamicViewsModules = import.meta.glob('../../views/**/*.{vue,tsx}');
|
||||
// 跟模块views合并
|
||||
dynamicViewsModules = Object.assign({}, dynamicViewsModules, packageViews);
|
||||
}
|
||||
if (!routes) return;
|
||||
routes.forEach((item) => {
|
||||
// update-begin--author:sunjianlei---date:20210918---for:适配旧版路由选项 --------
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
export type DynamicViewsRecord = Record<string, () => Promise<Recordable>>
|
||||
|
||||
/** 已注册模块的动态页面 */
|
||||
export const packageViews: DynamicViewsRecord = {};
|
||||
|
||||
/**
|
||||
* 注册动态路由页面
|
||||
* @param getViews 获取该模块下所有页面的方法
|
||||
*/
|
||||
export function registerDynamicRouter(getViews: () => DynamicViewsRecord) {
|
||||
if (typeof getViews === 'function') {
|
||||
let dynamicViews = getViews();
|
||||
Object.keys(dynamicViews).forEach((key) => {
|
||||
// 处理动态页面的key,使其可以让路由识别
|
||||
let newKey = key.replace('./src/views', '../../views');
|
||||
packageViews[newKey] = dynamicViews[key];
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import type { App } from 'vue';
|
||||
import { warn } from '/@/utils/log';
|
||||
import { registerDynamicRouter } from '/@/utils/monorepo/dynamicRouter';
|
||||
// 引入模块
|
||||
import PACKAGE_TEST_JEECG_ONLINE from '@jeecg/online';
|
||||
|
||||
export function registerPackages(app: App) {
|
||||
use(app, PACKAGE_TEST_JEECG_ONLINE);
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
const installOptions = {
|
||||
baseImport,
|
||||
};
|
||||
|
||||
/** 注册模块 */
|
||||
function use(app: App, pkg) {
|
||||
app.use(pkg, installOptions);
|
||||
registerDynamicRouter(pkg.getViews);
|
||||
}
|
||||
|
||||
// 模块里可使用的import
|
||||
const importGlobs = [
|
||||
import.meta.glob('../../utils/**/*.{ts,js,tsx}'),
|
||||
import.meta.glob('../../hooks/**/*.{ts,js,tsx}'),
|
||||
];
|
||||
|
||||
/**
|
||||
* 基础项目导包
|
||||
* 目前支持导入如下
|
||||
* /@/utils/**
|
||||
* /@/hooks/**
|
||||
*
|
||||
* @param path 文件路径,ts无需输入后缀名。如:/@/utils/common/compUtils
|
||||
*/
|
||||
async function baseImport(path: string) {
|
||||
if (path) {
|
||||
// 将 /@/ 替换成 ../../
|
||||
path = path.replace(/^\/@\//, '../../');
|
||||
for (const glob of importGlobs) {
|
||||
for (const key of Object.keys(glob)) {
|
||||
if (path === key || `${path}.ts` === key || `${path}.tsx` === key) {
|
||||
return glob[key]();
|
||||
}
|
||||
}
|
||||
}
|
||||
warn(`引入失败:${path} 不存在`);
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -62,6 +62,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
},
|
||||
build: {
|
||||
target: 'es2015',
|
||||
cssTarget: 'chrome80',
|
||||
outDir: OUTPUT_DIR,
|
||||
terserOptions: {
|
||||
compress: {
|
||||
|
@ -93,6 +94,9 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
plugins: createVitePlugins(viteEnv, isBuild),
|
||||
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
target: 'es2020',
|
||||
},
|
||||
// @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly
|
||||
include: [
|
||||
'@iconify/iconify',
|
||||
|
|
Loading…
Reference in New Issue