chore: 初始开源发布

iotlcm-admin-svr:管理后台服务。

- Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件)
- 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、
  MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位;
  私网 IP → 文档地址段;库名 xiujie_admin → iotlcm
- 真实手机号/邮箱 → 合法 11 位编造号 / example.com
- 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、
  私有依赖 go get 行、明文 registry 登录口令
- 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名
- Dockerfile 改用公共基础镜像
- 拼错的 RADEME.md → README.md,README 重写
- 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用
- 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes

数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
This commit is contained in:
MiFaZhan
2026-10-23 14:46:05 +08:00
commit 59eb34976a
1132 changed files with 138197 additions and 0 deletions
@@ -0,0 +1,119 @@
<template>
<BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
<BasicForm>
</BasicForm>
</BasicDrawer>
</template>
<script setup lang="ts">
import { computed, nextTick, ref } from 'vue';
import { useVbenDrawer, useVbenModal, VbenButton } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep } from '@vben/utils';
import { useVbenForm } from '#/adapter/form';
import { Alert } from 'ant-design-vue';
import { Edit, View } from '@{.importWebApi}';
import { editSchema } from './model';
const emit = defineEmits<{ reload: [] }>();
interface ModalProps {
id?: number | string;
update: boolean;
view: boolean;
}
const isUpdate = ref(false);
const isView = ref(false);
const title = computed(() => {
if (isView.value) {
return $t('pages.common.view');
}
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
},
formItemClass: 'col-span-@{.script.formGridSpan}',
},
layout: 'vertical',
schema: editSchema,
showDefaultActions: false,
wrapperClass: 'grid-cols-@{.script.formGridSpan} gap-x-4',
});
@{ if eq .isEditModal true }
const [BasicDrawer, drawerApi] = useVbenModal
@{else}
const [BasicDrawer, drawerApi] = useVbenDrawer
@{end}
({
onCancel: handleCancel,
onConfirm: handleConfirm,
async onOpenChange(isOpen) {
if (!isOpen) {
return null;
}
drawerApi.setState({ confirmLoading: true, loading: true })
const { id, update, view, } = drawerApi.getData() as ModalProps;
isUpdate.value = update;
isView.value = view;
if (isUpdate.value || isView.value) {
const record = await View({ @{.pk.TsName}: id });
await formApi.setValues(record);
}
drawerApi.setState({ confirmLoading: false, loading: false })
if (view) {
drawerApi.setState({ showConfirmButton: false });
formApi.setState({
commonConfig: {
componentProps: {
readonly: true,
"only-read": true,
}
}
});
} else {
drawerApi.setState({ showConfirmButton: true });
formApi.setState({
commonConfig: {
componentProps: {
readonly: false,
"only-read": false,
}
}
});
}
},
});
async function handleConfirm() {
try {
drawerApi.setState({ confirmLoading: true, loading: true })
const { valid } = await formApi.validate();
if (!valid) {
return;
}
const data = cloneDeep(await formApi.getValues());
await (Edit(data));
emit('reload');
await handleCancel();
} catch (error) {
console.error(error);
} finally {
drawerApi.setState({ confirmLoading: false, loading: false })
}
}
async function handleCancel() {
drawerApi.close();
await formApi.resetForm();
}
</script>