添加字段

This commit is contained in:
yangjun 2026-02-12 13:26:12 +08:00
parent 7821f9658e
commit afc498fdbe
6 changed files with 601 additions and 22 deletions

View File

@ -6,11 +6,14 @@ const { createConfirm } = useMessage();
enum Api {
list = '/workorder/workOrder/list',
save='/workorder/workOrder/add',
saveSjygl='/sys/dataSource/add',
edit='/workorder/workOrder/edit',
updateMqById='/workorder/workOrder/updateMqById',
deleteOne = '/workorder/workOrder/delete',
deleteBatch = '/workorder/workOrder/deleteBatch',
importExcel = '/workorder/workOrder/importExcel',
exportXls = '/workorder/workOrder/exportXls',
testConnection = '/online/cgreport/api/testConnection',
}
/**
@ -78,4 +81,25 @@ export const saveOrUpdate = (params, isUpdate) => {
*/
export const edit = (params) => {
return defHttp.post({ url: Api.edit, params }, { isTransformResponse: false });
}
}
export const updateMqById = (params) => {
return defHttp.post({ url: Api.updateMqById, params }, { isTransformResponse: false });
}
/**
*
* @param params
*/
export const saveSjygl = (params) => {
return defHttp.post({ url: Api.saveSjygl, params }, { isTransformResponse: false });
}
/**
*
* @param params
*/
export const testConnection = (params) => {
return defHttp.post({ url: Api.testConnection, params });
};

View File

