feat: 新增图表渲染
This commit is contained in:
parent
32ac8041ee
commit
f6afbac2a5
@ -12,7 +12,7 @@ module.exports = {
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
rules: {
|
||||
semi: 2,
|
||||
semi: 0,
|
||||
'vue/multi-word-component-names': 0,
|
||||
indent: [
|
||||
2, 2, {
|
||||
|
3
components.d.ts
vendored
3
components.d.ts
vendored
@ -25,6 +25,9 @@ declare module 'vue' {
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
|
@ -7,13 +7,14 @@
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<div class="chart-wrap">
|
||||
<Column v-if="chartType === 'bar'" />
|
||||
<Column v-if="chartType === 'bar'" :config="currentChart" />
|
||||
<Line v-if="chartType === 'line'" :config="currentChart" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import Line from "@/plugins/antv-g2plot/line.vue";
|
||||
import Column from "@/plugins/antv-g2plot/column.vue";
|
||||
|
||||
@ -25,6 +26,10 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const chartType = ref("line");
|
||||
|
||||
const currentChart = computed(() => {
|
||||
return props.chartCfg[chartType.value];
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -30,6 +30,7 @@
|
||||
:columns="columnConfig"
|
||||
:data-source="dataList"
|
||||
:pagination="false"
|
||||
:scroll="{ x: 1000, y: `calc(100vh - 260px)` }"
|
||||
size="small"
|
||||
bordered
|
||||
></a-table>
|
||||
@ -81,7 +82,6 @@ const pageState = reactive({
|
||||
watch(
|
||||
() => props.filterConfig,
|
||||
(newVal) => {
|
||||
console.log("newVal", newVal);
|
||||
|
||||
newVal.forEach((item) => {
|
||||
filterData.value[item.name] = undefined;
|
||||
@ -126,6 +126,7 @@ const pageChange = () => {
|
||||
.filter-item {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.input-item {
|
||||
width: 180px;
|
||||
|
@ -14,9 +14,9 @@
|
||||
:options="projectSelect"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="数据表名称" name="modular_name">
|
||||
<a-form-item label="数据来源" name="modular_name">
|
||||
<a-input
|
||||
placeholder="请输入数据表名称"
|
||||
placeholder="请输入数据来源"
|
||||
v-model:value="formData.modular_name"
|
||||
/>
|
||||
</a-form-item>
|
||||
@ -27,26 +27,48 @@
|
||||
:unCheckedValue="0"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="展示类型" name="show_type_id">
|
||||
<a-select
|
||||
placeholder="请选择展示类型"
|
||||
v-model:value="formData.show_type_id"
|
||||
:options="showTypes"
|
||||
/>
|
||||
<a-form-item label="数据源类型" name="original_type">
|
||||
<a-radio-group v-model:value="formData.original_type">
|
||||
<a-radio :value="1">自定义</a-radio>
|
||||
<a-radio :value="2">指定表</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="sql数据源" name="original_sql">
|
||||
<a-form-item
|
||||
v-if="formData.original_type === 1"
|
||||
label="sql数据源"
|
||||
name="original_sql"
|
||||
>
|
||||
<a-input
|
||||
placeholder="请输入sql数据源"
|
||||
v-model:value="formData.original_sql"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="formData.original_type === 2"
|
||||
label="数据表"
|
||||
name="table"
|
||||
>
|
||||
<a-select
|
||||
placeholder="请选择数据表"
|
||||
v-model:value="formData.table"
|
||||
:options="tableTypes"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<!-- <a-form-item label="展示类型" name="show_type_id">
|
||||
<a-select
|
||||
placeholder="请选择展示类型"
|
||||
v-model:value="formData.show_type_id"
|
||||
:options="showTypes"
|
||||
/>
|
||||
</a-form-item> -->
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { getShowTypeSelect } from "@/views/config-manage/module-cfg/service";
|
||||
import { getDbTableSelect } from "@/views/config-manage/module-cfg/service";
|
||||
|
||||
const props = defineProps({
|
||||
open: {
|
||||
@ -70,20 +92,24 @@ const props = defineProps({
|
||||
const emit = defineEmits(["ok"]);
|
||||
const formRules = ref({
|
||||
modular_name: [
|
||||
{ required: true, message: "请输入数据表名称", trigger: "submit" },
|
||||
{ required: true, message: "请输入数据来源", trigger: "submit" },
|
||||
],
|
||||
show_type_id: [{ required: true, message: "请选择", trigger: "submit" }],
|
||||
// show_type_id: [{ required: true, message: "请选择", trigger: "submit" }],
|
||||
original_type: [{ required: true, message: "请选择", trigger: "submit" }],
|
||||
original_sql: [{ required: true, message: "请输入", trigger: "submit" }],
|
||||
table: [{ required: true, message: "请选择", trigger: "submit" }],
|
||||
});
|
||||
|
||||
const showTypes = ref([]);
|
||||
const tableTypes = ref([]);
|
||||
const formRef = ref();
|
||||
const formData = ref({
|
||||
project_id: undefined,
|
||||
modular_name: undefined,
|
||||
is_show: 0,
|
||||
show_type_id: undefined,
|
||||
original_type: 1, // 1 - 自定义,2 - 指定表
|
||||
// show_type_id: undefined,
|
||||
original_sql: undefined,
|
||||
table: undefined,
|
||||
});
|
||||
|
||||
watch(
|
||||
@ -97,20 +123,21 @@ watch(
|
||||
project_id: newVal.project_id,
|
||||
modular_name: newVal.modular_name,
|
||||
is_show: newVal.is_show,
|
||||
show_type_id: newVal.show_type_id,
|
||||
// show_type_id: newVal.show_type_id,
|
||||
original_sql: newVal.original_sql,
|
||||
table: newVal.table,
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
toGetShowType();
|
||||
toGetDbTable();
|
||||
});
|
||||
|
||||
const toGetShowType = () => {
|
||||
getShowTypeSelect().then((res) => {
|
||||
showTypes.value = res.data;
|
||||
const toGetDbTable = () => {
|
||||
getDbTableSelect().then((res) => {
|
||||
tableTypes.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
@ -119,8 +146,10 @@ const resetFormData = () => {
|
||||
project_id: undefined,
|
||||
modular_name: undefined,
|
||||
is_show: 0,
|
||||
show_type_id: undefined,
|
||||
original_type: 1, // 1 - 自定义,2 - 指定表
|
||||
// show_type_id: undefined,
|
||||
original_sql: undefined,
|
||||
table: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ export const moduleCfgCols = [
|
||||
{ dataIndex: 'modular_name', title: '数据表名称', align: 'center'},
|
||||
{ dataIndex: 'project_name', title: '项目名称', align: 'center'},
|
||||
{ dataIndex: 'is_show', title: '展示状态', align: 'center'},
|
||||
{ dataIndex: 'show_type_handle', title: '展示类型', align: 'center'},
|
||||
{ dataIndex: 'original_type_handle', title: '数据源类型', align: 'center'},
|
||||
// { dataIndex: 'sort', title: '排序', align: 'center'},
|
||||
{ dataIndex: 'action', title: '操作', align: 'center'},
|
||||
];
|
||||
|
@ -54,10 +54,10 @@ export function getProjectSelect() {
|
||||
});
|
||||
}
|
||||
|
||||
// 展示类型下拉
|
||||
export function getShowTypeSelect() {
|
||||
// 数据源表下拉
|
||||
export function getDbTableSelect() {
|
||||
return get({
|
||||
url: `/api/v1/modular/get-show-type-drop`,
|
||||
url: `/api/v1/modular/get-database-table-drop`,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,16 @@
|
||||
<div class="normal-container">
|
||||
<div class="view-create-box">
|
||||
<div class="left-box">
|
||||
<a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
||||
<a-form-item label="项目"
|
||||
><a-select
|
||||
placeholder="请选择项目"
|
||||
:options="projectSel"
|
||||
v-model:value="projectId"
|
||||
@change="onProjectChange"
|
||||
></a-select
|
||||
><a-select
|
||||
placeholder="请选择项目"
|
||||
:options="projectSel"
|
||||
v-model:value="projectId"
|
||||
@change="onProjectChange"
|
||||
></a-select
|
||||
></a-form-item>
|
||||
<a-form-item label="数据表">
|
||||
<a-form-item label="数据来源">
|
||||
<a-select
|
||||
placeholder="请选择"
|
||||
:options="modularSel"
|
||||
@ -19,16 +19,29 @@
|
||||
@change="onModularChange"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="字段">
|
||||
<a-checkbox-group v-if="fieldList.length" v-model:value="fieldIds">
|
||||
<a-form-item label="展示类型">
|
||||
<a-select
|
||||
placeholder="请选择展示类型"
|
||||
:options="showTypeSel"
|
||||
v-model:value="showTypeId"
|
||||
@change="onShowTypeChange"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="字段" v-if="fieldList.length">
|
||||
<a-checkbox-group v-model:value="fieldIds">
|
||||
<a-checkbox
|
||||
v-for="(item, index) in fieldList"
|
||||
:key="index"
|
||||
:value="item.value"
|
||||
>{{ item.label }}</a-checkbox
|
||||
>{{ item.label }}</a-checkbox
|
||||
>
|
||||
</a-checkbox-group>
|
||||
<a-empty v-else description="暂无字段数据" />
|
||||
</a-form-item>
|
||||
<a-form-item label="x轴" v-if="xDataList.length">
|
||||
<a-radio-group :options="xDataList" v-model:value="xDataId"></a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="y轴" v-if="yDataList.length">
|
||||
<a-checkbox-group :options="yDataList" v-model:value="yDataId"></a-checkbox-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="footer">
|
||||
@ -36,7 +49,7 @@
|
||||
class="preview-btn"
|
||||
:loading="previewLoading"
|
||||
@click="toPreview"
|
||||
>预览</a-button
|
||||
>预览</a-button
|
||||
>
|
||||
<a-button type="primary" @click="addViewName">点击保存</a-button>
|
||||
</div>
|
||||
@ -74,7 +87,7 @@
|
||||
:columns="previewData.columnConfig"
|
||||
:data-source="previewData.dataList"
|
||||
:pagination="false"
|
||||
:scroll="{ x: 1200 }"
|
||||
:scroll="{ x: 1000, y: `calc(100vh - 260px)` }"
|
||||
size="small"
|
||||
bordered
|
||||
></a-table>
|
||||
@ -89,6 +102,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<y-chart v-if="previewData.type === 'chart'" :chartCfg="previewData.chartCfg"></y-chart>
|
||||
<div class="preview-area" v-else>
|
||||
<div><BarChartOutlined /></div>
|
||||
<div>预览区</div>
|
||||
@ -113,16 +127,29 @@
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from "vue";
|
||||
import { getProModularField, preview, saveView } from "./service";
|
||||
import {
|
||||
getProModularField,
|
||||
preview,
|
||||
saveView,
|
||||
getShowTypeSelect,
|
||||
getFieldOpts,
|
||||
} from "./service";
|
||||
import { message } from "ant-design-vue";
|
||||
import { BarChartOutlined } from "@ant-design/icons-vue";
|
||||
import yChart from "@/components/common/y-chart.vue";
|
||||
|
||||
const projectSel = ref([]);
|
||||
const modularSel = ref([]);
|
||||
const fieldList = ref([]);
|
||||
const projectSel = ref([]); // 项目下拉
|
||||
const modularSel = ref([]) // 数据来源下拉
|
||||
const showTypeSel = ref([]); // 展示类型下拉
|
||||
const fieldList = ref([]); // 字段列表
|
||||
const xDataList = ref([]); // x轴数据列表
|
||||
const yDataList = ref([]); // y轴数据列表
|
||||
const projectId = ref();
|
||||
const modularId = ref();
|
||||
const showTypeId = ref();
|
||||
const fieldIds = ref([]);
|
||||
const xDataId = ref();
|
||||
const yDataId = ref();
|
||||
|
||||
const previewLoading = ref(false);
|
||||
const nameVisible = ref(false);
|
||||
@ -134,6 +161,7 @@ const previewData = reactive({
|
||||
columnConfig: [], // 表格表头
|
||||
dataList: [], // 表格数据
|
||||
filterData: {},
|
||||
chartCfg: {},
|
||||
page: 1,
|
||||
perPage: 20,
|
||||
total: 0,
|
||||
@ -141,6 +169,7 @@ const previewData = reactive({
|
||||
|
||||
onMounted(() => {
|
||||
toGetProModularField();
|
||||
toGetShowTypes();
|
||||
});
|
||||
|
||||
const toGetProModularField = () => {
|
||||
@ -149,6 +178,31 @@ const toGetProModularField = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 获取展示类型下拉
|
||||
const toGetShowTypes = () => {
|
||||
getShowTypeSelect().then((res) => {
|
||||
showTypeSel.value = res.data;
|
||||
});
|
||||
};
|
||||
|
||||
// 获取字段列表
|
||||
const toGetFieldOpts = () => {
|
||||
getFieldOpts({
|
||||
modularId: modularId.value,
|
||||
showTypeId: showTypeId.value,
|
||||
}).then((res) => {
|
||||
fieldList.value = res.data.list ? tranformList(res.data.list) : [];
|
||||
xDataList.value = res.data.x_data ? tranformList(res.data.x_data) : [];
|
||||
yDataList.value = res.data.y_data ? tranformList(res.data.y_data) : [];
|
||||
if (!fieldList.value.length) {
|
||||
fieldIds.value = [];
|
||||
} else {
|
||||
xDataId.value = undefined;
|
||||
yDataId.value = [];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onProjectChange = (val) => {
|
||||
const target = projectSel.value.find((item) => item.value === val);
|
||||
modularSel.value = target.child;
|
||||
@ -159,11 +213,24 @@ const onProjectChange = (val) => {
|
||||
};
|
||||
|
||||
const onModularChange = (val) => {
|
||||
const target = modularSel.value.find((item) => item.value === val);
|
||||
fieldList.value = target.child;
|
||||
// const target = modularSel.value.find((item) => item.value === val);
|
||||
// fieldList.value = target.child;
|
||||
resetPreviewData();
|
||||
};
|
||||
|
||||
const onShowTypeChange = () => {
|
||||
toGetFieldOpts();
|
||||
};
|
||||
|
||||
const tranformList = (list) => {
|
||||
return list.map((item) => {
|
||||
return {
|
||||
label: item.field_name,
|
||||
value: item.field_id,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const resetPreviewData = () => {
|
||||
previewData.type = "";
|
||||
previewData.filterConfig = [];
|
||||
@ -194,6 +261,9 @@ const toPreview = () => {
|
||||
page: previewData.page,
|
||||
perPage: previewData.perPage,
|
||||
filter,
|
||||
showTypeId: showTypeId.value,
|
||||
xDataId: xDataId.value.toString(),
|
||||
yDataId: yDataId.value.toString(),
|
||||
})
|
||||
.then((res) => {
|
||||
previewData.type = res.data.type;
|
||||
@ -207,6 +277,8 @@ const toPreview = () => {
|
||||
previewData.columnConfig = res.data.header;
|
||||
previewData.dataList = res.data.data;
|
||||
previewData.total = res.data.count;
|
||||
} else {
|
||||
previewData.chartCfg = res.data.config;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@ -228,8 +300,11 @@ const toSaveView = () => {
|
||||
modularId: modularId.value,
|
||||
fieldIds: fieldIds.value.toString(),
|
||||
previewName: previewName.value,
|
||||
showTypeId: showTypeId.value,
|
||||
xDataId: xDataId.value.toString(),
|
||||
yDataId: yDataId.value.toString(),
|
||||
}).then(() => {
|
||||
message.success("保存成功");
|
||||
message.success("保存成功,可前往视图列表查看");
|
||||
nameVisible.value = false;
|
||||
});
|
||||
};
|
||||
@ -282,7 +357,6 @@ const toFilt = () => {
|
||||
font-size: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.y-table-filter {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@ -290,6 +364,7 @@ const toFilt = () => {
|
||||
.filter-item {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.input-item {
|
||||
width: 180px;
|
||||
|
@ -7,8 +7,26 @@ export function getProModularField() {
|
||||
});
|
||||
}
|
||||
|
||||
// 展示类型下拉
|
||||
export function getShowTypeSelect() {
|
||||
return get({
|
||||
url: `/api/v1/modular/get-show-type-drop`,
|
||||
});
|
||||
}
|
||||
|
||||
// 字段列表
|
||||
export function getFieldOpts({ modularId, showTypeId }) {
|
||||
return get({
|
||||
url: "/api/v1/preview/get-preview-field",
|
||||
params: {
|
||||
modular_id: modularId,
|
||||
show_type_id: showTypeId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 预览
|
||||
export function preview({ modularId, fieldIds, page, perPage, filter }) {
|
||||
export function preview({ modularId, fieldIds, page, perPage, filter, showTypeId, xDataId, yDataId }) {
|
||||
return post({
|
||||
url: "api/v1/preview/view",
|
||||
data: {
|
||||
@ -17,18 +35,24 @@ export function preview({ modularId, fieldIds, page, perPage, filter }) {
|
||||
page,
|
||||
per_page: perPage,
|
||||
filter,
|
||||
show_type_id: showTypeId,
|
||||
x_data_id: xDataId,
|
||||
y_data_id: yDataId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 点击保存
|
||||
export function saveView({ modularId, fieldIds, previewName }) {
|
||||
export function saveView({ modularId, fieldIds, previewName, showTypeId, xDataId, yDataId }) {
|
||||
return post({
|
||||
url: "api/v1/preview/save",
|
||||
data: {
|
||||
modular_id: modularId,
|
||||
field_ids: fieldIds,
|
||||
preview_name: previewName,
|
||||
show_type_id: showTypeId,
|
||||
x_data_id: xDataId,
|
||||
y_data_id: yDataId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="normal-container">
|
||||
<div class="view-list-box">
|
||||
<div class="left-box">
|
||||
<a-form :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
|
||||
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
||||
<a-form-item label="项目">
|
||||
<a-select
|
||||
:options="projectSel"
|
||||
@ -11,11 +11,11 @@
|
||||
@change="onProjectChange"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="数据表">
|
||||
<a-form-item label="数据来源">
|
||||
<a-select
|
||||
:options="modularSel"
|
||||
v-model:value="modularId"
|
||||
placeholder="请选择数据表"
|
||||
placeholder="请先选好项目再选择"
|
||||
@change="onModularChange"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user