This commit is contained in:
ln1778 2024-05-06 14:57:20 +08:00
parent 8e5cd84cd4
commit 3cec961d0e
15 changed files with 2046 additions and 0 deletions

303
CommonInput/Composite.vue Normal file
View File

@ -0,0 +1,303 @@
<template>
<div>
<el-input
:placeholder="content"
v-model="form.value"
class="input-with-select"
:size="size"
@input="input"
@keydown.enter.native="Enter"
>
<el-select
v-model="form.select"
slot="prepend"
:placeholder="name"
class="dateselect"
:style="width"
@change="input"
@keydown.enter.native="Enter"
>
<template slot="prefix">
{{ (data.find((e) => e.value == form.select) || {}).label }}
</template>
<el-option
v-for="item in data"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-input>
</div>
</template>
<script>
export default {
name: "Composite",
props: {
size: {
type: String,
default: "small",
},
width: {
type: Number,
default: 50,
},
name: {
type: String,
default: "",
},
default: {
default: null,
},
content: {
type: String,
default: "",
},
data: {
type: Array,
default: () => {
return [];
},
},
enName: {
type: String,
default: "",
},
},
components: {},
data() {
return {
form: {
value: "",
select: this.default,
enName: this.enName,
},
};
},
methods: {
//
input() {
this.$emit("CompositeVal", this.form);
},
//
Enter() {
// this.$emit("select", this.form);
},
},
};
</script>
<style scoped lang='scss'>
::v-deep .input-with-select .el-input-group__prepend {
background-color: #fff;
border: none !important;
}
::v-deep .el-input--prefix .el-input__inner {
padding-left: 15px;
}
::v-deep .dateselect {
color: #606266;
text-align: start;
.el-input__prefix {
position: relative;
left: 0;
padding: 0 20px 0 18px;
box-sizing: border-box;
color: #606266;
visibility: hidden;
}
.el-input__inner {
padding: 0 0 0 15px;
border-radius: 4px 0 0 4px;
z-index: 1;
}
.el-input__suffix {
display: flex;
align-items: flex-start;
z-index: 50;
margin-top: 1px;
}
.el-input__inner {
position: relative;
left: 0;
border: 1px solid #dcdfe6 !important;
}
}
::v-deep .el-select {
margin: 0 -21px !important;
box-sizing: border-box;
}
::v-deep .el-input__inner:hover {
position: relative;
z-index: 99 !important;
border: 1px solid #c0c4cc !important;
}
::v-deep .el-input__inner:focus {
position: relative;
z-index: 99 !important;
border: 1px solid #1890ff !important;
}
</style>
<!-- 两个select下拉框联动 -->
<!-- <template>
<div>
<el-input
placeholder="请输入内容"
v-model="value"
class="input-with-select"
:size="size"
>
<el-select
v-model="select"
slot="prepend"
placeholder="请选择"
class="dateselect"
>
<template slot="prefix">
{{ (PopUp.find((e) => e.enName == select) || {}).lable }}
</template>
<el-option
v-for="item in PopUp"
:key="item.enName"
:label="item.lable"
:value="item.enName"
>
</el-option>
</el-select>
<el-select
v-model="select"
slot="prepend"
placeholder="请选择"
class="dateselect dateselect-two"
>
<template slot="prefix">
{{ (PopUp.find((e) => e.enName == select) || {}).lable }}
</template>
<el-option
v-for="item in PopUp"
:key="item.enName"
:label="item.lable"
:value="item.enName"
>
</el-option>
</el-select>
</el-input>
</div>
</template>
<script>
export default {
props: {
size: {
type: String,
default: "small",
},
data: {
type: Array,
default: () => {
return [];
},
},
formLabelAlign: {
type: Object,
default: () => {
return {};
},
},
},
components: {},
data() {
return {
value: "",
select: "",
};
},
computed: {
//
PopUp() {
if (!this.data) return;
return this.data.filter((item) => item.isPopUp);
},
},
methods: {},
};
</script>
<style scoped lang='scss'>
::v-deep .el-select .el-input {
// flex: 1;
width: 100px;
}
::v-deep .input-with-select .el-input-group__prepend {
background-color: #fff;
border: none !important;
padding: 0;
}
::v-deep .el-input--prefix .el-input__inner {
padding-left: 15px;
}
::v-deep .dateselect {
// min-width: 105px;
color: #606266;
text-align: start;
.el-input__prefix {
position: relative;
left: 0;
padding: 0 10px 0 30px;
box-sizing: border-box;
color: #606266;
visibility: hidden;
}
.el-input__inner {
padding: 0 0 0 15px;
border-radius: 4px 0 0 4px;
z-index: 1;
}
.el-input__suffix {
display: flex;
align-items: flex-start;
z-index: 50;
margin-top: 1px;
}
.el-input__inner {
position: relative;
margin-left: 2px;
left: 0;
border: 1px solid #dcdfe6 !important;
}
}
::v-deep .el-select {
margin: 0 0px !important;
box-sizing: border-box;
}
::v-deep .el-input__inner:hover {
position: relative;
z-index: 50;
border: 1px solid #c0c4cc !important;
}
::v-deep .el-input__inner:focus {
position: relative;
z-index: 55;
border: 1px solid #1890ff !important;
}
::v-deep .dateselect-two {
.el-input__inner {
border-radius: 0px;
margin-left: 1px;
}
}
::v-deep .dateselect-two:hover {
.el-input__inner {
z-index: 999;
}
}
</style> -->