@ -66,6 +66,9 @@
</BasicTable>
<!-- 表单区域 -->
<WorkOrderModal ref="registerModal" @success="handleSuccess"></WorkOrderModal>
<GdglDataSourceModal ref="registerDrawer" @success="reload" />
</div>
</template>
@ -81,8 +84,13 @@ import { useUserStore } from '/@/store/modules/user';
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
import { useMessage } from '/@/hooks/web/useMessage';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import GdglDataSourceModal from './components/DataSourceModal.vue';
import {useDrawer} from "@/components/Drawer";
const formRef = ref();
const registerDrawer = ref();
const queryParam = reactive<any>({});
const toggleSearchStatus = ref<boolean>(false);
const registerModal = ref();
@ -129,21 +137,13 @@ function handleSuperQuery(params) {
});
searchQuery();
}
/**
* 新增事件
* 数据源管理
*/
function handleAdd() {
registerModal.value.disableSubmit = false;
registerModal.value.add();
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
registerModal.value.disableSubmit = false;
registerModal.value.edit(record);
function handleSjygl(record){
console.log("🚀 ~ handleSjygl ~ record:", record)
registerDrawer.value.add(record);
registerDrawer.value.disableSubmit = false;
}
/**
@ -182,10 +182,15 @@ function getTableAction(record) {
label: '机构详情',
onClick: handleOrgDetail.bind(null, record)
},
{
label: '数据源管理',
onClick: handleSjygl.bind(null, record),
ifShow: record.status == '0'
},
{
label: '反馈',
onClick: handleQueren.bind(null, record),
ifShow: record.status == '0'
ifShow: record.status == '1'
},
];
}
@ -194,6 +199,8 @@ function getTableAction(record) {
* 接收
*/
function handleQueren(record) {
record.accountNo = record.orgTel;
record.passwordText = "123456";
registerModal.value.disableSubmit = false;
registerModal.value.orgFankui(record);
}

View File

@ -0,0 +1,316 @@
<template>
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"
name="WorkOrderForm">
<a-row class="card-class">
<a-col :span="24">
<a-form-item label="数据源名称" v-bind="validateInfos.name" id="WorkOrderForm-name" name="name">
<a-input v-model:value="formData.name" placeholder="请输入数据源名称" disabled ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数据源编码" v-bind="validateInfos.code" id="WorkOrderForm-code" name="code">
<a-input v-model:value="formData.code" placeholder="请输入数据源编码" disabled ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数据库类型" v-bind="validateInfos.dbType" id="WorkOrderForm-dbType" name="dbType">
<JDictSelectTag placeholder="请输入数据库类型" v-model:value="formData.dbType" dictCode="database_type" @change="onChangeDbType"></JDictSelectTag>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="驱动类" v-bind="validateInfos.dbDriver" id="WorkOrderForm-dbDriver" name="dbDriver">
<a-input v-model:value="formData.dbDriver" placeholder="请输入驱动类" ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数据源地址" v-bind="validateInfos.dbUrl" id="WorkOrderForm-dbUrl" name="dbUrl">
<a-textarea :rows="3" v-model:value="formData.dbUrl" placeholder="请输入数据源地址" ></a-textarea>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数据库用户名" v-bind="validateInfos.dbUsername" id="WorkOrderForm-dbUsername" name="dbUsername">
<a-input v-model:value="formData.dbUsername" placeholder="请输入数据库用户名" ></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="数据库密码" v-bind="validateInfos.dbPassword" id="WorkOrderForm-dbPassword" name="dbPassword">
<a-input-search v-model:value="formData.dbPassword" placeholder="请输入数据库密码" enter-button="测试" @search="handleTest"/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="备注" v-bind="validateInfos.remark" id="WorkOrderForm-remark" name="remark">
<a-textarea v-model:value="formData.remark" placeholder="请输入备注" ></a-textarea>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
</JFormContainer>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, reactive, defineExpose, nextTick, defineProps, computed, onMounted } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import { getValueType } from '/@/utils';
import { saveSjygl,saveOrUpdate,testConnection } from '../WorkOrder.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({}) },
formBpm: { type: Boolean, default: true }
});
const formRef = ref();
const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']);
const formData = reactive<Record<string, any>>({
id: '',
code: '',
name: '',
remark: '',
dbType: '',
dbDriver: '',
dbUrl: '',
dbUsername: '',
dbPassword: '',
});
const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const confirmLoading = ref<boolean>(false);
//
const validatorRules = reactive({
code: [{ required: true, message: '请输入数据源编码!'},],
name: [{ required: true, message: '请输入数据源名称!'},],
dbType: [{ required: true, message: '请输入数据库类型'},],
dbDriver: [{ required: true, message: '请输入驱动类!'},],
dbUrl: [{ required: true, message: '请输入数据源地址!'},],
dbUsername: [{ required: true, message: '请输入数据库用户名!'},],
dbPassword: [{ required: true, message: '请输入数据库密码!'},],
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
const dbDriverMap = {
// MySQL
'1': { dbDriver: 'com.mysql.jdbc.Driver' },
//MySQL5.7+
'4': { dbDriver: 'com.mysql.cj.jdbc.Driver' },
// Oracle
'2': { dbDriver: 'oracle.jdbc.OracleDriver' },
// SQLServer
'3': { dbDriver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver' },
// marialDB
'5': { dbDriver: 'org.mariadb.jdbc.Driver' },
// postgresql
'6': { dbDriver: 'org.postgresql.Driver' },
//
'7': { dbDriver: 'dm.jdbc.driver.DmDriver' },
//
'8': { dbDriver: 'com.kingbase8.Driver' },
//
'9': { dbDriver: 'com.oscar.Driver' },
// SQLite
'10': { dbDriver: 'org.sqlite.JDBC' },
// DB2
'11': { dbDriver: 'com.ibm.db2.jcc.DB2Driver' },
// Hsqldb
'12': { dbDriver: 'org.hsqldb.jdbc.JDBCDriver' },
// Derby
'13': { dbDriver: 'org.apache.derby.jdbc.ClientDriver' },
// H2
'14': { dbDriver: 'org.h2.Driver' },
//
'15': { dbDriver: '' },
};
const dbUrlMap = {
// MySQL
'1': { dbUrl: 'jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false' },
//MySQL5.7+
'4': {
dbUrl:
'jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai',
},
// Oracle
'2': { dbUrl: 'jdbc:oracle:thin:@127.0.0.1:1521:ORCL' },
// SQLServer
'3': { dbUrl: 'jdbc:sqlserver://127.0.0.1:1433;SelectMethod=cursor;DatabaseName=jeecgboot' },
// Mariadb
'5': { dbUrl: 'jdbc:mariadb://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useSSL=false' },
// Postgresql
'6': { dbUrl: 'jdbc:postgresql://127.0.0.1:5432/jeecg-boot' },
//
'7': { dbUrl: 'jdbc:dm://127.0.0.1:5236/?jeecg-boot&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8' },
//
'8': { dbUrl: 'jdbc:kingbase8://127.0.0.1:54321/jeecg-boot' },
//
'9': { dbUrl: 'jdbc:oscar://192.168.1.125:2003/jeecg-boot' },
// SQLite
'10': { dbUrl: 'jdbc:sqlite://opt/test.db' },
// DB2
'11': { dbUrl: 'jdbc:db2://127.0.0.1:50000/jeecg-boot' },
// Hsqldb
'12': { dbUrl: 'jdbc:hsqldb:hsql://127.0.0.1/jeecg-boot' },
// Derby
'13': { dbUrl: 'jdbc:derby://127.0.0.1:1527/jeecg-boot' },
// H2
'14': { dbUrl: 'jdbc:h2:tcp://127.0.0.1:8082/jeecg-boot' },
//
'15': { dbUrl: '' },
};
//
const disabled = computed(() => {
if (props.formBpm === true) {
if (props.formData.disabled === false) {
return false;
} else {
return true;
}
}
return props.formDisabled;
});
function onChangeDbType(value) {
formData.dbUrl = dbUrlMap[value].dbUrl
formData.dbDriver = dbDriverMap[value].dbDriver
}
async function handleTest() {
if(!formData.dbType || !formData.dbDriver || !formData.dbUrl || !formData.dbUsername || !formData.dbPassword){
createMessage.warning('请填写完整数据源信息!');
return;
}
var params = {'dbType':formData.dbType, 'dbDriver':formData.dbDriver, 'dbUrl':formData.dbUrl, 'dbUsername':formData.dbUsername, 'dbPassword':formData.dbPassword}
console.log("🚀 ~ handleTest ~ params:", params)
let loading = createMessage.loading('连接中....', 0);
testConnection(params)
.then((data) => {
if (data.success) {
createMessage.success('连接成功');
}
})
.catch((error) => { })
.finally(() => loading());
}
/**
* 新增
*/
function add(record) {
console.log("🚀 ~ add ~ record:", record)
edit({name:record.orgName,code:record.orgCode,id:record.id});
}
/**
* 编辑
*/
function edit(record) {
nextTick(() => {
resetFields();
const tmpData = {};
Object.keys(formData).forEach((key) => {
if (record.hasOwnProperty(key)) {
tmpData[key] = record[key]
}
})
//
Object.assign(formData, tmpData);
});
}
/**
* 提交数据
*/
async function submitForm() {
try {
//
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//
let model = formData;
if (model.id) {
isUpdate.value = true;
}
//
for (let data in model) {
//
if (model[data] instanceof Array) {
let valueType = getValueType(formRef.value.getProps, data);
//
if (valueType === 'string') {
model[data] = model[data].join(',');
}
}
}
var params2 = {code:formData.code,name:formData.name,'dbType':formData.dbType, 'dbDriver':formData.dbDriver, 'dbUrl':formData.dbUrl, 'dbUsername':formData.dbUsername, 'dbPassword':formData.dbPassword}
await saveSjygl(params2).then((res) => {
console.log("🚀 ~ submitForm ~ res:", res)
if (res.success) {
var params = {id:model.id,status:'1'}
saveOrUpdate(params, isUpdate.value).then((res) => {
if (res.success) {
createMessage.success(res.message);
emit('ok');
} else {
createMessage.warning(res.message);
}
})
.finally(() => {
confirmLoading.value = false;
});
} else {
createMessage.warning(res.message);
}
});
// saveSjygl(model).then((res) => { });
}
defineExpose({
add,
edit,
submitForm,
});
</script>
<style lang="less" scoped>
.antd-modal-form {
padding: 0 4px 0 4px;
}
.card-class {
padding-top: 24px;
padding-bottom: 24px;
padding-left: 14px;
padding-right: 14px;
// background-color: rgba(255, 255, 255, 0.9);
background-color: #fcfdff;
border-radius: 10px;
// box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 12px;
margin-bottom: 14px;
}
</style>

View File

@ -0,0 +1,87 @@
<template>
<a-drawer :title="title" :width="width" v-model:visible="visible" :closable="true"
:footer-style="{ textAlign: 'right' }" :bodyStyle="{ padding: '14px' }" @close="handleCancel">
<DataSourceForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false">
</DataSourceForm>
<template #footer>
<a-button type="primary" style="margin-right: 8px" @click="handleCancel">关闭</a-button>
<a-button type="primary" @click="handleOk" v-if="!disableSubmit">确认</a-button>
</template>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import DataSourceForm from './DataSourceForm.vue'
const title = ref<string>('');
const width = ref<number>(600);
const visible = ref<boolean>(false);
const orgDetailVisible = ref<boolean>(false);
const orgFankuiVisible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const registerForm = ref();
const emit = defineEmits(['register', 'success']);
/**
* 新增
*/
function add(record) {
title.value = '数据源管理';
visible.value = true;
nextTick(() => {
registerForm.value.add(record);
});
}
/**
* 编辑
* @param record
*/
function edit(record) {
title.value = disableSubmit.value ? '详情' : '编辑';
visible.value = true;
nextTick(() => {
registerForm.value.edit(record);
});
}
/**
* 确定按钮点击事件
*/
function handleOk() {
registerForm.value.submitForm();
}
/**
* form保存回调事件
*/
function submitCallback() {
handleCancel();
emit('success');
}
/**
* 取消按钮回调事件
*/
function handleCancel() {
visible.value = false;
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less">
/**隐藏样式-modal确定按钮 */
.jee-hidden {
display: none !important;
}
</style>
<style lang="less" scoped></style>

View File

@ -55,10 +55,21 @@
</div>
<a-row>
<a-col :span="12">
<a-form-item label="反馈内容" v-bind="validateInfos.replyContent" id="WorkOrderForm-replyContent"
name="replyContent">
<a-textarea v-model:value="formData.replyContent" rows="4" placeholder="请输入反馈内容" :maxlength="100"
showCount />
<a-form-item label="访问地址" v-bind="validateInfos.netUrl" id="WorkOrderForm-netUrl"
name="netUrl">
<a-input v-model:value="formData.netUrl" placeholder="请输入访问地址" :maxlength="100" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="账号" v-bind="validateInfos.accountNo" id="WorkOrderForm-accountNo"
name="accountNo">
<a-input v-model:value="formData.accountNo" placeholder="请输入账号" :maxlength="100" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="密码" v-bind="validateInfos.passwordText" id="WorkOrderForm-passwordText"
name="passwordText">
<a-input v-model:value="formData.passwordText" placeholder="请输入密码" :maxlength="100" />
</a-form-item>
</a-col>
<a-col :span="12">
@ -66,6 +77,14 @@
<JUpload v-model:value="formData.replyFile" :bizPath="upBizPrefix + '/jgxx/jg'" :maxCount="1"></JUpload>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="反馈内容" v-bind="validateInfos.replyContent" id="WorkOrderForm-replyContent"
name="replyContent">
<a-textarea v-model:value="formData.replyContent" rows="4" placeholder="请输入反馈内容" :maxlength="100"
showCount />
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
@ -78,7 +97,7 @@ import { ref, reactive, defineExpose, nextTick, defineProps, computed, onMounted
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import { getValueType } from '/@/utils';
import { saveOrUpdate } from '../WorkOrder.api';
import { updateMqById } from '../WorkOrder.api';
import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
@ -116,6 +135,9 @@ const formData = reactive<Record<string, any>>({
handleBy: '',
replyFile: '',
replyContent: '',
netUrl: '',
accountNo: '',
passwordText: '',
});
const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
@ -123,7 +145,10 @@ const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
const confirmLoading = ref<boolean>(false);
//
const validatorRules = reactive({
replyContent: [{ required: true, message: '请输入反馈内容' },],
// replyContent: [{ required: true, message: '' },],
netUrl: [{ required: true, message: '请输入访问地址' },],
accountNo: [{ required: true, message: '请输入账号' },],
passwordText: [{ required: true, message: '请输入密码' },],
});
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
@ -153,6 +178,7 @@ function open(record) {
tmpData[key] = record[key]
}
})
//
Object.assign(formData, tmpData);
});
@ -196,7 +222,7 @@ async function submitForm() {
model.handleBy = userStore.getUserInfo.realname;
model.status = '3';
await saveOrUpdate(model, isUpdate.value)
await updateMqById(model, isUpdate.value)
.then((res) => {
if (res.success) {
createMessage.success(res.message);

View File

@ -0,0 +1,119 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit" width="40%">
<BasicForm @register="registerForm">
<template #pwd="{ model, field }">
<a-row :gutter="8">
<a-col :sm="15" :md="16" :lg="17" :xl="19">
<a-input-password v-model:value="model[field]" placeholder="请输入密码" />
</a-col>
<a-col :sm="9" :md="7" :lg="7" :xl="5">
<a-button type="primary" style="width: 100%" @click="handleTest">测试</a-button>
</a-col>
</a-row>
</template>
<template #departSelect="{ model, field }">
<a-select v-model:value="model[field]" :disabled="model['id'] != null"
@change="(value, option) => handleChange(value, model)" :allowClear="true">
<template v-for="item in departOptions" :key="`${item.code}`">
<a-select-option :value="item.code" :label="item.departName">
{{ item.departName }}
</a-select-option>
</template>
</a-select>
</template>
</BasicForm>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from './datasource.data';
import { saveOrUpdateDataSource, getDataSourceById, testConnection, queryDeparts } from './datasource.api';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
// Emits
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const departOptions = ref<any[]>([]);
//
const [registerForm, { getFieldsValue, resetFields, validateFields, setFieldsValue, validate }] = useForm({
// labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
});
//
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//
await resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
await getDepartOptions('');
} else {
await getDepartOptions('1');
}
if (unref(isUpdate)) {
//
data.record = await getDataSourceById({ id: data.record.id });
//
await setFieldsValue({
...data.record,
});
}
});
//
const title = computed(() => (!unref(isUpdate) ? '新增数据源' : '编辑数据源'));
async function getDepartOptions(addFLag) {
departOptions.value = [];
const data = await queryDeparts({ addFLag: addFLag });
console.log(data);
Object.assign(departOptions.value, data);
}
async function handleChange(value, formData) {
if (value == null) {
formData["code"] = "";
} else {
formData["code"] = value;
}
}
async function handleTest() {
let keys = ['dbType', 'dbDriver', 'dbUrl', 'dbName', 'dbUsername', 'dbPassword'];
//
let fieldsValues = getFieldsValue(keys);
let setFields = {};
keys.forEach((key) => (setFields[key] = { value: fieldsValues[key], errors: null }));
await validateFields(keys).then((values) => {
let loading = createMessage.loading('连接中....', 0);
testConnection(values)
.then((data) => {
if (data.success) {
createMessage.success('连接成功');
}
})
.catch((error) => { })
.finally(() => loading());
});
}
//
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({ confirmLoading: true });
//
await saveOrUpdateDataSource(values, isUpdate.value);
//
closeModal();
//
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>