基础数据库,数据目录

dev
dengjia 2025-07-21 11:32:02 +08:00
parent a3e5b6d0ee
commit c1337c2f60
22 changed files with 2075 additions and 110 deletions

View File

@ -1,6 +1,11 @@
// 将常用的值储存成常量,防止重复使用写错
export const WHETHER_LIST = [
{ id: "0", name: "否" },
{ id: "1", name: "是" },
{ id: 0, name: "否" },
{ id: 1, name: "是" },
];
export const STATUS_LIST = [
{ name: "正常", id: 1 },
{ name: "关停", id: 2 },
];

View File

@ -1,14 +1,41 @@
/**
* 匹配中国手机号码可包含国家代码86支持各种运营商号段
*/
export const PHONE =
/^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-7|9])|(?:5[0-3|5-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1|8|9]))\d{8}$/;
/**
* 匹配中国大陆的统一社会信用代码
*/
export const UNIFIED_SOCIAL_CREDIT_CODE =
/^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
/**
* 匹配中国大陆的身份证号码包括15位和18位号码并验证最后一位校验码
*/
export const ID_NUMBER =
/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/;
/**
* 匹配中国大陆的移动电话号码不包含国家代码
*/
export const MOBILE_PHONE =
/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/;
/**
* 匹配浮点数允许整数一位或两位小数以及零的情况
*/
export const FLOATING_POINT_NUMBER =
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/;
/**
* 匹配中国大陆的车牌号码
*/
export const LICENSE_PLATE_NUMBER =
/^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1})$/;
/**
* 匹配强密码要求至少8个字符包含大小写字母数字和特殊字符
*/
export const STRONG_PASSWORD =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{8,}$/;

View File

@ -0,0 +1,214 @@
<template>
<template v-for="(option, index) in options" :key="option.key || index">
<template v-if="!option.hidden">
<el-col
v-if="!option.root"
v-show="!collapse || index < 3"
:span="option.span || span || 12"
>
<el-form-item
:label="option.label"
:label-width="option.labelWidth"
:prop="option.key"
:rules="option.rules"
>
<slot :name="option.key">
<el-input
v-if="option.type === 'input' || !option.type"
v-model="modelValue[option.key]"
:placeholder="'请输入' + option.label"
v-bind="fnGetProps(option)"
/>
<el-input
v-else-if="option.type === 'textarea'"
v-model="modelValue[option.key]"
:placeholder="'请输入' + option.label"
type="textarea"
:autosize="{ minRows: 3 }"
v-bind="fnGetProps(option)"
/>
<el-input-number
v-else-if="
option.type === 'inputNumber' || option.type === 'number'
"
v-model="modelValue[option.key]"
:placeholder="'请输入' + option.label"
v-bind="fnGetProps(option)"
/>
<el-select
v-else-if="option.type === 'select'"
v-model="modelValue[option.key]"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
:multiple="option.multiple"
:collapse-tags="option.multiple"
>
<el-option
v-for="item in unref(option.options)"
:key="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
:label="item[option.labelKey] || item['name']"
:value="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
/>
</el-select>
<el-checkbox-group
v-else-if="option.type === 'checkbox'"
v-model="modelValue[option.key]"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
>
<el-checkbox
v-for="item in unref(option.options)"
:key="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
:value="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
>
{{ item[option.labelKey] || item["name"] }}
</el-checkbox>
</el-checkbox-group>
<el-radio-group
v-else-if="option.type === 'radio'"
v-model="modelValue[option.key]"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
>
<el-radio
v-for="item in unref(option.options)"
:key="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
:value="
item[option.valueKey] || item['dictionariesId'] || item['id']
"
>
{{ item[option.labelKey] || item["name"] }}
</el-radio>
</el-radio-group>
<el-date-picker
v-else-if="option.type === 'date'"
v-model="modelValue[option.key]"
value-format="YYYY-MM-DD"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
/>
<el-date-picker
v-else-if="option.type === 'dateMonth'"
v-model="modelValue[option.key]"
type="month"
value-format="YYYY-MM"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
/>
<el-date-picker
v-else-if="option.type === 'dateYear'"
v-model="modelValue[option.key]"
type="year"
value-format="YYYY"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
/>
<el-date-picker
v-else-if="option.type === 'daterange'"
v-model="modelValue[option.key]"
type="daterange"
value-format="YYYY-MM-DD"
:start-placeholder="'请选择开始' + option.label"
:end-placeholder="'请选择结束' + option.label"
v-bind="fnGetProps(option)"
/>
<el-date-picker
v-else-if="option.type === 'datetime'"
v-model="modelValue[option.key]"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="'请选择' + option.label"
v-bind="fnGetProps(option)"
/>
<el-date-picker
v-else-if="option.type === 'datetimerange'"
v-model="modelValue[option.key]"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
:start-placeholder="'请选择开始' + option.label"
:end-placeholder="'请选择结束' + option.label"
:default-time="[
new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59),
]"
v-bind="fnGetProps(option)"
/>
<component
:is="option.type"
v-else
v-model="modelValue[option.key]"
v-bind="fnGetProps(option)"
/>
</slot>
</el-form-item>
</el-col>
<template v-if="option.root">
<slot :name="option.key">
<component
:is="option.type"
v-model="modelValue[option.key]"
v-bind="fnGetProps(option)"
/>
</slot>
</template>
</template>
</template>
</template>
<script setup>
import { omit } from "lodash-es";
import { unref } from "vue";
defineProps({
options: { type: Array, required: true },
span: { type: Number, default: 0 },
collapse: { type: Boolean, default: false },
});
const modelValue = defineModel({ type: Object, required: true });
const rootProps = [
"label", //
"key", // formkey
"type", // input
"span", // 12
"hidden", //
"rules", //
"options", // selectradiocheckbox
"valueKey", // selectradiocheckbox value
"labelKey", // selectradiocheckbox label
"attrs", //
"root", // el-col
"labelWidth", // label
// ... // attrs使attrs
];
const fnGetProps = (option) => {
if (option.attrs) return option.attrs;
return omit(option, rootProps);
};
/**
* type 组件映射关系
* 空和input 组件映射为el-input
* textarea 组件映射为el-input的textarea
* inputNumber和number 组件映射为el-input-number
* select 映射为el-select
* radio 映射为el-radio-group
* checkbox 映射为el-checkbox-group
* date 映射为el-date-picker日期格式为YYYY-MM-DD
* dateMonth 映射为el-date-picker日期格式为YYYY-MM
* dateYear 映射为el-date-picker日期格式为YYYY
* daterange 映射为el-date-picker日期格式为YYYY-MM-DD
* datetime 映射为el-date-picker日期格式为YYYY-MM-DD HH:mm:ss
* datetimerange 映射为el-date-picker日期格式为YYYY-MM-DD HH:mm:ss
*/
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,66 @@
<template>
<el-form
ref="formRef"
:model="modelValue"
:rules="rules"
:label-width="labelWidth"
:label-position="labelPosition"
>
<el-row :gutter="gutter">
<form-items-renderer
v-if="options && options.length"
v-model="modelValue"
:options="options"
:span="span"
>
<template v-for="(_, name) in slots" :key="name" #[name]="slotProps">
<slot :name="name" v-bind="slotProps" />
</template>
</form-items-renderer>
</el-row>
</el-form>
</template>
<script setup>
import { useSlots, useTemplateRef } from "vue";
import FormItemsRenderer from "@/components/form_builder/form_items_renderer.vue";
const slots = useSlots();
defineOptions({
name: "AppFormBuilder",
});
defineProps({
options: {
type: Array,
required: true,
},
rules: {
type: Object,
default: () => ({}),
},
gutter: {
type: Number,
default: 24,
},
span: {
type: Number,
default: 0,
},
labelWidth: {
type: [Number, String],
default: "100px",
},
labelPosition: {
type: String,
default: "right",
},
});
const modelValue = defineModel({ type: Object, required: true });
const formRef = useTemplateRef("formRef");
defineExpose({
validate: (callback) => formRef.value.validate(callback),
resetFields: () => formRef.value.resetFields(),
});
</script>
<style scoped lang="scss"></style>