233
CommonInput/Compound.vue Normal file
View File

@ -0,0 +1,233 @@
<template>
<div>
<el-form label-position="top" :inline="true" class="popover">
<el-select
v-model="select"
placeholder="请选择"
class="dateselect"
:size="size"
@keydown.enter.native="Enter"
>
<template slot="prefix">
{{ (PopUp.find((e) => e.enName == select) || {}).lable }}
</template>
<el-option
v-for="item in PopUp"
:key="item.enName"
:label="item.lable"
:value="item.enName"
>
</el-option>
</el-select>
<el-popover
placement="bottom"
trigger="manual"
ref="popover"
popper-class="popperOptions"
v-model="popBox"
>
<el-input
v-model="textarea"
type="textarea"
:rows="12"
placeholder="一行一项最多支持200行"
resize="none"
@input="changeText('textarea')"
/>
<el-divider class="divider"></el-divider>
<div class="btnbox">
<div>
<el-button size="mini" @click="close">关闭</el-button>
</div>
<div>
<el-button size="mini" @click="clear">清空</el-button>
<el-button size="mini" type="primary" plain @click="Enter"
>查询</el-button
>
</div>
</div>
<el-input
slot="reference"
v-model="value"
:size="size"
class="compound-input"
:placeholder="placeholder"
@input="changeText('value')"
@keydown.enter.native="Enter"
>
<i
slot="suffix"
class="iconfont iconicon-piliangcaozuo imeiicondefault"
:class="popBox ? 'imeiiconActive' : 'imeiicon'"
style="font-size: 12px; margin-top: 4px"
@click.prevent="eject"
></i>
</el-input>
</el-popover>
</el-form>
</div>
</template>
<script>
export default {
name:'Compound',
props: {
size: {
type: String,
default: "small",
},
default: {
default: "imei",
},
data: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {
select: this.default,
value: "",
textarea: "",
values: "",
popBox: false,
placeholder: "请输入内容",
};
},
computed: {
//
PopUp() {
if (!this.data) return;
return this.data.filter((item) => item.isPopUp);
},
},
methods: {
changeText(mark) {
const rep = /[^\s]+/g;
let values = "";
if (mark == "textarea") {
this.value = "";
values = this._.words(this.textarea, rep).join();
} else {
this.textarea = "";
values = this.value;
}
this.values = values;
},
//
eject() {
this.popBox = !this.popBox;
},
//
clear() {
this.disable = false;
this.textarea = "";
},
//
close() {
this.popBox = false;
},
//
Enter() {
console.log(this.select, this.values, "++++++this.value, imeisn");
},
},
};
</script>
<style scoped lang='scss'>
.popover {
width: 330px;
display: flex;
line-height: 0;
span {
width: 100%;
}
}
::v-deep .dateselect {
flex-grow: 0;
flex-shrink: 0;
min-width: 105px;
max-width: 155px;
color: #fff;
text-align: start;
.el-input__prefix {
position: relative;
top: 0;
left: 0;
padding: 0 35px 0 18px;
box-sizing: border-box;
color: #606266;
visibility: hidden;
}
.el-input {
height: 100%;
}
.el-input__inner {
padding: 0 15px;
border-radius: 4px 0 0 4px;
z-index: 1;
}
.el-input__inner:hover {
z-index: 1;
}
.el-input__suffix {
display: flex;
align-items: flex-start;
z-index: 50;
}
.el-input__inner {
position: absolute;
left: 0;
}
}
::v-deep .compound-input {
flex-grow: 1;
margin-left: -1px;
.imeiicondefault {
padding: 5px;
border-radius: 4px;
background: #f0f2f5;
cursor: pointer;
}
.imeiiconActive {
color: #409eff;
background: #e9f1fc;
}
.el-input__inner {
position: relative;
border-radius: 0 4px 4px 0 !important;
}
.el-input__inner:hover {
position: relative;
z-index: 1;
}
.el-input.is-active .el-input__inner,
.el-input__inner:focus {
position: relative;
z-index: 1;
}
.el-input__suffix {
display: flex;
align-items: center;
z-index: 50;
}
}
.btnbox {
padding: 5px;
display: flex;
justify-content: space-between;
border: none;
}
.divider {
margin: 0;
}
::v-deep .el-textarea__inner {
border: none;
}
</style>

82
CommonInput/ErpEchart.vue Normal file
View File

@ -0,0 +1,82 @@
<template>
<div :id="uuid" :style="style"></div>
</template>
<script>
import * as echarts from "echarts";
const idGen = () => {
return new Date().getTime();//id
};
export default {
name:'ErpEchart',
props: {
height: {
type: String,
default: "400px",
},
width: {
type: String,
default: "600px",
},
options: {
type: Object,
default: null,
},
},
data() {
return {
uuid: null,
myChart: null,
};
},
watch: {
width(a, b) {
if (this.myChart) {
//
setTimeout(() => {
this.myChart.resize({
animation: {
duration: 500,
},
});
}, 0);
}
},
options() {
if (this.myChart) {
// notMerge option false
// true option
this.myChart.setOption(this.options, {
notMerge: true,
});
}
},
},
computed: {
style() {
return {
height: this.height,
width: this.width,
};
},
},
created() {
this.uuid = idGen();
},
mounted() {
//
this.myChart = echarts.init(document.getElementById(this.uuid));
//
this.myChart.setOption(this.options);
},
};
</script>

