初始提交

This commit is contained in:
2025-09-04 16:27:57 +08:00
commit f2faa2d5fd
1076 changed files with 478489 additions and 0 deletions

View File

@ -0,0 +1,651 @@
<template>
<div style="height: calc(100vh - 230px); overflow: auto">
<div class="component-card-title">
组件 使用参考
<a
style="color: cornflowerblue"
target="_blank"
href="https://rmyf85frnp.feishu.cn/docs/doccnUnuEvm146PnT8Gl0Wn1C0w#"
>文档地址</a
>
</div>
<!-- {{ form }} -->
<!---使用 from表单前
1. el-from 加上 mosty-from-wrap 是必要的
2. 组件宽度已经封装 直接传 width="800px" 可设置右侧 el-form-item__content的宽度
3. 如使用校验
①请引入import * as rule from "@/utils/rules.js";
②注意如要使用校验的话 封装的组件prop是固定的 v-model form.属性 也需要对应上
有更优方案我们可以讨论交流
4.组件库支持两种使用方式 可单独使用 如ChooseUser组件 也可统一使用 如MOSTY.ChooseIcon
--->
<el-form
ref="formRef"
:model="form"
label-width="140px"
class="mosty-from-wrap"
:rules="rules"
>
<el-form-item label="选人组件" prop="">
<el-button
type="success"
size="small"
round
@click="chooseUserVisible = true"
>选择用户组件</el-button
>
<!-- :roleId="" 可筛选对应角色下面的人员 -->
<ChooseUser
v-model="chooseUserVisible"
@choosedUsers="hanlderChoose"
></ChooseUser>
</el-form-item>
<el-form-item label="选择图标" prop="iconName">
<MOSTY.ChooseIcon
width="200px"
clearable
placeholder="请选择图标名称"
v-model="form.iconName"
></MOSTY.ChooseIcon>
</el-form-item>
<el-form-item label="管理部门树形" prop="iconName">
<MOSTY.DepartmentTree
placeholder="管理部门ID"
clearable
v-model="form.deptId"
/>
</el-form-item>
<el-form-item label="文件组件" prop="upload">
<!-- === 使用
上传组件默认上传图片 如果上传其他文件格式 请加上:isImg="false"
:limit="3" 限制上传文件数
width="800px" 最外层box宽度
limit控制上传数量
disabled-->
<MOSTY.Upload
width="800px"
:limit="3"
:isImg="false"
v-model="form.upload"
></MOSTY.Upload>
</el-form-item>
<el-form-item label="图片组件" prop="upload">
<MOSTY.Upload
width="800px"
:limit="2"
v-model="form.upload"
></MOSTY.Upload>
</el-form-item>
<el-form-item label="新的文件上传组件" prop="upload">
<MOSTY.FileUpload
v-model:modelValue="form.fjdz"
width="150px"
:limit="3"
@handleChange="changeFile"
></MOSTY.FileUpload>
</el-form-item>
<el-form-item label="身份证号" prop="identityCard">
<!--
clearable 是否清除
-->
<MOSTY.IdentityCard
width="200px"
v-model="form.identityCard"
clearable
@onInput="identityCardChange"
>
</MOSTY.IdentityCard>
</el-form-item>
<el-form-item label="联系方式" prop="phone">
<!-- === clearable:是否可清除 show-word-limit -->
<MOSTY.Phone
width="210px"
show-word-limit
v-model="form.phone"
maxlength="11"
clearable
@onInput="phoneChange"
>
</MOSTY.Phone>
</el-form-item>
<el-form-item label="性别" prop="">
<!-- === clearable:是否可清除 show-word-limit -->
<MOSTY.Sex width="220px" v-model:sex="form.sex"></MOSTY.Sex>
</el-form-item>
<el-form-item label="E-mail" prop="email">
<!-- === clearable:是否可清除 show-word-limit -->
<MOSTY.Email v-model="form.email" width="230px" clearable></MOSTY.Email>
</el-form-item>
<el-divider content-position="left"
>通用下拉组件Demo展示 所有支持的下拉组件请展开底部手风琴</el-divider
>
<el-form-item label="下拉多选" prop="packageSelect">
<!-- 单选 多选 下拉组件
0.impoert 需要传入字典枚举值 详见 selectAll
1.clearable:是否可清除
2.filterable:是否可筛选(直接在下拉框内输入)
3.是否多选 添加 multiple collapse-tags
4handleChange:选中方法
-->
<!--注意 使用使用时 prop要与form里面的值保持一致-->
<!---- GENDER:性别 ----->
<MOSTY.PackageSelect
dictEnum="GENDER"
width="240px"
v-model="form.packageSelect"
clearable
filterable
@handleChange="handleSelectChange"
/>
</el-form-item>
<el-form-item label="封装民族" prop="nation">
<!--==民族== clearable:是否可清除 filterable:是否可筛选(直接在下拉框内输入) handleChange:选中方法-->
<!--注意 使用使用时 prop要与form里面的值保持一致-->
<!---- GENDER:性别 ----->
<MOSTY.PackageSelect
width="140px"
v-model="form.nation"
dictEnum="NATION"
clearable
filterable
/>
</el-form-item>
<el-divider content-position="left">通用下拉组件Demo展示 end</el-divider>
<el-form-item label="组织机构" prop="frameWork2">
<!-- ==组织机构== defaultConf:节点渲染配置选项 multiple:是否多选 clearable:是否可清除 filterable:是否可筛选 handleChange:选中方法================ -->
<MOSTY.FrameWork
width="250px"
v-model="form.frameWork2"
clearable
filterable
:multiple="true"
:defaultConf="defaultProps"
:treeData="treeData"
@handleChange="frameWorkChange"
/>
</el-form-item>
<p>{{ form }}</p>
<el-form-item label="菜单" prop="frameWork">
<!--
multiple 支持多选 单选请传入字符串 7 多选传入 [ "9", "5" ]
filterable 过滤
clearable 清空
-->
<MOSTY.FrameWork2
width="300px"
clearable
placeholder="请选择菜单"
filterable
v-model="form.frameWork"
/>
</el-form-item>
<!---
multiple 支持多选 单选请传入字符串 7 多选传入 [ "9", "5" ]
filterable 过滤
clearable 清空
---->
<el-form-item label="选择部门:" prop="">
<MOSTY.Department
width="280px"
clearable
filterable
v-model="form.deptIds"
/>
</el-form-item>
<el-form-item label="岗位选择" prop="stationSelect">
<!-- ==组织机构2== :multiple="true" 是否多选 clearable:是否可清除 filterable:是否可筛选 -->
<MOSTY.StationSelect
width="300px"
clearable
filterable
v-model="form.stationSelect"
/>
</el-form-item>
<el-form-item label="车牌号" prop="carnumber">
<!-- ==车牌号== handleChange:选中方法-->
<MOSTY.CarNumber
width="260px"
v-model:carnumber="form.carnumber"
@handleChange="carnumberChange"
/>
</el-form-item>
<el-form-item label="地址" prop="address">
<!-- ==地址== filterable:是否可筛选 defaultConf:节点渲染配置选项 handleChange:选中方法 -->
<MOSTY.AddressSelect
width="270px"
v-model="form.address"
filterable
:defaultConf="defaultConf"
@handleChange="addressChange"
/>
</el-form-item>
<el-form-item label="多级联动" prop="">
<MOSTY.Provinces
width="280px"
placeholder="请选择身份"
clearable
v-model="form.provinces"
/>
</el-form-item>
<el-form-item label="Other" prop="other">
<!-- 如果设计稿里面没有 并且你不想使用 element自带的表单 你可以试试自定义组件Other -->
<MOSTY.Other
width="280px"
placeholder="如果设计稿里面没有的 你也可以使用Other组件"
clearable
v-model="form.other"
/>
</el-form-item>
<p style="color: #ccc; padding-bottom: 20px; font-size: 14px">
如果公用组件设计稿里面没有 并且你不想使用 element自带的表单
你可以试试自定义组件Other
</p>
<el-form-item label="自定义" prop="test">
<el-input
v-model="form.test"
placeholder="自定义表单参考element"
></el-input>
</el-form-item>
<el-form-item label="element" prop="marriage">
<el-select v-model="form.element" placeholder="普通element">
<el-option label="蛋糕" value="1"></el-option>
<el-option label="香蕉" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(from)">提交</el-button>
</el-form-item>
<MOSTY.MarkdownEdit :detail="detailData" v-model="form.markdownEdit" />
<div class="accordion-box" v-if="true">
<el-divider content-position="left">**</el-divider>
{{ selectForm }}
<el-collapse v-model="activeNames">
<el-collapse-item title="支持的下拉组件展示" name="1">
<div class="left-wrap">
<div class="from-wrap">
<el-form-item
:label="item.name"
v-for="(item, index) in selectAll"
:key="'packageSelect' + index"
>
<!--==民族== clearable:是否可清除 filterable:是否可筛选(直接在下拉框内输入) handleChange:选中方法-->
<!--注意 使用使用时 prop要与form里面的值保持一致-->
<!---- GENDER:性别 ----->
<MOSTY.PackageSelect
v-model:modelValue="selectForm[item.dictElementEnum]"
:dictEnum="item.dictElementEnum"
clearable
filterable
/>
</el-form-item>
</div>
</div>
<div class="right-wrap">
<pre>
1.对应映射值
{ NATION: "民族" },
{ GENDER: "性别" },
{ BLOOD_TYPE: "血型" },
{ EDUCATION: "学历" },
{ POLITICAL_OUTLOOK: "政治面貌" },
{ MARITAL_STATUS: "婚姻状况" },
{ RELATIONSHIP: "亲属关系" },
{ VEHICLE_MODEL: "车辆型号" },
<!-- { VEHICLE_COLOR: "车辆颜色" }, -->
{ VEHICLE_NUMBER_TYPE: "机动车号牌种类" },
{ CAR_NUMBER: "车牌号" }
</pre>
</div>
</el-collapse-item>
<el-collapse-item title="字体图标组件" name="2">
<div>
<SvgIcon class="manIcon" icon="man"></SvgIcon>
<p>SvgIcon组件 本地图标 icon传入对应文件名即可</p>
<p>线上图标 icon 直接传入在线链接</p>
</div>
</el-collapse-item>
<el-collapse-item title="地图demo" name="3">
<el-button type="primary" @click="toTSFX">查看演示</el-button>
<el-button type="primary" @click="toBaidu">百度地图</el-button>
</el-collapse-item>
</el-collapse>
</div>
</el-form>
</div>
</template>
<script setup>
//引用组件必备
import ChooseUser from "@/components/MyComponents/ChooseUser";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
//引用组件必备
import { getSystemMeny } from "@/api/user-manage";
import { ElMessage } from "element-plus";
import { ref, reactive } from "vue";
import { useRouter } from "vue-router";
const selectAll = [
{
dictElementEnum: "NATION",
name: "民族"
},
{
dictElementEnum: "GENDER",
name: "性别"
},
{
dictElementEnum: "BLOOD_TYPE",
name: "血型"
},
{
dictElementEnum: "EDUCATION",
name: "学历"
},
{
dictElementEnum: "POLITICAL_OUTLOOK",
name: "政治面貌"
},
{
dictElementEnum: "MARITAL_STATUS",
name: "婚姻状况"
},
{
dictElementEnum: "RELATIONSHIP",
name: "亲属关系"
}
// {
// dictElementEnum: "VEHICLE_MODEL",
// name: "车辆型号"
// },
// {
// dictElementEnum: "VEHICLE_COLOR",
// name: "车辆颜色"
// },
// {
// dictElementEnum: "VEHICLE_NUMBER_TYPE",
// name: "机动车号牌种类"
// }
// { dictElementEnum: "CAR_NUMBER", name: "车牌号" }
];
const selectForm = ref({});
const form = reactive({
identityCard: "",
phone: "",
packageSelect: "",
// frameWork: '73At4FDoFFC',
frameWork: ["73At4FDoFFC", "83At4FDAFFC"],
carnumber: "川A80R00",
address: ["51", "5101", "510107", "5101041"],
email: "",
marriage: "",
nation: "",
upload: [],
deptIds: "7",
markdownEdit: ""
});
const activeNames = ref(["1"]);
const rules = ref({
...rule.phoneRule({
require: true,
validator: true
}), // 是否必填 是否进行校验
// ...rule.phoneRule({ validator: true },'telePhone'), // 是否必填 是否进行校验 如果props与from里面数据不一致可以传第二个参数
...rule.identityCardRule(
{
require: true,
validator: true
},
"identityCard"
), //身份证校验
...rule.carNumberRule({
require: true,
validator: true
}), //车牌号校验
...rule.nationSelectRule({
require: true
}), //民族校验
...rule.frameWorkRule(
{
require: true
},
"frameWork"
), //组织机构
...rule.departmentRule(
{
require: true
},
"department"
), //部门
...rule.addressSelectRule({
require: true
}), //地址
...rule.emailRule({
require: true,
validator: true
}), //邮箱
test: [
{
required: true,
message: "自定义表单参考element",
trigger: "blur"
},
{
min: 3,
max: 5,
message: "自定义表单参考element",
trigger: "blur"
}
],
packageSelect: [
{
required: true,
message: "请选择",
trigger: "change"
}
],
other: [
{
required: true,
message: "other校验,剩下的你可以自由发挥哦",
trigger: "blur"
}
],
iconName: [
{
required: true,
message: "请输入图标名称",
trigger: "change"
}
]
});
const chooseUserVisible = ref(false);
const formRef = ref(null);
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
ElMessage.error("校验成功!");
} else {
ElMessage.error("校验失败,请完成必填项!");
return false;
}
});
};
// =================民族================
const handleSelectChange = (data) => {
};
// =================组织机构================
const treeData = [
{
id: "73A64FDAFFC",
name: "总裁办",
children: [
{
id: "73At4FDoFFC",
name: "张三"
},
{
id: "73At4FpAFFC",
name: "李四"
},
{
id: "73AtwFDAFFC",
name: "数据中心",
children: [
{
id: "13At4FDAFFC",
name: "王五"
},
{
id: "83At4FDAFFC",
name: "赵武"
},
{
id: "83Al4FDAFFC",
name: "通讯中心",
children: [
{
id: "73At4FmAFFC",
name: "谢一"
},
{
id: "73At4FpAFFC",
name: "谢四"
}
]
}
]
}
]
},
{
id: "72A64FDAFFC",
name: "技术部",
children: [
{
id: "73At4FDAFFC",
name: "赵小刚"
},
{
id: "73AtuFDAFFC",
name: "李小刚"
},
{
id: "73yt4FDAFFC",
name: "王小刚"
}
]
}
];
//选择用户
const hanlderChoose = (users) => {
};
const defaultProps = {
children: "children",
label: "name"
};
const frameWorkChange = (data) => {
let nameArr = [];
data.forEach((el) => {
nameArr.push(el.name);
});
form.frameWork = nameArr;
};
// =================车牌号================
const carnumberChange = (data) => {
form.carnumber = data;
};
// =================地址================
const defaultConf = {
children: "children",
label: "name",
id: "code"
};
// 新的文件上传返回
const changeFile = (data) => {
};
const addressChange = (data) => {
form.address = data;
};
const phoneChange = (data) => {
};
const identityCardChange = (data) => {
};
const handleUpload = (data) => {
form.upload = [...data];
};
//跳转地图示例
const router = useRouter();
const DDZHhref = router.resolve({
name: "mapdemo", //这里是跳转页面的name
path: "/mapdemo"
});
const BDMAP = router.resolve({
name: "bdMap", //这里是跳转页面的name
path: "/bdMap"
});
function toTSFX() {
window.open(DDZHhref.href, "_blank");
}
function toBaidu(){
window.open(BDMAP.href, "_blank");
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/element-plus.scss";
// @import "~@/styles/mixin.scss";
// .el-form-box{
// display: flex;
// justify-content: flex-start;
// flex-wrap: wrap;
// .el-form-item{
// margin-right: 30px;
// }
// }
.component-card-title {
@include text-overflow;
}
.accordion-box {
.from-wrap {
width: 300px;
}
::v-deep .el-collapse-item__content {
display: flex;
justify-content: flex-start;
.left-wrap {
width: 350px;
@include text-overflow;
}
.right-wrap {
width: 700px;
}
}
}
</style>
<!----
// 备注1 普通的script标签 只在组件首次引入的时候执行一次, script setup会在每次 “组件实例被创建的时候执行”
//区别 普通script标签相当于是全局的 。 setup函数里面的 只在setup当前局部有效
// 备注2.2 顶层绑定将会主动暴露给模板
// 备注3 compiler Macros宏命令 它是编译器或者解释器 预先定义好的一系列可以替换的规则
//宏 是一种批量处理的称谓 它是抽象的概念, 解释器遇到宏时 会自动进行模式替换 ,或动作转化为一系列指令
---->

View File

@ -0,0 +1,93 @@
<template>
<div class="component-card-container">
<div class="component-card-title">基础组件封装 使用描述</div>
{{ validateObj }}
<el-collapse v-model="activeNames">
<el-collapse-item title="Form表单封装" name="1">
<div class="left-wrap">
<div class="from-wrap">
<IdentityCard v-model="formData.identity" prop="identity" :isRequired="true"
@validateStatus="changeValidate" placeholder="请输入身份证号"></IdentityCard>
<Phone v-model="formData.phone" prop="phone" @blur="blurTest()" maxlength="11" show-word-limit
@validateStatus="changeValidate"></Phone>
<Email v-model="formData.email" prop="identity" @validateStatus="changeValidate" placeholder="请输入邮箱">
</Email>
<el-button type="success" @click="validateData()">一键校验form</el-button>
</div>
</div>
<div class="right-wrap">
<pre>
1.正常引入组件随着父级元素自适应宽度
import IdentityCard from '@/components/From/IdentityCard/index'
import Phone from '@/components/From/Phone/index'
2.使用组件 已把校验封装到组件里 支持element 属性 事件
3.*正常使用组件 如需使用 required 请单独传入 :isRequired="true" element bug避免校验出现英文的情况
4. 如果需要 一键 校验表单 请调用 validateData() 方法 返回Boolean值
</pre>
</div>
</el-collapse-item>
<el-collapse-item title="民族选择组件" name="2">
<div>next</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus';
import IdentityCard from '@/components/From/IdentityCard/index'
import Phone from '@/components/From/Phone/index'
import Email from '@/components/From/Email/index'
const activeNames = ref(['1'])
const formData = ref({})
const blurTest = (e) => {
}
/****一键校验 bengin*****/
const validateObj = ref({})
const changeValidate = (e) => {
const [key, value] = [...Object.entries(e)[0]]
validateObj.value[key] = value;
return !Object.values(validateObj.value).includes(false)
}
const verifySuccess = computed(() =>
!Object.values(validateObj.value).includes(false)
)
const validateData = () => {
if (verifySuccess.value) {
ElMessage.success("校验通过")
} else {
ElMessage.error("校验失败")
}
}
/****校验代码end*****/
</script>
<style lang="scss" scoped>
.component-card-container {
.component-card-title {
padding-bottom: 20px;
}
.from-wrap {
width: 300px;
}
::v-deep .el-collapse-item__content {
display: flex;
justify-content: flex-start;
.left-wrap {
width: 350px;
@include text-overflow;
}
.right-wrap {
width: 700px;
}
}
}
</style>

View File

@ -0,0 +1,32 @@
<template>
<div class="developer-container">
<el-card>
<el-tabs v-model="activeName">
<el-tab-pane label="Demo1" name="feature">
<ComponentCard></ComponentCard>
</el-tab-pane>
<el-tab-pane label="Demo2表单弃用" name="section">
<Section></Section>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</template>
<script setup>
import { ref } from "vue";
import ComponentCard from "./components/ComponentCard.vue";
import Section from "./components/Section.vue";
const activeName = ref("feature");
</script>
<style lang="scss" scoped>
.developer-container {
margin: 20px 0 0 0;
.user-card {
margin-right: 20px;
}
}
</style>