View File

@ -5,7 +5,21 @@
@submit.prevent="emits('submit')"
>
<el-row :class="className">
<slot :collapse="collapse"></slot>
<template v-if="options && options.length">
<form-items-renderer
v-model="modelValue"
:options="options"
:span="6"
:collapse="collapse"
>
<template v-for="(_, name) in slots" :key="name" #[name]="slotProps">
<slot :name="name" v-bind="slotProps" />
</template>
</form-items-renderer>
</template>
<template v-else>
<slot :collapse="collapse"></slot>
</template>
<el-col :span="showCollapseButton ? (collapse ? 6 : span) : span">
<el-form-item label-width="10px" class="end">
<el-button type="primary" native-type="submit"> 搜索 </el-button>
@ -46,19 +60,24 @@
</template>
<script setup>
import { onMounted, ref, useSlots } from "vue";
import { nextTick, onMounted, ref, useSlots, watch } from "vue";
import { uniqueId } from "lodash-es";
import { ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import FormItemsRenderer from "@/components/form_builder/form_items_renderer.vue";
const slots = useSlots();
defineOptions({
name: "AppSearch",
});
defineProps({
const props = defineProps({
labelWidth: {
type: String,
default: "100px",
},
options: {
type: Array,
default: undefined,
},
});
const modelValue = defineModel({ type: Object, required: true });
const emits = defineEmits(["submit"]);
@ -70,11 +89,18 @@ const changeSearchCollapse = () => {
collapse.value = !collapse.value;
};
onMounted(() => {
const colEl = document.querySelectorAll(`.${className.value} .el-col`);
const colElLength = colEl.length;
const excludeLast = colElLength - (slots.button ? 2 : 1);
span.value = { 0: 24, 1: 18, 2: 12, 3: 6 }[excludeLast % 4];
showCollapseButton.value = excludeLast > 3;
watch(
() => props.options,
async () => {
await nextTick();
const colEl = document.querySelectorAll(`.${className.value} .el-col`);
const colElLength = colEl.length;
const excludeLast = colElLength - (slots.button ? 2 : 1);
span.value = { 0: 24, 1: 18, 2: 12, 3: 6 }[excludeLast % 4];
showCollapseButton.value = excludeLast > 3;
},
{ immediate: true }
);
});
</script>

View File

@ -69,86 +69,31 @@ defineOptions({
name: "AppTable",
});
const props = defineProps({
data: {
type: Array,
required: true,
},
showPagination: {
type: Boolean,
default: true,
},
showIndex: {
type: Boolean,
default: true,
},
showSelection: {
type: Boolean,
default: false,
},
stripe: {
type: Boolean,
default: true,
},
border: {
type: Boolean,
default: true,
},
showHeader: {
type: Boolean,
default: true,
},
highlightCurrentRow: {
type: Boolean,
default: false,
},
showSummary: {
type: Boolean,
default: false,
},
defaultExpandAll: {
type: Boolean,
default: false,
},
rowKey: {
type: [String, Function],
},
maxHeight: {
type: [String, Number],
},
height: {
type: [String, Number],
},
rowClassName: {
type: Function,
},
rowStyle: {
type: Function,
},
summaryMethod: {
type: Function,
},
spanMethod: {
type: Function,
},
selectable: {
type: Function,
},
data: { type: Array, required: true },
showPagination: { type: Boolean, default: true },
showIndex: { type: Boolean, default: true },
showSelection: { type: Boolean, default: false },
stripe: { type: Boolean, default: true },
border: { type: Boolean, default: true },
showHeader: { type: Boolean, default: true },
highlightCurrentRow: { type: Boolean, default: false },
showSummary: { type: Boolean, default: false },
defaultExpandAll: { type: Boolean, default: false },
rowKey: { type: [String, Function] },
maxHeight: { type: [String, Number] },
height: { type: [String, Number] },
rowClassName: { type: Function },
rowStyle: { type: Function },
summaryMethod: { type: Function },
spanMethod: { type: Function },
selectable: { type: Function },
treeProps: {
type: Object,
default: () => ({ hasChildren: "hasChildren", children: "children" }),
},
headerCellStyle: {
type: Object,
default: () => ({}),
},
cellStyle: {
type: [Object, Function],
default: () => ({}),
},
showOverflowTooltip: {
type: Boolean,
default: true,
},
headerCellStyle: { type: Object, default: () => ({}) },
cellStyle: { type: [Object, Function], default: () => ({}) },
showOverflowTooltip: { type: Boolean, default: true },
});
const pagination = defineModel("pagination", {
type: Object,

View File

@ -0,0 +1,29 @@
import {
getDataDictionariesList,
getDepartmentTree,
} from "@/request/data_dictionary.js";
// 部门
export const appFnGetDepartmentTree = async (params) => {
const { deptTree } = await getDepartmentTree(params);
return deptTree;
};
// 无法确定parentId的数据字典
export const appFnGetDataDictionary = async (parentId) => {
const { dictionariesList } = await getDataDictionariesList(parentId);
return dictionariesList;
};
// 导航栏
export const appFnGetMenuNavList = async () => {
const { dictionariesList } = await getDataDictionariesList({
parentId: "7b2cf146798280ecf8f4dfbf8c4f59d8",
});
return dictionariesList;
};
// 获取行业
export const appFnGetSectorList = async () => {
const { dictionariesList } = await getDataDictionariesList({
parentId: "f2598ba72e864eadabf0ca4b664d26b9",
});
return dictionariesList;
};

View File

@ -22,11 +22,11 @@ const verificationParameter = (api, options) => {
)
throw new Error("options.callback必须是一个函数");
if (
options.beforeGetData &&
getDataType(options.beforeGetData) !== "Function" &&
getDataType(options.beforeGetData) !== "AsyncFunction"
options.before &&
getDataType(options.before) !== "Function" &&
getDataType(options.before) !== "AsyncFunction"
)
throw new Error("options.beforeGetData必须是一个函数");
throw new Error("options.before必须是一个函数");
if (
options.defaultSearchForm &&
getDataType(options.defaultSearchForm) !== "Object"
@ -53,6 +53,8 @@ const verificationParameter = (api, options) => {
getDataType(options.tabsActiveName) !== "String"
)
throw new Error("options.tabsActiveName必须是一个字符串");
if (options.apiType && getDataType(options.apiType) !== "String")
throw new Error("options.apiType必须是一个字符串");
};
const getOptionParams = (params) => {
@ -65,11 +67,20 @@ const getOptionParams = (params) => {
}
};
const getBeforeParams = (before, params) => {
if (before) {
const paramsValue = before(JSON.parse(JSON.stringify(params)));
if (getDataType(paramsValue) !== "Object")
throw new Error("options.before必须存在返回值并且必须是一个对象");
else return paramsValue;
}
};
/**
* @param {Function} api - 接口请求函数用于获取列表数据
* @param {Object} [options] - 配置项可选
* @param {Function} [options.callback] - 数据获取完成后的回调函数
* @param {Function} [options.beforeGetData] - 请求前执行的钩子函数
* @param {Function} [options.before] - 请求前执行的钩子函数必须返回一个对象
* @param {Object|Function} [options.params] - 额外的请求参数可以是对象或返回对象的函数
* @param {Object} [options.defaultSearchForm] - 搜索表单默认值
* @param {boolean} [options.immediate=true] - 是否立即执行接口请求
@ -78,6 +89,7 @@ const getOptionParams = (params) => {
* @param {boolean} [options.clearSelection=true] - 调用 resetPagination 时是否清空表格选择项
* @param {boolean} [options.isStorageQueryCriteria=true] - 是否缓存当前查询条件
* @param {string} [options.tabsActiveName] - 当存在 Tabs 组件时当前激活的 tab 名称用于区分查询缓存
* @param {string} [options.apiType] - 多个路由指向一个页面时用于区分调用的api名称
* @return {Object} 返回对象包含以下属性list 表格数据pagination 分页数据searchForm 搜索表单数据tableRef 表格实例getData 获取数据函数resetPagination 重置分页函数
* @returns {Object} 返回对象包含以下属性
* - [list] {Ref<Array>} 表格数据使用 Vue ref 包裹的数组
@ -101,27 +113,26 @@ export default function useListData(api, options = {}) {
const queryCriteria = getQueryCriteria();
const pagination = ref(queryCriteria.pagination || defaultPagination);
const searchForm = ref(JSON.parse(JSON.stringify(defaultSearchForm)));
let beforeGetDataParams = {};
const tableRef = ref(null);
const getData = async () => {
if (options.beforeGetData) {
beforeGetDataParams = JSON.parse(
JSON.stringify(queryCriteria.searchForm || searchForm.value)
);
options.beforeGetData(beforeGetDataParams);
}
const resData = await api({
...(usePagination
? {
curPage: pagination.value.currentPage,
limit: pagination.value.pageSize,
}
: {}),
...searchForm.value,
...beforeGetDataParams,
...(queryCriteria.searchForm || {}),
...(getOptionParams(options.params) || {}),
});
const resData = await api(
{
...(usePagination
? {
curPage: pagination.value.currentPage,
limit: pagination.value.pageSize,
}
: {}),
...searchForm.value,
...(queryCriteria.searchForm || {}),
...(getBeforeParams(
options.before,
queryCriteria.searchForm || searchForm.value
) || {}),
...(getOptionParams(options.params) || {}),
},
options.apiType ? options.apiType : undefined
);
if (usePagination) {
if (resData.page[key]) list.value = resData.page[key];
else list.value = resData[key] || resData.varList;

View File

@ -12,3 +12,6 @@ export const getDataDictionariesListTree = (params) =>
// 部门树
export const getDepartmentListTree = (params) =>
getRequest("/sysdepartment/listTree", params);
// 属地
export const getAreaListTree = (params) =>
postRequest("/sys/dictionaries/area", params);

View File

@ -0,0 +1,17 @@
import { postRequest } from "./axios";
// 获取企业信息-分页
export const getDataList = (params, apiType) =>
postRequest(`/${apiType}/listPage`, params);
// 获取记录信息-分页
export const getRecordList = (params, apiType) =>
postRequest(`/${apiType}/record/listPage`, params);
// 记录信息 - 删除
export const setRecordDelete = (params, apiType) =>
postRequest(`/${apiType}/record/delete`, params);
// 记录信息 - 详情
export const getRecordDetail = (params, apiType) =>
postRequest(`/${apiType}/record/detail`, params);

81
src/request/database.js Normal file
View File

@ -0,0 +1,81 @@
import { postRequest } from "./axios";
// 获取上级平台管理信息-分页
export const getBusThirdPlatformList = (params) =>
postRequest("/busThirdPlatform/listPage", params);
// 上级平台管理信息-保存
export const setBusThirdPlatformAdd = (params) =>
postRequest("/busThirdPlatform/save", params);
// 上级平台管理信息-修改
export const setBusThirdPlatformUpdate = (params) =>
postRequest("/busThirdPlatform/update", params);
// 上级平台管理信息 - 删除
export const setBusThirdPlatformDelete = (params) =>
postRequest("/busThirdPlatform/delete", params);
// 上级平台管理信息 - 详情
export const getBusThirdPlatform = (params) =>
postRequest("/busThirdPlatform/detail", params);
// 数据目录项
export const getBusDataItemsMenuList = (params) =>
postRequest("/busDataItems/menuList", params);
// 根据菜单id查询所有数据项
export const getFindByMenuId = (params) =>
postRequest("/busDataItems/findByMenuId", params);
// 数据项保存
export const setDataSave = (params) =>
postRequest("/busThirdPlatform/dataSave", params);
// 获取服务平台管理信息-分页
export const getBusServicePlatformList = (params) =>
postRequest("/busServicePlatform/listPage", params);
// 服务平台管理信息-保存
export const setBusServicePlatformAdd = (params) =>
postRequest("/busServicePlatform/save", params);
// 服务平台管理信息-修改
export const setBusServicePlatformUpdate = (params) =>
postRequest("/busServicePlatform/update", params);
// 服务平台管理信息 - 删除
export const setBusServicePlatformDelete = (params) =>
postRequest("/busServicePlatform/delete", params);
// 服务平台管理信息 - 详情
export const getBusServicePlatform = (params) =>
postRequest("/busServicePlatform/detail", params);
// 获取所有上级平台
export const getBusThirdPlatformListAll = (params) =>
postRequest("/busThirdPlatform/listAll", params);
// 获取对接企业管理信息-分页
export const getBusCompanyInfoList = (params) =>
postRequest("/busCompanyInfo/listPage", params);
// 对接企业管理信息-保存
export const setBusCompanyInfoAdd = (params) =>
postRequest("/busCompanyInfo/save", params);
// 对接企业管理信息-修改
export const setBusCompanyInfoUpdate = (params) =>
postRequest("/busCompanyInfo/update", params);
// 对接企业管理信息 - 删除
export const setBusCompanyInfoDelete = (params) =>
postRequest("/busCompanyInfo/delete", params);
// 对接企业管理信息 - 详情
export const getBusCompanyInfo = (params) =>
postRequest("/busCompanyInfo/detail", params);
// 获取所有服务平台
export const getBusServicePlatformListAll = (params) =>
postRequest("/busServicePlatform/listAll", params);

View File

@ -0,0 +1,93 @@
<template>
<div>
<app-search v-model="searchForm" :options @submit="resetPagination" />
<app-table ref="tableRef" v-model:pagination="pagination" :data="list">
<el-table-column prop="servicePlatformName" label="所在平台名称" />
<el-table-column prop="companyName" label="企业名称" />
<el-table-column prop="sectorName" label="所属行业" />
<el-table-column prop="thirdPlatformName" label="对接上级平台">
</el-table-column>
<el-table-column prop="pushCount" label="推送记录" />
<el-table-column prop="pushStatus" label="上级平台接口状态">
<template #default="{ row }">
{{ translationStatus(row.pushStatus, pushOptions) }}
</template>
</el-table-column>
<el-table-column prop="receiveStatus" label="服务平台接口状态">
<template #default="{ row }">
{{ translationStatus(row.receiveStatus, receiveOptions) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: `/data_directory/records`,
query: {
thirdPlatformId: row.thirdPlatformId,
companyId: row.companyId,
servicePlatformId: row.servicePlatformId,
apiType: apiType,
},
})
"
>
推进记录信息
</el-button>
</template>
</el-table-column>
</app-table>
</div>
</template>
<script setup>
import { getDataList } from "@/request/data_directory.js";
import useListData from "@/hooks/useListData.js";
import AppSearch from "@/components/search/index.vue";
import AppTable from "@/components/table/index.vue";
import { translationStatus } from "@/assets/js/utils.js";
import { useRouter } from "vue-router";
const router = useRouter();
const apiType = defineModel("apiType", {
type: String,
required: true,
default: "dataRiskEvents",
});
const { list, pagination, searchForm, resetPagination, tableRef } = useListData(
getDataList,
{
apiType: apiType.value,
}
);
const pushOptions = [
{ id: "1", name: "未推送" },
{ id: "2", name: "定时推送" },
{ id: "3", name: "推送成功" },
{ id: "4", name: "重试中" },
{ id: "5", name: "推送失败" },
];
const receiveOptions = [
{ id: "1", name: "接收正常" },
{ id: "2", name: "接收异常" },
];
const options = [
{
key: "pushStatus",
label: "推送状态",
type: "select",
options: pushOptions,
},
{
key: "receiveStatus",
label: "接收状态",
type: "select",
options: receiveOptions,
},
];
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,107 @@
<template>
<div>
<app-search v-model="searchForm" :options @submit="resetPagination" />
<app-table
ref="tableRef"
v-model:pagination="pagination"
:data="list"
@get-data="getData"
>
<el-table-column prop="servicePlatformName" label="所在平台名称" />
<el-table-column prop="businessType" label="数据类型" />
<el-table-column prop="receiveTime" label="上传时间" />
<el-table-column prop="receiveStatus" label="数据接收状态">
<template #default="{ row }">
{{ translationStatus(row.receiveStatus, receiveOptions) }}
</template>
</el-table-column>
<el-table-column prop="thirdPlatformName" label="上级平台名称" />
<el-table-column prop="pushTime" label="推送时间" />
<el-table-column prop="pushStatus" label="上报数据状态">
<template #default="{ row }">
{{ translationStatus(row.pushStatus, pushOptions) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button
type="primary"
text
link
@click="
router.push({
path: `/data_directory/records_detail`,
query: {
id: row.id,
apiType: route.query.apiType,
},
})
"
>
详情信息
</el-button>
<el-button type="danger" text link @click="fnDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</app-table>
</div>
</template>
<script setup>
import { getRecordList, setRecordDelete } from "@/request/data_directory.js";
import useListData from "@/hooks/useListData.js";
import AppSearch from "@/components/search/index.vue";
import AppTable from "@/components/table/index.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { translationStatus } from "@/assets/js/utils.js";
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const { list, pagination, searchForm, getData, resetPagination, tableRef } =
useListData(getRecordList, {
params: () => ({
thirdPlatformId: route.query.thirdPlatformId,
companyId: route.query.companyId,
servicePlatformId: route.query.servicePlatformId,
}),
apiType: route.query.apiType,
});
const pushOptions = [
{ id: "1", name: "未推送" },
{ id: "2", name: "定时推送" },
{ id: "3", name: "推送成功" },
{ id: "4", name: "重试中" },
{ id: "5", name: "推送失败" },
];
const receiveOptions = [
{ id: "1", name: "接收正常" },
{ id: "2", name: "接收异常" },
];
const options = [
{
key: "pushStatus",
label: "推送状态",
type: "select",
options: pushOptions,
},
{
key: "receiveStatus",
label: "接收状态",
type: "select",
options: receiveOptions,
},
];
const fnDelete = async (id) => {
await ElMessageBox.confirm("确定要删除吗?", {
type: "warning",
});
await setRecordDelete({ id }, route.params.apiType);
ElMessage.success("删除成功");
resetPagination();
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,105 @@
<template>
<div>
<el-row :gutter="40">
<el-col :span="12"
><div class="grid-content">
<h4 class="mb-10">请求信息</h4>
<template v-if="isJsonRequest">
{
<div
class="mt-2 pl-18"
v-for="(value, key) in requestData"
:key="key"
>
<span class="key-contanier"> {{ key }}</span> :
<span class="value-contanier">{{ value }}</span>
</div>
}
</template>
<div v-else class="text-red">{{ requestData }}</div>
</div></el-col
>
<el-col :span="12">
<div class="grid-content">
<h4 class="mb-10">响应信息</h4>
<template v-if="isJsonResponse">
{
<div
class="mt-2 pl-18"
v-for="(value, key) in responseData"
:key="key"
>
<span class="key-contanier"> {{ key }}</span> :
<span class="value-contanier">{{ value }}</span>
</div>
}
</template>
<div v-else class="text-red">{{ responseData }}</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref } from "vue";
import { getRecordDetail } from "@/request/data_directory.js";
import { useRoute } from "vue-router";
const route = useRoute();
const { data } = await getRecordDetail(
{
id: route.query.id,
},
route.query.apiType
);
const { request, response } = data;
const isJsonRequest = ref(false);
const isJsonResponse = ref(false);
const fnJsonParse = (params, type) => {
if (params === null) {
type === "1"
? (isJsonRequest.value = false)
: (isJsonResponse.value = false);
return params;
}
try {
const obj = JSON.parse(params);
type === "1" ? (isJsonRequest.value = true) : (isJsonResponse.value = true);
return obj;
} catch (error) {
type === "1"
? (isJsonRequest.value = false)
: (isJsonResponse.value = false);
return params;
}
};
const requestData = fnJsonParse(request, "1");
const responseData = fnJsonParse(response, "2");
</script>
<style lang="scss" scoped>
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
border: 1px solid #dcdfe6;
padding: 20px;
word-break: break-all;
}
.key-contanier {
color: #92278f;
font-weight: bold;
}
.value-contanier {
color: #3ab54a;
font-weight: bold;
}
</style>

View File

@ -0,0 +1,9 @@
<template>
<index-page api-type="dataRiskUnit" />
</template>
<script setup>
import indexPage from "../data_risk_events/index.vue";
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,452 @@
<template>
<el-dialog v-model="visible" :title="title" :before-close="fnClose">
<el-form
ref="formRef"
:rules="rules"
label-width="220px"
:model="form"
label-position="right"
>
<el-divider content-position="left">企业基础信息</el-divider>
<el-row :gutter="24">
<form-items-renderer v-model="form" :options="baseInfoOptions">
<template #area>
<el-cascader
v-model="form.area"
:options="dictionariesList"
:props="{
value: 'dictionaryId',
label: 'name',
children: 'list',
}"
></el-cascader>
</template>
<template #sectorId>
<app-cascader
ref="sectorIdRef"
id="f2598ba72e864eadabf0ca4b664d26b9"
value="dictionaryId"
v-model="form.sectorId"
:check-strictly="false"
></app-cascader>
</template>
<template #address>
<el-input v-model="form.address" disabled>
<template #append
><el-button type="primary" @click="handleMap"
>定位</el-button
></template
></el-input
>
</template>
</form-items-renderer>
</el-row>
<el-divider content-position="left">企业属性信息</el-divider>
<el-row :gutter="24">
<form-items-renderer v-model="form" :options="companyPropsOptions">
</form-items-renderer>
</el-row>
</el-form>
<el-divider content-position="left">对接上级平台信息</el-divider>
<div class="add-btn mb-10">
<el-button type="primary" @click="fnAddThirdList()"
>添加上级平台</el-button
>
</div>
<el-form ref="formRef1" label-width="220px" label-position="right">
<el-row :gutter="24" v-for="(item, index) in thirdList" :key="index">
<el-divider></el-divider>
<el-col :span="12">
<el-form-item label="上级对接平台">
<el-select
:disabled="thirdListOptions.length === 0"
v-model="item.thirdPlatformId"
placeholder="请选择"
>
<el-option
v-for="item1 in thirdListOptions"
:key="item1.id"
:label="item1.platformName"
:value="item1.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="上级平台编码" prop="superPlatformId">
<el-input v-model="item.thirdPlatformCode"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重大危险源编码" prop="majorHazardCode">
<el-input v-model="item.majorHazardCode">
<!-- TODO 功能待定 -->
<template #append
><el-button type="primary">添加编码</el-button></template
></el-input
>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="密钥" prop="accessKey">
<el-input v-model="item.accessKey"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="公钥" prop="rsaPublicKey">
<el-input v-model="item.rsaPublicKey"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="对接URL" prop="url">
<el-input v-model="item.url"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="对接IV" prop="iv">
<el-input v-model="item.iv"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业CODE" prop="code">
<el-input v-model="item.code"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业APPID" prop="appid">
<el-input v-model="item.appid"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业SECRET" prop="secret">
<el-input v-model="item.secret"></el-input>
</el-form-item>
</el-col>
<el-col class="add-btn" :span="24" v-if="index > 0"
><el-button type="danger" @click="fnReduceThirdList(index)"
>删除</el-button
></el-col
>
</el-row>
</el-form>
<template #footer>
<el-button type="primary" @click="fnSubmit"></el-button>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
<app-map
v-model:visible="visibleMap"
v-model:longitude="form.longitude"
v-model:latitude="form.latitude"
@submit="fnSubmitMap"
></app-map>
</template>
<script setup>
import useForm from "@/hooks/useForm.js";
import { ref, watch } from "vue";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import FormItemsRenderer from "@/components/form_builder/form_items_renderer.vue";
import {
setBusCompanyInfoAdd,
setBusCompanyInfoUpdate,
getBusCompanyInfo,
getBusServicePlatformListAll,
} from "@/request/database.js";
import { STATUS_LIST, WHETHER_LIST } from "@/assets/js/constant.js";
import { getAreaListTree } from "@/request/data_dictionary.js";
import AppCascader from "@/components/cascader/index.vue";
import AppMap from "@/components/map/map.vue";
import { UNIFIED_SOCIAL_CREDIT_CODE } from "@/assets/js/regular.js";
const { dictionariesList } = await getAreaListTree();
const visible = defineModel("visible", { type: Boolean, required: true });
const props = defineProps({
corpInfoId: { type: Number, required: false },
title: { type: String, required: true },
});
const { data: servicePlatformList } = await getBusServicePlatformListAll();
const emits = defineEmits(["getData"]);
const { formRef, validate, reset } = useForm();
// const { formRef, reset } = useForm();
const form = ref({
companyName: "", //
code: "", //
area: [], //
sectorId: [], //
address: "",
latitude: "", //
longitude: "", //
companyStatus: "", //
companyAddress: "", //
companyContacts: "", //
companyMobile: "", //
servicePlatformId: "", //
isMajorHazard: 0, //
isOpenMajorHazard: 0, //
isKeyProcess: 0, //
isOpenKeyProcess: 0, //
isSpecialInspection: 0, //
isOpenSpecialInspection: 0, //
isDustExplosion: 0, //
});
const rules = {
companyName: [
{ required: true, message: "企业名称不能为空", trigger: "blur" },
],
code: [
{ required: true, message: "统一社会信用代码不能为空", trigger: "blur" },
{
pattern: UNIFIED_SOCIAL_CREDIT_CODE,
message: "请输入正确的统一社会信用代码",
},
],
sectorId: [
{ required: true, message: "所属行业不能为空", trigger: "change" },
],
companyStatus: [
{ required: true, message: "企业状态不能为空", trigger: "change" },
],
companyContacts: [
{ required: true, message: "主要负责人不能为空", trigger: "blur" },
],
companyMobile: [
{ required: true, message: "负责人电话", trigger: "blur" },
{ min: 11, max: 13, message: "请输入手机号码或座机号", trigger: "blur" },
{
pattern:
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$|^0\d{2,3}-?\d{7,8}$/,
message: "请输入正确的手机号码或座机号(例:010-12345678)",
},
],
servicePlatformId: [
{ required: true, message: "服务平台不能为空", trigger: "change" },
],
isMajorHazard: [
{ required: true, message: "是否重大危险源企业", trigger: "change" },
],
isOpenMajorHazard: [
{
required: true,
message: "是否开启重大危险源数据推送",
trigger: "change",
},
],
isKeyProcess: [
{ required: true, message: "是否重点工艺企业", trigger: "change" },
],
isOpenKeyProcess: [
{
required: true,
message: "是否开启重点工艺企业数据推送",
trigger: "change",
},
],
isSpecialInspection: [
{ required: true, message: "是否重点专项检查企业", trigger: "change" },
],
isOpenSpecialInspection: [
{
required: true,
message: "是否开启重点专项检查企业数据推送",
trigger: "change",
},
],
isDustExplosion: [
{ required: true, message: "是否粉尘涉爆企业", trigger: "change" },
],
};
const baseInfoOptions = [
{ key: "companyName", label: "企业名称" },
{ key: "code", label: "统一社会信用代码" },
{ key: "area", label: "属地" },
{ key: "sectorId", label: "所属行业" },
{ key: "address", label: "经营地址" },
{
key: "companyStatus",
label: "企业状态",
type: "select",
options: STATUS_LIST,
},
{ key: "companyAddress", label: "地理位置" },
{ key: "companyContacts", label: "主要负责人" },
{ key: "companyMobile", label: "负责人电话" },
{
key: "servicePlatformId",
label: "服务平台",
type: "select",
valueKey: "id",
labelKey: "serviceName",
options: servicePlatformList,
},
];
const companyPropsOptions = [
{
key: "isMajorHazard",
label: "是否重大危险源企业",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isOpenMajorHazard",
label: "是否开启重大危险源数据推送",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isKeyProcess",
label: "是否重点工艺企业",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isOpenKeyProcess",
label: "是否开启重点工艺企业数据推送",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isSpecialInspection",
label: "是否重点专项检查企业",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isOpenSpecialInspection",
label: "是否开启专项检查数据推送",
type: "radio",
options: WHETHER_LIST,
},
{
key: "isDustExplosion",
label: "是否粉尘涉爆企业",
type: "radio",
options: WHETHER_LIST,
},
];
const thirdListOptions = ref([]);
watch(
() => form.value.servicePlatformId,
(val) => {
thirdListOptions.value = servicePlatformList.filter(
(item) => item.id === val
)[0].thirdList;
}
);
const fnGetData = async () => {
if (!props.corpInfoId) return;
const { data } = await getBusCompanyInfo({ id: props.corpInfoId });
form.value = data;
form.value.area = [form.value.province, form.value.city, form.value.county];
form.value.sectorId = data.sectorId.split(",");
form.value.address = `${form.value.longitude}-${form.value.latitude}`;
thirdList.value = data.thirdList;
};
fnGetData();
const fnClose = () => {
reset();
visible.value = false;
};
const thirdList = ref([
{
thirdPlatformId: "",
thirdPlatformCode: "",
majorHazardCode: "",
accessKey: "",
rsaPublicKey: "",
url: "",
iv: "",
code: "",
appid: "",
secret: "",
},
]);
const fnAddThirdList = () => {
thirdList.value.push({
thirdPlatformId: "",
thirdPlatformCode: "",
majorHazardCode: "",
accessKey: "",
rsaPublicKey: "",
url: "",
iv: "",
code: "",
appid: "",
secret: "",
});
};
const fnReduceThirdList = (index) => {
thirdList.value.splice(index, 1);
};
const visibleMap = ref(false);
const handleMap = () => {
visibleMap.value = true;
};
const fnSubmitMap = () => {
form.value.address = `${form.value.longitude}-${form.value.latitude}`;
};
const checkThirdListItem = () => {
thirdList.value.forEach((item) => {
if (
!item.thirdPlatformId ||
!item.thirdPlatformCode ||
!item.majorHazardCode
) {
ElMessage.error("上级对接平台、企业编码、重大危险源编码不能为空");
return false;
}
});
return true;
};
const sectorIdRef = ref("");
const fnSubmit = debounce(
1000,
async () => {
// setBusCompanyInfoAdd();
await validate();
const ischeck = checkThirdListItem();
if (ischeck) {
const sectorName = sectorIdRef.value.getCheckedNodes();
const [province = "", city = "", county = ""] = form.value.area;
const sectorId = form.value.sectorId.join(",");
const params = {
...form.value,
sectorId,
province,
city,
county,
sectorName,
thirdList: thirdList.value,
};
!props.corpInfoId
? setBusCompanyInfoAdd(params)
: setBusCompanyInfoUpdate(params);
ElMessage.success("操作成功");
emits("getData");
visible.value = false;
}
},
{ atBegin: true }
);
</script>
<style scoped lang="scss">
.add-btn {
display: flex;
justify-content: end;
}
:deep {
.el-input-group__append button.el-button {
background-color: #409eff;
color: white;
}
}
</style>

View File

@ -0,0 +1,112 @@
<template>
<div>
<app-search v-model="searchForm" :options @submit="resetPagination" />
<el-button type="primary" class="mb-10" @click="fnAddorEdit('add')">
新增平台
</el-button>
<app-table
ref="tableRef"
v-model:pagination="pagination"
:data="list"
@get-data="getData"
>
<el-table-column prop="serviceName" label="所在平台名称" />
<el-table-column prop="companyName" label="企业名称" />
<el-table-column prop="sectorName" label="所属行业" />
<el-table-column prop="thirdList" label="对接上级平台">
<template #default="{ row }">
{{ row.thirdList.map((item) => item.platformName).join("") }}
</template>
</el-table-column>
<el-table-column prop="runTime" label="运行时间" />
<el-table-column prop="companyStatus" label="状态">
<template #default="{ row }">
{{ translationStatus(row.companyStatus, STATUS_LIST) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button type="primary" text link> 查看 </el-button>
<el-button type="primary" text link @click="fnAddorEdit('edit', row)">
编辑
</el-button>
<el-button type="danger" text link @click="fnDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</app-table>
<edit-dialog
v-if="visible"
v-model:visible="visible"
:title="title"
:corp-info-id="corpInfoId"
@get-data="resetPagination"
></edit-dialog>
</div>
</template>
<script setup>
import { ref } from "vue";
import {
getBusCompanyInfoList,
setBusCompanyInfoDelete,
getBusServicePlatformListAll,
} from "@/request/database.js";
import useListData from "@/hooks/useListData.js";
import AppSearch from "@/components/search/index.vue";
import AppTable from "@/components/table/index.vue";
import editDialog from "./components/editDialog.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { translationStatus } from "@/assets/js/utils.js";
import { STATUS_LIST } from "@/assets/js/constant.js";
const corpInfoId = ref(null);
const { data: serveOptions } = await getBusServicePlatformListAll();
const { list, pagination, searchForm, getData, resetPagination, tableRef } =
useListData(getBusCompanyInfoList);
const options = [
{ key: "companyName", label: "企业名称" },
{
key: "serviceName",
label: "服务平台名称",
type: "select",
labelKey: "serviceName",
valueKey: "serviceName",
options: serveOptions,
},
{
key: "platformStatus",
label: "状态",
type: "select",
options: STATUS_LIST,
},
{
key: "platformName",
label: "上级平台名称",
},
];
const visible = ref(false);
const title = ref("");
const fnAddorEdit = (type, row) => {
if (type === "edit") {
corpInfoId.value = row.id;
title.value = "修改";
} else {
title.value = "新增";
corpInfoId.value = null;
}
visible.value = true;
};
const fnDelete = async (id) => {
await ElMessageBox.confirm("确定要删除吗?", {
type: "warning",
});
await setBusCompanyInfoDelete({ id });
ElMessage.success("删除成功");
resetPagination();
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,138 @@
<template>
<el-dialog v-model="visible" :title="title" :before-close="fnClose">
<app-form-builder
ref="formRef"
v-model="form"
:rules
:options
label-width="160px"
>
</app-form-builder>
<template #footer>
<el-button type="primary" @click="fnSubmit"></el-button>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import useForm from "@/hooks/useForm.js";
import { ref } from "vue";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import AppFormBuilder from "@/components/form_builder/index.vue";
import {
setBusServicePlatformAdd,
setBusServicePlatformUpdate,
getBusServicePlatform,
getBusThirdPlatformListAll,
} from "@/request/database.js";
import { STATUS_LIST } from "@/assets/js/constant.js";
const visible = defineModel("visible", { type: Boolean, required: true });
const props = defineProps({
corpInfoId: { type: Number, required: false },
title: { type: String, required: true },
});
const { data: thirdPlatformList } = await getBusThirdPlatformListAll();
const emits = defineEmits(["getData"]);
const { formRef, validate, reset } = useForm();
const form = ref({
serviceCompany: "",
serviceName: "",
serviceCode: "",
thirdIdList: "",
serviceUrl: "",
platformStatus: "",
platformContacts: "",
platformMobile: "",
});
const rules = {
serviceCompany: [
{ required: true, message: "平台服务单位不能为空", trigger: "blur" },
],
serviceName: [
{ required: true, message: "平台名称不能为空", trigger: "blur" },
],
serviceCode: [
{ required: true, message: "服务平台编码不能为空", trigger: "blur" },
],
thirdIdList: [
{ required: true, message: "涉及对接上级平台不能为空", trigger: "change" },
],
serviceUrl: [
{ required: true, message: "平台地址不能为空", trigger: "blur" },
],
platformStatus: [
{ required: true, message: "请选择状态", trigger: "change" },
],
platformContacts: [
{ required: true, message: "负责人不能为空", trigger: "blur" },
],
platformMobile: [
{ required: true, message: "联系电话不能为空", trigger: "blur" },
{ min: 11, max: 13, message: "请输入手机号码或座机号", trigger: "blur" },
{
pattern:
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$|^0\d{2,3}-?\d{7,8}$/,
message: "请输入正确的手机号码或座机号(例:010-12345678)",
},
],
};
const options = [
{ key: "serviceCompany", label: "平台服务单位" },
{ key: "serviceName", label: "平台名称" },
{ key: "serviceCode", label: "服务平台编码" },
{
key: "thirdIdList",
label: "涉及对接上级平台",
type: "select",
valueKey: "id",
labelKey: "platformName",
options: thirdPlatformList,
multiple: true,
},
{ key: "serviceUrl", label: "平台地址" },
{
key: "platformStatus",
label: "状态",
type: "radio",
options: STATUS_LIST,
},
{
key: "platformContacts",
label: "负责人",
},
{
key: "platformMobile",
label: "联系电话",
},
];
const fnGetData = async () => {
if (!props.corpInfoId) return;
const { data } = await getBusServicePlatform({ id: props.corpInfoId });
form.value = data;
form.value.area = [form.value.province, form.value.city, form.value.county];
};
fnGetData();
const fnSubmit = debounce(
1000,
async () => {
await validate();
!props.corpInfoId
? await setBusServicePlatformAdd(form.value)
: await setBusServicePlatformUpdate(form.value);
ElMessage.success("操作成功");
emits("getData");
visible.value = false;
},
{ atBegin: true }
);
const fnClose = () => {
reset();
visible.value = false;
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,101 @@
<template>
<div>
<app-search v-model="searchForm" :options @submit="resetPagination" />
<el-button type="primary" class="mb-10" @click="fnAddorEdit('add')">
新增平台
</el-button>
<app-table
ref="tableRef"
v-model:pagination="pagination"
:data="list"
@get-data="getData"
>
<el-table-column prop="serviceName" label="平台名称" />
<el-table-column prop="serviceCompany" label="平台服务单位名称" />
<el-table-column prop="serviceUrl" label="平台地址" />
<el-table-column prop="thirdList" label="对接上级平台">
<template #default="{ row }">
{{ row.thirdList.map((item) => item.platformName).join("") }}
</template>
</el-table-column>
<el-table-column prop="runTime" label="运行时间" />
<el-table-column prop="platformStatus" label="状态">
<template #default="{ row }">
{{ translationStatus(row.platformStatus, STATUS_LIST) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button type="primary" text link> 查看 </el-button>
<el-button type="primary" text link @click="fnAddorEdit('edit', row)">
编辑
</el-button>
<el-button type="danger" text link @click="fnDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</app-table>
<edit-dialog
v-if="visible"
v-model:visible="visible"
:title="title"
:corp-info-id="corpInfoId"
@get-data="resetPagination"
></edit-dialog>
</div>
</template>
<script setup>
import { ref } from "vue";
import {
getBusServicePlatformList,
setBusServicePlatformDelete,
} from "@/request/database.js";
import useListData from "@/hooks/useListData.js";
import AppSearch from "@/components/search/index.vue";
import AppTable from "@/components/table/index.vue";
import editDialog from "./components/editDialog.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { translationStatus } from "@/assets/js/utils.js";
import { STATUS_LIST } from "@/assets/js/constant.js";
const corpInfoId = ref(null);
const { list, pagination, searchForm, getData, resetPagination, tableRef } =
useListData(getBusServicePlatformList);
const options = [
{ key: "serviceName", label: "平台名称" },
{
key: "serviceCompany",
label: "平台服务单位",
},
{
key: "platformStatus",
label: "状态",
type: "select",
options: STATUS_LIST,
},
];
const visible = ref(false);
const title = ref("");
const fnAddorEdit = (type, row) => {
if (type === "edit") {
corpInfoId.value = row.id;
title.value = "修改";
} else {
title.value = "新增";
corpInfoId.value = null;
}
visible.value = true;
};
const fnDelete = async (id) => {
await ElMessageBox.confirm("确定要删除吗?", {
type: "warning",
});
await setBusServicePlatformDelete({ id });
ElMessage.success("删除成功");
resetPagination();
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,140 @@
<template>
<el-dialog
v-model="visible"
title="对接数据项维护管理"
:before-close="fnClose"
>
<el-form ref="formRef" v-model="form" label-width="160px">
<el-row>
<el-col :span="12">
<el-form-item label="对接表名称" prop="tableName">
<el-input v-model="form.tableName" placeholder="请输入对接表名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数据资源" prop="resourceId">
<el-select v-model="form.resourceId" placeholder="请选择数据目录">
<el-option
v-for="item in menuList"
:key="item.menuId"
:label="item.menuName"
:value="item.menuId"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数据目录" prop="menuId">
<el-select v-model="form.menuId" placeholder="请选择数据目录">
<el-option
v-for="item in childMenuList"
:key="item.menuId"
:label="item.menuName"
:value="item.menuId"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-button class="ml-10" type="primary" @click="fnFindByMenuId">
搜索
</el-button>
</el-row>
<el-table :data="list">
<el-table-column prop="fieldDesc" label="字段描述" />
<el-table-column prop="fieldName" label="字段名" />
<el-table-column prop="fieldType" label="字段类型" />
<el-table-column label="是否必填">
<template #default="{ row }">
<el-radio-group v-model="row.isRequired">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column label="是否需要">
<template #default="{ row }">
<el-radio-group v-model="row.isNeed">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</template>
</el-table-column>
</el-table>
</el-form>
<template #footer>
<el-button type="primary" @click="fnSubmit"></el-button>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from "vue";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import {
getBusDataItemsMenuList,
getFindByMenuId,
setDataSave,
} from "@/request/database.js";
const formRef = ref(null);
const visible = defineModel("visible", { type: Boolean, required: true });
const props = defineProps({
corpInfoId: { type: Number, required: false },
});
const form = ref({
tableName: "",
resourceId: "",
menuId: "",
});
const { list: menuList } = await getBusDataItemsMenuList();
const childMenuList = ref([]);
watch(
() => form.value.resourceId,
(val) => {
childMenuList.value = menuList.filter(
(item) => item.menuId === val
)[0].children;
}
);
const list = ref([]);
const fnFindByMenuId = async () => {
if (!form.value.menuId) {
return ElMessage.warning("请选择数据目录");
}
const { data } = await getFindByMenuId({
thirdPlatformId: props.corpInfoId,
menuId: form.value.menuId,
});
console.log(data, "data");
list.value = data.list;
};
const validateForm = () => {
if (!form.value.menuId && !form.value.tableName) {
return ElMessage.warning("请选择数据目录并填写对接表名称");
}
return true;
};
const fnSubmit = debounce(
1000,
async () => {
await validateForm();
const params = {
...form.value,
thirdPlatformId: props.corpInfoId,
list: list.value,
};
await setDataSave(params);
ElMessage.success("操作成功");
visible.value = false;
},
{ atBegin: true }
);
const fnClose = () => {
formRef.value.resetFields();
visible.value = false;
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,149 @@
<template>
<el-dialog v-model="visible" :title="title" :before-close="fnClose">
<app-form-builder
ref="formRef"
v-model="form"
:rules
:options
label-width="160px"
>
<template #area>
<el-cascader
v-model="form.area"
:options="dictionariesList"
:props="{ value: 'dictionaryId', label: 'name', children: 'list' }"
></el-cascader>
</template>
</app-form-builder>
<template #footer>
<el-button type="primary" @click="fnSubmit"></el-button>
<el-button @click="fnClose"></el-button>
</template>
</el-dialog>
</template>
<script setup>
import useForm from "@/hooks/useForm.js";
import { ref } from "vue";
import { debounce } from "throttle-debounce";
import { ElMessage } from "element-plus";
import AppFormBuilder from "@/components/form_builder/index.vue";
import {
setBusThirdPlatformAdd,
setBusThirdPlatformUpdate,
getBusThirdPlatform,
} from "@/request/database.js";
import { getAreaListTree } from "@/request/data_dictionary.js";
import { STATUS_LIST } from "@/assets/js/constant.js";
const visible = defineModel("visible", { type: Boolean, required: true });
const props = defineProps({
corpInfoId: { type: Number, required: false },
title: { type: String, required: true },
});
const { dictionariesList } = await getAreaListTree();
const emits = defineEmits(["getData"]);
const { formRef, validate, reset } = useForm();
const form = ref({
platformName: "",
platformCode: "",
platformLevel: "",
area: [],
url: "",
platformStatus: 1,
frequency: "",
});
const rules = {
platformName: [
{ required: true, message: "平台名称不能为空", trigger: "blur" },
],
platformCode: [
{ required: true, message: "平台编码不能为空", trigger: "blur" },
],
platformLevel: [
{ required: true, message: "级别不能为空", trigger: "change" },
],
platformStatus: [
{ required: true, message: "请选择状态", trigger: "change" },
],
frequency: [
{ required: true, message: "推送频率不能为空", trigger: "change" },
],
};
const platformLevelOptions = [
{ name: "国家", id: 1 },
{ name: "省平台", id: 2 },
{ name: "市平台", id: 3 },
{ name: "县平台", id: 4 },
{ name: "园区", id: 5 },
];
const frequencyOptions = [
{ name: "实时", id: 0 },
{ name: "每日", id: 1 },
{ name: "每周", id: 2 },
{ name: "每月", id: 3 },
];
const options = [
{ key: "platformName", label: "平台名称" },
{ key: "platformCode", label: "平台编码" },
{
key: "platformLevel",
label: "级别",
type: "select",
valueKey: "id",
options: platformLevelOptions,
},
{
key: "area",
label: "归属属地",
},
{ key: "url", label: "对接地址" },
{
key: "platformStatus",
label: "状态",
type: "radio",
options: STATUS_LIST,
},
{
key: "frequency",
label: "推送频率",
type: "select",
valueKey: "id",
options: frequencyOptions,
},
];
const fnGetData = async () => {
if (!props.corpInfoId) return;
const { data } = await getBusThirdPlatform({ id: props.corpInfoId });
form.value = data;
form.value.area = [form.value.province, form.value.city, form.value.county];
};
fnGetData();
const fnSubmit = debounce(
1000,
async () => {
await validate();
const [province = "", city = "", county = ""] = form.value.area;
const params = {
...form.value,
province,
city,
county,
};
!props.corpInfoId
? await setBusThirdPlatformAdd(params)
: await setBusThirdPlatformUpdate(params);
ElMessage.success("操作成功");
emits("getData");
visible.value = false;
},
{ atBegin: true }
);
const fnClose = () => {
reset();
visible.value = false;
};
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,135 @@
<template>
<div>
<app-search v-model="searchForm" :options @submit="resetPagination" />
<el-button type="primary" class="mb-10" @click="fnAddorEdit('add')">
新增平台
</el-button>
<app-table
ref="tableRef"
v-model:pagination="pagination"
:data="list"
@get-data="getData"
>
<el-table-column prop="platformLevel" label="平台级别">
<template #default="{ row }">
{{ translationStatus(row.platformLevel, platformLevelOptions) }}
</template>
</el-table-column>
<el-table-column prop="platformName" label="平台名称" />
<el-table-column prop="url" label="平台地址" />
<el-table-column prop="fieldCount" label="涉及推送字段数" />
<el-table-column prop="runTime" label="运行时间" />
<el-table-column prop="frequency" label="推送频率"
><template #default="{ row }">
{{ translationStatus(row.frequency, frequencyOptions) }}
</template></el-table-column
>
<el-table-column prop="platformStatus" label="状态">
<template #default="{ row }">
{{ translationStatus(row.platformStatus, STATUS_LIST) }}
</template>
</el-table-column>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button type="primary" text link @click="fnDataItems(row.id)">
对接项维护
</el-button>
<el-button type="primary" text link> 查看 </el-button>
<el-button type="primary" text link @click="fnAddorEdit('edit', row)">
编辑
</el-button>
<el-button type="danger" text link @click="fnDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</app-table>
<edit-dialog
v-if="visible"
v-model:visible="visible"
:title="title"
:corp-info-id="corpInfoId"
@get-data="resetPagination"
></edit-dialog>
<data-items-dialog
v-if="dataItemVisible"
v-model:visible="dataItemVisible"
:corp-info-id="corpInfoId"
></data-items-dialog>
</div>
</template>
<script setup>
import { ref } from "vue";
import {
getBusThirdPlatformList,
setBusThirdPlatformDelete,
} from "@/request/database.js";
import useListData from "@/hooks/useListData.js";
import AppSearch from "@/components/search/index.vue";
import AppTable from "@/components/table/index.vue";
import editDialog from "./components/editDialog.vue";
import dataItemsDialog from "./components/dataItemsDialog.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { translationStatus } from "@/assets/js/utils.js";
import { STATUS_LIST } from "@/assets/js/constant.js";
const platformLevelOptions = [
{ name: "国家", id: 1 },
{ name: "省平台", id: 2 },
{ name: "市平台", id: 3 },
{ name: "县平台", id: 4 },
{ name: "园区", id: 5 },
];
const frequencyOptions = [
{ name: "实时", id: 0 },
{ name: "每日", id: 1 },
{ name: "每周", id: 2 },
{ name: "每月", id: 3 },
];
const corpInfoId = ref(null);
const { list, pagination, searchForm, getData, resetPagination, tableRef } =
useListData(getBusThirdPlatformList);
const options = [
{ key: "platformName", label: "平台名称" },
{
key: "platformLevel",
label: "平台级别",
type: "select",
options: platformLevelOptions,
},
{
key: "platformStatus",
label: "状态",
type: "select",
options: STATUS_LIST,
},
];
const visible = ref(false);
const title = ref("");
const fnAddorEdit = (type, row) => {
if (type === "edit") {
corpInfoId.value = row.id;
title.value = "修改";
} else {
title.value = "新增";
corpInfoId.value = null;
}
visible.value = true;
};
const dataItemVisible = ref(false);
const fnDataItems = (id) => {
corpInfoId.value = id;
dataItemVisible.value = true;
};
const fnDelete = async (id) => {
await ElMessageBox.confirm("确定要删除吗?", {
type: "warning",
});
await setBusThirdPlatformDelete({ id });
ElMessage.success("删除成功");
resetPagination();
};
</script>
<style scoped lang="scss"></style>