12
CommonInput/ErpEcharts.md Normal file
View File

@ -0,0 +1,12 @@
## ErpEcharts 图表封装
> **组件名ErpEcharts**
> 代码块: `ErpEcharts`
> 关联组件:`echarts`
> **子组件:传参**
> options组件接收的参数直接去echarts图表中复制option传到组件即可
> width: "600px",----------------------------图表宽度(选填)
> height: "400px",----------------------------图表高度(选填)
> **注意事项**
> 循环多个图表时this.uuid必须为唯一值

126
CommonInput/MoreClass.md Normal file
View File

@ -0,0 +1,126 @@
## MoreClass 级联选择器弹出层
> **组件名MoreClass**
> 代码块: `MoreClass`
> 关联组件:`el-element`
> **子组件:传参**
> data组件接收的参数默认为[] 其中classifiable等于true的时候默认到该组件
> lable: "分类",----------------------------输入框名称(选填)
> type: "el-select",------------------------输入框类型el-inpit,el-selec组件没用到但最好必填
> enName: "cate_id",------------------------返回值与model双向绑定必填
> placeholder: "请选择机器类型",-------------输入框占位文本(选填)
> size: "small",----------------------------输入框大小(选填)
> show: true,-------------------------------是否展示(必填)
> filterable: true,-------------------------是否可搜索(选填)
> clearable: true,--------------------------是否可清除(选填)
> classifiable: true,-----------------------是否分类,使用组件必填(必填)
> disabled: false,--------------------------是否禁用(选填)
> loading: false,---------------------------加载效果(选填)
> options: [],------------------------------输入框下拉的值,父组件调用接口传递
> formLabelAlign组件返回的参数与v-model双向绑定{}
> disabled组件是否禁用默认false
> size:组件大小默认值small
> width组件宽度默认450
> Title组件最外层占位文本默认为请选择分类/品牌/型号
> **子组件:方法**
> SearchClass点击查询后直接父组件中打印formLabelAlign的值
> ClearInput父组件绑定ref直接调用子组件ClearInput方法然后子组件会给父组件抛出一个resetfrom方法在父组件resetfrom中清空formLabelAlign中的邦定值
> **父组件:方法**
> getphonetype():父组件中获取第一条分类数据
> SelectChange():选择数据后调用 后面是处理方法其中如果不是同一个接口resetFields中的值需要改变后续代码也要修改
SelectChange(item) {
const resetFields = {
cate_id: ["brand_id", "model_id", "color_id", "rom_id"],
brand_id: ["model_id", "color_id", "rom_id"],
model_id: ["color_id", "rom_id"],
};
Object.entries(resetFields).forEach(([field, resetFields]) => {
if (item.enName === field) {
resetFields.forEach((field) => {
this.formLabelAlign[field] = "";
this.input.find((res) => res.enName === field).options = [];
});
}
});
/** 获取型号 颜色 容量*/
if (item.enName == "cate_id" && this.formLabelAlign.cate_id != "") {
this.getqualityinfo(
{ cate_id: this.formLabelAlign.cate_id },
1,
"brand_id"
);
} else if (
item.enName == "brand_id" &&
this.formLabelAlign.brand_id != ""
) {
this.getqualityinfo(
{
cate_id: this.formLabelAlign.cate_id,
brand_id: this.formLabelAlign.brand_id,
},
2,
"model_id"
);
} else if (
item.enName == "model_id" &&
this.formLabelAlign.model_id != ""
) {
this.getqualityinfo(
{
cate_id: this.formLabelAlign.cate_id,
brand_id: this.formLabelAlign.brand_id,
model_id: this.formLabelAlign.model_id,
},
3,
"color_id"
);
}
},
// 获取品牌,颜色,模型数据
async getqualityinfo(data, val, itm) {
this.input.forEach((item) => {
if (item.enName == itm) {
item.loading = true;
}
});
try {
const res = await cate_brand_list_in_stock(data);
this.input.forEach((item) => {
if (item.enName == itm) {
item.loading = false;
}
});
if (res.errcode !== 0) return;
if (val == 1) {
this.updateInputOptions("brand_id", res.datas);
} else if (val == 2) {
this.updateInputOptions("model_id", res.datas);
} else {
this.updateInputOptions("rom_id", res.datas.rom_list);
this.updateInputOptions("color_id", res.datas.color_list);
}
} catch (error) {
// 处理错误
console.error(error);
}
},
处理数据
updateInputOptions(enName, list) {
const mappedList = Array.isArray(list)
? list.map((item) => ({ label: item.label, value: item.value }))
: [];
this.input.forEach((r, i) => {
if (r.enName === enName) {
if (
r.enName !== "model_id" &&
r.enName !== "cate_id" &&
r.enName !== "brand_id"
) {
this.input[i].show =
Array.isArray(list) && list.length ? true : false;
}
this.input[i].options = mappedList;
}
});
},

211
CommonInput/MoreClass.vue Normal file
View File

@ -0,0 +1,211 @@
<template>
<div class="machinemore">
<el-popover
placement="bottom"
:offset="90"
:width="width"
v-model="classvisible"
trigger="manual"
popper-class="machine-box"
>
<el-form label-position="top" :inline="true">
<el-row :gutter="10">
<el-col :span="12" v-for="(item, index) in ClassData" :key="index">
<el-form-item
:label="item.lable"
:prop="item.prop"
v-show="item.show"
>
<el-select
v-model="formLabelAlign[item.enName]"
:size="item.size"
:placeholder="item.placeholder"
:clearable="item.clearable"
:filterable="item.filterable"
:disabled="item.disabled"
v-loading="item.loading"
@change="SelectChange(item, formLabelAlign[item.enName])"
@clear="Selectclear()"
>
<el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="btnbox1">
<el-button size="mini" plain @click="CancelClass">取消</el-button>
<el-button size="mini" type="primary" plain @click="SearchClass"
>查询</el-button
>
</div>
<el-input
readonly
slot="reference"
v-model="classval"
:placeholder="Title"
:size="size"
:disabled="disabled"
clearable
@focus="FocusInput"
@change="changeInput"
></el-input>
</el-popover>
</div>
</template>
<script>
export default {
name:'MoreClass',
props: {
disabled: {
type: Boolean,
default: false,
},
size: {
type: String,
default: "small",
},
width: {
type: String,
default: "450",
},
Title: {
type: String,
default: "请选择分类/品牌/型号",
},
data: {
type: Array,
default: () => {
return [];
},
},
formLabelAlign: {
type: Object,
default: () => {
return {};
},
},
},
components: {},
data() {
return {
classvisible: false, //
classval: "", //-input
result: [],
};
},
computed: {
//-
ClassData() {
if (!this.data) return;
return this.data.filter((item) => item.classifiable);
},
},
methods: {
// input
//
FocusInput() {
this.classvisible = true;
},
//
changeInput() {},
//
ClearInput() {
this.classval = "";
this.classvisible = false;
this.$emit("resetfrom");
},
// select
//
SelectChange(item, val) {
this.$emit("SelectChange", item);
this.result = this.result.filter((e) => e);
const selectedOption = item.options.find((i) => i.value === val);
if (selectedOption) {
selectedOption.enName = item.enName;
}
const index = this.result.findIndex((e) => e.enName === item.enName);
if (index >= 0) {
if (this.ClassData.every((e) => e.options.length)) {
this.result.splice(index, 1, selectedOption);
} else {
this.result.splice(index, this.ClassData.length, selectedOption);
}
} else {
this.result.push(selectedOption);
}
this.classval = this.result
.filter((e) => e)
.map((e) => e.label)
.join("/");
},
//
Selectclear() {},
//
//
SearchClass() {
this.$emit("SearchClass");
},
//
CancelClass() {
this.classvisible = false;
},
},
};
</script>
<style scoped lang='scss'>
.machinemore {
width: 230px;
}
.machine-box {
height: 275px !important;
display: flex;
flex-wrap: wrap;
.machine {
margin-bottom: 5px;
}
.btnbox1 {
width: 100%;
display: flex;
justify-content: flex-end;
}
.el-form {
width: 100%;
}
.el-form-item {
width: 100%;
margin: 0px;
}
.el-select {
width: 100%;
}
}
::v-deep .el-form-item__label {
padding: 0px !important;
height: 20px;
line-height: 20px;
}
::v-deep .el-form-item__content {
line-height: 32px;
}
::v-deep .el-loading-spinner {
height: 32px;
margin-top: -15px;
.circular {
height: 26px !important;
width: 26px !important;
}
}
</style>

138
CommonInput/MoreScreen.vue Normal file
View File

@ -0,0 +1,138 @@
<template>
<div class="morescreen">
<el-popover
popper-class="machinebox"
placement="bottom"
width="450"
trigger="manual"
ref="popover"
v-model="visible"
>
<!-- 下拉项不需要合并的 -->
<el-form label-position="top" label-width="90px" :inline="true">
<el-row :gutter="10">
<el-col :span="12" v-for="(item, index) in screenList" :key="index">
<el-form-item
:label="item.label"
:prop="item.prop"
v-show="item.show"
>
<div
:is="item.type"
v-model="formLabelAlign[item.enName]"
:placeholder="item.placeholder"
:clearable="item.clearable"
:filterable="item.filterable"
:size="item.size"
:multiple="item.multiple"
collapse-tags
>
<el-option
v-for="item in item.options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="morebtnbox">
<el-button size="mini" plain @click="cancel">取消</el-button>
<el-button size="mini" type="primary" plain @click="search"
>查询</el-button
>
</div>
<el-button
slot="reference"
size="small"
@click="morescreen"
class="morescreen"
>更多筛选</el-button
>
</el-popover>
</div>
</template>
<script>
export default {
name:'MoreScreen',
props: {
data: {
default: () => {
return [];
},
},
formLabelAlign: {
type: Object,
default: () => {
return {};
},
},
},
components: {},
data() {
return {
visible: false, //
};
},
computed: {
screenList() {
if (!this.data) return;
return this.data.filter((item) => item.MoreScreen);
},
},
methods: {
//
morescreen() {
this.visible = !this.visible;
},
//-
cancel() {
this.visible = false;
},
//-
search() {
this.visible = false;
this.$emit("search");
},
},
};
</script>
<style scoped lang='scss'>
.morescreen{
display: inline-block;
}
.machinebox {
.el-form-item {
width: 100%;
margin: 0px;
}
.el-input {
margin: 0px !important;
}
.el-select {
width: 100%;
margin: 0px !important;
}
}
::v-deep .el-form-item__label {
height: 20px;
line-height: 20px;
padding: 0 !important;
}
.morebtnbox {
width: 100%;
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
.el-row {
display: flex;
flex-wrap: wrap;
}
</style>

View File

@ -0,0 +1,21 @@
## TimingModule 时间选择器
> **组件名TimingModule**
> 代码块: `TimingModule`
> 关联组件:`el-element`
> **子组件:传参**
> data组件接收的参数默认为[] 其中type等于el-date-picker的时候默认到该组件
> lable: "分类名称",----------------------------输入框名称(必填)
> type: "el-date-picker",------------------------输入框类型el-date-picker必填
> TimeType:daterange(daterange为时间段date为当前时间)
> enName: "time",------------------------返回值与model双向绑定必填
> show: true,-------------------------------是否展示(必填)
> size:组件大小默认值small
> default:默认参数
> **子组件:方法**
> getDateTime子组件抛出一个getDateTime(a,b)接受两个参数a为下拉选择器的值b为时间值
> **注意事项**
> 循环多个图表时this.uuid必须为唯一值

View File

@ -0,0 +1,317 @@
<template>
<div class="TimingModule">
<el-select
v-model="select"
placeholder="请选择"
class="dateselect"
:size="size"
@change="selectChange"
>
<template slot="prefix">
{{ (timer.find((e) => e.enName == select) || {}).lable }}
</template>
<el-option
v-for="item in timer"
:key="item.enName"
:label="item.lable"
:value="item.enName"
>
</el-option>
</el-select>
<el-date-picker
v-show="timer[Index].TimeType == 'daterange'"
class="datepicker"
v-model="DateTime"
value-format="timestamp"
:picker-options="pickerOptions"
:size="size"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
@change="timeChange"
>
</el-date-picker>
<el-date-picker
v-show="timer[Index].TimeType == 'date'"
v-model="Time"
:size="size"
align="right"
type="date"
clearable
value-format="yyyy-MM-dd"
placeholder="选择日期"
:picker-options="pickerOption"
@change="timeChange"
>
</el-date-picker>
</div>
</template>
<script>
export default {
name:'TimingModule',
props: {
default: {
default: null,
},
size: {
type: String,
default: "small",
},
data: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {
select: this.default, //
DateTime: [],
Time: "",
pickerOptions: {
disabledDate(time) {
return (
time.getTime() >
new Date(new Date().toLocaleDateString()).getTime() +
24 * 60 * 60 * 1000 -
1
);
},
shortcuts: [
{
text: "本月",
onClick(picker) {
const end =
new Date(new Date().toLocaleDateString()).getTime() +
24 * 60 * 60 * 1000 -
1;
const time = new Date();
time.setDate(1);
time.setHours(0);
time.setSeconds(0);
time.setMinutes(0);
var start = time.getTime();
picker.$emit("pick", [start, end]);
},
},
{
text: "近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
{
text: "近六个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 180);
picker.$emit("pick", [start, end]);
},
},
{
text: "近一年",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 360);
picker.$emit("pick", [start, end]);
},
},
],
}, //
pickerOption: {
disabledDate(time) {
return time.getTime() > Date.now();
},
shortcuts: [
{
text: "近一周",
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 7 * 24 * 60 * 60 * 1000);
picker.$emit("pick", date);
},
},
{
text: "近一个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 1);
picker.$emit("pick", date);
},
},
{
text: "近三个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 3);
picker.$emit("pick", date);
},
},
{
text: "近六个月",
onClick(picker) {
const date = new Date();
date.setMonth(date.getMonth() - 6);
picker.$emit("pick", date);
},
},
{
text: "近一年",
onClick(picker) {
const date = new Date();
date.setFullYear(date.getFullYear() - 1);
picker.$emit("pick", date);
},
},
],
}, //
Index: 0,
};
},
computed: {
timer() {
if (!this.data) return;
return this.data.filter((item) => item.type === "el-date-picker");
},
},
methods: {
//
selectChange(val) {
this.timer.forEach((e, i) => {
if (e.enName == val) {
this.Index = i;
}
});
this.screen();
},
//
timeChange(e) {
this.screen();
},
//
screen() {
if (
this.timer.find((e) => e.enName == this.select).TimeType == "daterange"
) {
this.$emit("getDateTime", this.select, this.DateTime);
console.log(this.select, this.DateTime);
} else if (
this.timer.find((e) => e.enName == this.select).TimeType == "date"
) {
this.$emit("getDateTime", this.select, this.Time);
console.log(this.select, this.Time);
}
},
},
};
</script>
<style scoped lang='scss'>
.TimingModule {
width: 380px;
display: flex;
span {
width: 100%;
}
.el-input__suffix {
z-index: 1;
}
.el-input__inner:hover,
.el-select:hover .el-input__inner {
position: relative;
z-index: 1;
}
.el-range-editor.is-active,
.el-range-editor.is-active:hover,
.el-select .el-input.is-focus .el-input__inner {
position: relative;
z-index: 1;
}
.el-range-editor.el-input__inner {
border-radius: 0px 4px 4px 0px;
margin-left: -1px;
}
}
::v-deep .el-date-editor {
width: 100% !important;
.el-input__suffix {
z-index: 1;
}
.el-input__prefix {
z-index: 99;
}
.el-input__inner:hover {
position: relative;
z-index: 1;
}
.el-input__inner:focus {
position: relative;
z-index: 50;
}
.el-input__inner {
border-radius: 0px 4px 4px 0px;
margin-left: -1px;
}
}
::v-deep .dateselect {
flex-grow: 0;
flex-shrink: 0;
min-width: 105px;
max-width: 140px;
color: #fff;
text-align: start;
.el-input__prefix {
position: relative;
top: 0;
left: 0;
padding: 0 35px 0 18px;
box-sizing: border-box;
color: #606266;
visibility: hidden;
}
.el-input {
height: 100%;
}
.el-input__inner {
padding: 0 15px;
border-radius: 4px 0 0 4px;
z-index: 1;
}
.el-input__inner:hover {
z-index: 1;
}
.el-input__suffix {
display: flex;
align-items: flex-start;
z-index: 50;
}
.el-input__inner {
position: absolute;
left: 0;
}
}
</style>

116
CommonInput/app-title.vue Normal file
View File

@ -0,0 +1,116 @@
<template>
<div class="box">
<div v-show="shoptitle">
<p
class="hover-shoptitle"
@mouseover="handleMouseOver"
@mousemove="handleMouseMove"
@mouseout="handleMouseOut"
>
{{ shoptitle }}
</p>
<div
class="tooltip"
v-if="showTooltip"
:style="{ left: tooltipX + 'px', top: tooltipY + 'px' }"
>
{{ shoptitle }}
</div>
</div>
</div>
</template>
<script>
export default {
name:'appTitle',
props: ["shoptitle"],
data() {
return {
showTooltip: false,
tooltipX: 0,
tooltipY: 0,
};
},
components: {},
handleMouseOut() {
window.removeEventListener("scroll", this.updateTooltipPosition);
},
methods: {
handleMouseOver(event) {
this.showTooltip = true;
this.updateTooltipPosition(event);
},
handleMouseMove(event) {
this.updateTooltipPosition(event);
},
handleMouseOut() {
this.showTooltip = false;
},
updateTooltipPosition(event) {
if (!this.showTooltip) return;
this.tooltipX = event.clientX + 10;
this.tooltipY = event.clientY + 10;
},
},
};
</script>
<style scoped lang='scss'>
.box {
font-size: 14px;
font-weight: 400;
color: #000000;
margin-top: 5px;
}
.hover-trigger,
.hover-shoptitle {
font-weight: bold;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
height: 60px;
line-height: 20px;
text-overflow: ellipsis;
cursor: pointer;
}
.hover-shoptitle {
font-size: 14px;
color: #606266;
font-weight: 400;
-webkit-line-clamp: 3;
margin-bottom: 0;
}
.tooltip {
position: fixed;
top: 0px;
left: 0px;
width: 380px;
background-color: #fff;
padding: 2px 5px;
border-radius: 5px;
border: 1px solid;
z-index: 99;
}
.preferential {
display: inline-block;
background: #d6e4ff;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3478fd;
font-size: 12px;
font-weight: 400;
color: #3478fd;
padding: 5px 10px;
box-sizing: border-box;
}
.tooltip-preferential {
height: 28px;
color: #e61628;
background-color: #fff;
border: 1px solid;
line-height: 28px;
text-align: center;
}
</style>

15
CommonInput/compound.md Normal file
View File

@ -0,0 +1,15 @@
## Compound 多功能输入框(支持输入多组数据)
> **组件名Compound**
> 代码块: `Compound`
> 关联组件:`el-element`
> **子组件:传参**
> data组件接收的参数默认为[] 其中isPopUp等于true的时候默认到该组件
> lable: "IMEI/SN/机器编号",----------------------------输入框名称(选填)
> type: "el-select",------------------------输入框类型(必填)
> enName: "cate_id",------------------------返回值与model双向绑定必填
> size: "small",----------------------------输入框大小(选填)
> show: true,-------------------------------是否展示(必填)
> isPopUp: true,-----------------------是否分类,使用组件必填(必填)
> default组件默认值
> size:组件大小默认值small

12
CommonInput/selectbtn.md Normal file
View File

@ -0,0 +1,12 @@
## selectbtn 多功能多选组件(仅筛选,多选,反选,模糊查询选择操作)
> **组件名SelectBtn**
> 代码块: `selectbtn`
> 关联组件:`el-element`
> **子组件:传参**
> SourceData组件接收的参数默认为[{label:'',value:''}] 接口的数据
> dropdowntitle:组件占位文本
> value:返回值的字段名如value"name_id" 则search中parmas的接收参数为{name_id:['返回的参数']},参数为必填
> selectAll:默认false是否全选
> **子组件:方法**
> search(params):params接收选择的参数

405
CommonInput/selectbtn.vue Normal file
View File

@ -0,0 +1,405 @@
<template>
<el-dropdown
ref="messageDrop"
szie="mini"
trigger="click"
:hide-on-click="false"
@click.native="checkeddown"
:class="{ 'el-dropdown_active': !down }"
@visible-change="dropdownchange"
>
<span class="el-dropdown-link">
<span>
<span :class="{ color: selectvalue.length }">{{ dropdownvalue }}</span
><span class="list-length" v-if="valuelength >= 1"
>+ {{ valuelength }}</span
></span
><i
v-if="dropdownvalue == dropdowntitle"
class="el-icon-arrow-up el-icon--right"
:class="{ 'rotate-arrow': down }"
></i>
<i v-else class="el-icon-close el-icon--right" @click="clear"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-input
placeholder="请输入内容"
v-model="seek"
size="small"
class="el_input"
@input="inputblur"
@keydown.enter.prevent="confirm"
>
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
<div v-if="dataList && dataList.length" class="checkbox-group">
<div v-if="dataList && dataList.length > 1" class="all-checked">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
>全选</el-checkbox
>
/
<span @click="invert" class="invertstatus">反选</span>
</div>
<el-checkbox-group
class="checked-list"
:class="{ 'top-height': dataList && dataList.length <= 1 }"
v-model="checkedList"
@change="handleCheckedCitiesChange"
>
<div v-for="(el, id) in dataList" :key="id" class="setScore">
<el-checkbox :label="el.value">{{ el.label }}</el-checkbox>
<span @click="confirm(el, 'only')">仅筛选此项</span>
</div>
</el-checkbox-group>
</div>
<div v-else class="nothing">暂无数据</div>
<div class="btnbox">
<div>
<el-button size="mini" @click="cancel">取消</el-button>
<el-button size="mini" type="primary" plain @click="confirm"
>确定</el-button
>
</div>
</div>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
name:'selectbtn',
props: ["SourceData", "dropdowntitle", "value", "selectAll"],
data() {
return {
seek: "",
dropdownvalue: this.dropdowntitle,
valuelength: 0,
down: true,
checkAll: false,
checkedList: [],
dataList: [], //
isIndeterminate: false,
retract: false,
selectvalue: [], //
};
},
components: {},
watch: {
SourceData: {
handler(val) {
this.dataList = val;
this.checkedList = []; //-
if (this.selectAll && this.dataList) {
this.dataList.map((e) => {
this.checkedList.push(e.value);
});
this.confirm();
}
},
deep: true,
immediate: true,
},
},
methods: {
//
checkeddown() {
if (this.checkedList.length) {
this.checkedList = this.selectvalue;
} else {
this.checkedList = [];
}
this.checkedstatus();
},
dropdownchange() {
this.down = !this.down;
},
inputblur(queryString) {
this.dataList = queryString
? this.SourceData.filter(this.createFilter(queryString))
: this.SourceData;
this.checkedstatus();
},
createFilter(queryString) {
return (restaurant) => {
const lowerCaseQuery = queryString.toLowerCase();
const lowerCaseLabel = restaurant.label.toLowerCase();
//
return lowerCaseLabel.includes(lowerCaseQuery);
};
},
//
sortByMatch(queryString, a, b) {
const lowerCaseQuery = queryString.toLowerCase();
const scoreA = this.calculateMatchScore(lowerCaseQuery, a.label);
const scoreB = this.calculateMatchScore(lowerCaseQuery, b.label);
//
return scoreB - scoreA;
},
calculateMatchScore(query, label) {
const lowerCaseLabel = label.toLowerCase();
return lowerCaseLabel.includes(query)
? lowerCaseLabel.indexOf(query)
: Infinity;
},
handleCheckAllChange() {
this.isIndeterminate = false;
if (this.checkAll) {
this.dataList.map((item) => {
this.checkedList.push(item.value);
});
this.checkedList = [...new Set(this.checkedList)];
} else {
if (this.seek) {
this.checkedList = this.checkedList.filter((item) => {
const matchingItem = this.dataList.find((el) => el.value === item);
return !matchingItem;
});
} else {
this.checkedList = [];
}
}
},
//
checkedstatus() {
let every = this.dataList.every((item) => {
return this.checkedList.includes(item.value);
});
let some = this.dataList.some((item) => {
return this.checkedList.includes(item.value);
});
if (every && some) {
this.checkAll = true;
this.isIndeterminate = false;
} else if (!every && some) {
this.isIndeterminate = true;
} else {
this.checkAll = false;
this.isIndeterminate = false;
}
},
invert() {
this.dataList.forEach((item) => {
if (this.checkedList.includes(item.value)) {
this.checkedList = this.checkedList.filter(
(value) => value !== item.value
);
} else {
this.checkedList.push(item.value);
}
});
this.checkedstatus();
},
handleCheckedCitiesChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.dataList.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.dataList.length;
this.checkedstatus();
},
cancel() {
if (this.selectvalue.length == this.dataList.length) {
this.checkAll = true;
this.isIndeterminate = false;
} else {
this.isIndeterminate = true;
}
if (!this.selectvalue.length) {
this.checkedList = [];
this.checkAll = false;
this.isIndeterminate = false;
}
this.seek = "";
this.inputblur();
this.checkedList = this.selectvalue;
this.$refs.messageDrop.hide();
},
confirm(val, name) {
if (name == "only") {
this.checkedList = [];
this.checkedList.push(val.value);
}
let arr = [];
arr = this.SourceData.filter((el, id) => {
return this.checkedList.includes(el.value);
});
if (arr.length) {
this.dropdownvalue = arr[0].label;
} else {
this.dropdownvalue = this.dropdowntitle;
this.valuelength = 0;
}
this.selectvalue = this.checkedList;
this.valuelength = this.checkedList.length - 1;
let params = { [this.value]: this.selectvalue };
console.log(this.selectvalue.length, "测试params");
this.cancel();
this.$emit("search", params);
},
clear() {
this.dropdownvalue = this.dropdowntitle;
this.valuelength = 0;
this.seek = "";
this.selectvalue = [];
this.checkedList = [];
this.checkAll = false;
this.isIndeterminate = false;
this.inputblur();
this.$refs.messageDrop.hide();
},
},
};
</script>
<style scoped lang='scss'>
.el-dropdown {
width: 100%;
height: 32px;
line-height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
}
.el-dropdown:hover {
border: 1px solid #c0c4cc;
}
.el-dropdown_active {
border: 1px solid #409eff;
}
.el-dropdown_active:hover {
border: 1px solid #409eff;
}
.el-icon-arrow-up {
transform: rotate(0deg);
transition: transform 0.3s ease;
}
.rotate-arrow {
transform: rotate(180deg);
transition: transform 0.3s ease;
}
::v-deep .el_input {
padding: 0 10px;
.el-input__inner {
border-radius: 0px;
border: none;
border-bottom: 1px solid #dcdfe6;
}
.el-input__inner:hover {
border-bottom: 1px solid #409eff;
}
}
.el-dropdown-menu {
min-width: 400px;
padding: 10px 0 0 0;
}
.checkbox-group {
overflow: hidden;
padding: 5px 0px 0;
box-sizing: border-box;
}
.all-checked {
position: fixed;
span {
font-size: 14px;
color: #606266;
font-weight: 500;
cursor: pointer;
}
.invertstatus:hover {
color: #409eff;
}
}
.checked-list {
max-height: 180px;
margin-top: 25px;
overflow-y: auto;
padding: 5px 0;
box-sizing: border-box;
}
.top-height {
margin-top: 0px;
}
.el-checkbox-group {
display: flex;
flex-direction: column;
}
.el-checkbox {
margin-right: 0px !important;
padding: 5px 0px 5px 10px;
box-sizing: border-box;
}
.btnbox {
padding: 5px;
display: flex;
justify-content: right;
border-top: 1px solid #dcdfe6;
}
.el-dropdown-link {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
width: 100%;
min-width: 180px;
font-size: 13px;
font-weight: 500;
color: #c0c4cc;
cursor: pointer;
}
.list-length {
padding: 3px 7px;
margin-left: 10px;
border-radius: 4px;
color: #33333379;
background-color: #dcdfe6;
}
.color {
color: #333;
font-weight: normal;
}
:focus-visible {
outline: none;
}
.nothing {
min-height: 80px;
line-height: 80px;
text-align: center;
color: #c0c4cc;
}
.el-icon-close {
opacity: 0;
}
.el-icon-close:hover {
opacity: 1;
}
.setScore {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
font-size: 14px;
span {
display: none;
height: 30px;
line-height: 30px;
padding: 0 10px;
cursor: pointer;
}
}
.setScore:hover {
background-color: rgba(192, 196, 204, 0.267);
span {
display: block;
color: #409eff;
height: 100%;
}
}
</style>

36
index.js Normal file
View File

@ -0,0 +1,36 @@
import appTitle from "./CommonInput/app-title.vue";
import Composite from "./CommonInput/Composite.vue";
import Compound from "./CommonInput/Compound.vue";
import ErpEchart from "./CommonInput/ErpEchart.vue";
import MoreClass from "./CommonInput/MoreClass.vue";
import MoreScreen from "./CommonInput/MoreScreen.vue";
import selectbtn from "./CommonInput/selectbtn.vue";
import TimingModule from "./CommonInput/TimingModule.vue";
const componentarr = [
appTitle,
Composite,
Compound,
ErpEchart,
MoreClass,
MoreScreen,
selectbtn,
TimingModule,
];
const install = function (Vue) {
// 判断是否安装
if (install.installed) return;
install.installed = true;
// 遍历并注册全局组件
componentarr.forEach((component) => Vue.component(component.name, component));
};
// 判断是否是直接引入文件如果Vue是全局对象自动安装插件
if (typeof window !== "undefined" && window.Vue) {
install(window.Vue);
}
export default {
install,
...componentarr
}

19
package.json Normal file
View File

@ -0,0 +1,19 @@
{
"name": "erp-element-ui",
"version": "1.0.1",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "liunan",
"license": "ISC",
"peerDependencies": {
"element-ui": "^2.15.6"
},
"homepage": "https://git.aiguoai.com/liunan/erp-el-element.git",
"repository": {
"type": "git",
"url": "github.com/ln1778/taro-server.git"
}
}