自定义时间选择、多选下拉组件

This commit is contained in:
龙运模 2024-07-11 20:40:29 +08:00
parent 8cb52b4cad
commit 784be21ad3
10 changed files with 265 additions and 110 deletions

View File

@ -0,0 +1,64 @@
<!--
* @Descripttion: 日期选择组件
* @Author: 龙运模
* @Date: 2024年07月11日
* @LastEditors: 龙运模
* @LastEditTime:
-->
<template>
<div class="scDatePicker">
<el-date-picker v-bind="$attrs" class="input" v-model="localDatePicker" @change="dateChange" @input="emitActivationDate" type="daterange" :size="size" :popper-options="{ placement: 'bottom-start' }" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder" clearable></el-date-picker>
</div>
</template>
<script>
export default {
name: "index",
props:{
activation_date: {
type: Object,
default: () => ({ operator: "between", value: [] })
},
size:{ type: String, default: "small" },
startPlaceholder:{type:String, default:""},
endPlaceholder:{type:String, default:""}
},
watch:{
activation_date:{
handler(val){
if(!val || val.value.length == 0){
this.localDatePicker = [];
}
},
deep:true
}
},
data(){
return{
localDatePicker:[],
}
},
mounted() {
},
methods:{
dateChange(e){
this.localDatePicker = e;
this.emitActivationDate();
},
emitActivationDate() {
this.$emit('update:activation_date', {
operator: this.activation_date.operator,
value: this.localDatePicker && this.localDatePicker.length > 0? this.localDatePicker.map(date => this.$TOOL.getTime(date)):[]
});
}
}
}
</script>
<style scoped lang="scss">
.scDatePicker{
width: 100%;
}
</style>

View File

@ -9,28 +9,28 @@
<template> <template>
<div class="sc-dialog" ref="scDialog"> <div class="sc-dialog" ref="scDialog">
<el-dialog ref="dialog" v-model="dialogVisible" :fullscreen="isFullscreen" v-bind="$attrs" :show-close="false"> <el-dialog ref="dialog" v-model="dialogVisible" :fullscreen="isFullscreen" v-bind="$attrs" :show-close="false">
<template #header> <template #header>
<slot name="header"> <slot name="header">
<span class="el-dialog__title">{{ title }}</span> <span class="el-dialog__title">{{ title }}</span>
</slot> </slot>
<div class="sc-dialog__headerbtn"> <div class="sc-dialog__headerbtn">
<button v-if="showFullscreen" aria-label="fullscreen" type="button" @click="setFullscreen"> <button v-if="showFullscreen" aria-label="fullscreen" type="button" @click="setFullscreen">
<el-icon v-if="isFullscreen" class="el-dialog__close"><el-icon-bottom-left /></el-icon> <el-icon v-if="isFullscreen" class="el-dialog__close"><el-icon-bottom-left /></el-icon>
<el-icon v-else class="el-dialog__close"><el-icon-full-screen /></el-icon> <el-icon v-else class="el-dialog__close"><el-icon-full-screen /></el-icon>
</button> </button>
<button v-if="showClose" aria-label="close" type="button" @click="closeDialog"> <button v-if="showClose" aria-label="close" type="button" @click="closeDialog">
<el-icon class="el-dialog__close"><el-icon-close /></el-icon> <el-icon class="el-dialog__close"><el-icon-close /></el-icon>
</button> </button>
</div>
</template>
<div v-loading="loading">
<slot></slot>
</div> </div>
</template> <template #footer>
<div v-loading="loading"> <slot name="footer"></slot>
<slot></slot> </template>
</div> </el-dialog>
<template #footer>
<slot name="footer"></slot>
</template>
</el-dialog>
</div> </div>
</template> </template>

View File

@ -0,0 +1,72 @@
<!--
* @Descripttion: 多选框组件
* @Author: 龙运模
* @Date: 2024年07月11日
* @LastEditors: 龙运模
* @LastEditTime:
-->
<template>
<div class="scSelect">
<el-select v-bind="$attrs" v-model="localData" class="input" :size="size" @visible-change="getDataList" @change="selectChange" :placeholder="placeholder" clearable>
<slot></slot>
</el-select>
</div>
</template>
<script>
export default {
name: "index",
props:{
select_params: {
type: Object,
default: () => ({ operator: "in", value: [] })
},
size:{ type: String, default: "small" },
placeholder:{type:String, default:"请选择"},
},
watch:{
select_params:{
handler(val){
if(!val || val.value.length == 0){
this.localData = [];
}
},
deep:true
}
},
data(){
return{
localData:[],
}
},
mounted() {
},
methods:{
getDataList(val){
this.$emit('fetchData',val);
},
selectChange(e){
this.localData = e;
this.emitActivationSelect();
},
emitActivationSelect() {
this.$emit('update:select_params', {
operator: this.select_params.operator,
value: this.localData? this.localData:[]
});
}
}
}
</script>
<style scoped lang="scss">
.scSelect{
width: 100%;
height: 100%;
:deep(.el-input){
height: 28px;
}
}
</style>

View File

@ -55,8 +55,8 @@
<header class="adminui-header"> <header class="adminui-header">
<div class="adminui-header-left"> <div class="adminui-header-left">
<div class="logo-bar"> <div class="logo-bar">
<img class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/login_logo.png"> <!-- <img class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/login_logo.png">-->
<!-- <span>{{ $CONFIG.APP_NAME }}</span>--> <span>{{ $CONFIG.APP_NAME }}</span>
</div> </div>
<Topbar v-if="!ismobile"></Topbar> <Topbar v-if="!ismobile"></Topbar>
</div> </div>

View File

@ -21,6 +21,8 @@ import scWaterMark from './components/scWaterMark'
import scQrCode from './components/scQrCode' import scQrCode from './components/scQrCode'
import ossImgUpload from "./components/scUpload/uploadImg"; import ossImgUpload from "./components/scUpload/uploadImg";
import ossImgListUpload from "./components/scUpload/uploadListImg"; import ossImgListUpload from "./components/scUpload/uploadListImg";
import scDatePicker from "./components/scDatePicker";
import scMultipleSelect from "./components/scMultipleSelect";
import scStatusIndicator from './components/scMini/scStatusIndicator' import scStatusIndicator from './components/scMini/scStatusIndicator'
import scTrend from './components/scMini/scTrend' import scTrend from './components/scMini/scTrend'
@ -66,6 +68,8 @@ export default {
app.component('scTrend', scTrend); app.component('scTrend', scTrend);
app.component('ossImgUpload', ossImgUpload); app.component('ossImgUpload', ossImgUpload);
app.component('ossImgListUpload', ossImgListUpload); app.component('ossImgListUpload', ossImgListUpload);
app.component('scDatePicker', scDatePicker);
app.component('scMultipleSelect', scMultipleSelect);
//注册全局指令 //注册全局指令
app.directive('auth', auth) app.directive('auth', auth)

View File

@ -32,10 +32,10 @@
.common-header-right {display: flex;align-items: center;} .common-header-right {display: flex;align-items: center;}
.common-header-right a {font-size: 14px;color: var(--el-color-primary);cursor: pointer;} .common-header-right a {font-size: 14px;color: var(--el-color-primary);cursor: pointer;}
.common-header-right a:hover {color: var(--el-color-primary-light-3);} .common-header-right a:hover {color: var(--el-color-primary-light-3);}
.common-container {max-width: 1240px;margin:30px auto 30px auto;} .common-container {max-width: 1200px;margin:30px auto 30px auto;}
.common-main {padding:20px;} .common-main {padding:20px;border:0;}
.common-title {font-size: 26px;margin-bottom: 20px;font-weight: normal;} .common-title {font-size: 24px;margin-bottom: 20px;font-weight: normal;}
.common-main .el-form {width: 500px;margin:30px auto;} .common-main .el-form {width: 420px;margin:30px auto;}
.common-main .el-steps .el-step__title {font-size: 14px;} .common-main .el-steps .el-step__title {font-size: 14px;}
.common-main .el-steps .el-step__icon {border: 1px solid;} .common-main .el-steps .el-step__icon {border: 1px solid;}
.common-main .yzm {display: flex;width: 100%;} .common-main .yzm {display: flex;width: 100%;}

View File

@ -148,19 +148,19 @@ tool.objCopy = function (obj) {
/* 日期格式化 */ /* 日期格式化 */
tool.dateFormat = function (date, fmt='yyyy-MM-dd hh:mm:ss') { tool.dateFormat = function (date, fmt='yyyy-MM-dd hh:mm:ss') {
date = new Date(date) date = new Date(date)
var o = { const o = {
"M+" : date.getMonth()+1, //月份 "M+": date.getMonth() + 1, // 月份
"d+" : date.getDate(), // "d+": date.getDate(), //
"h+" : date.getHours(), //小时 "h+": date.getHours(), // 小时
"m+" : date.getMinutes(), // "m+": date.getMinutes(), //
"s+" : date.getSeconds(), // "s+": date.getSeconds(), //
"q+" : Math.floor((date.getMonth()+3)/3), //季度 "q+": Math.floor((date.getMonth() + 3) / 3), // 季度
"S" : date.getMilliseconds() //毫秒 "S": date.getMilliseconds() // 毫秒
}; };
if(/(y+)/.test(fmt)) { if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length)); fmt = fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
} }
for(var k in o) { for(let k in o) {
if(new RegExp("("+ k +")").test(fmt)){ if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
} }
@ -168,6 +168,11 @@ tool.dateFormat = function (date, fmt='yyyy-MM-dd hh:mm:ss') {
return fmt; return fmt;
} }
tool.getTime = function (date){
date = new Date(date);
return Math.floor(date.getTime() / 1000);
}
/* 千分符 */ /* 千分符 */
tool.groupSeparator = function (num) { tool.groupSeparator = function (num) {
num = num + ''; num = num + '';

View File

@ -12,7 +12,7 @@
<router-link to="/login">返回登录</router-link> <router-link to="/login">返回登录</router-link>
</div> </div>
</el-header> </el-header>
<el-main> <el-main class="registerView">
<div class="common-container"> <div class="common-container">
<h2 class="common-title">{{title}}</h2> <h2 class="common-title">{{title}}</h2>
<div class="common-main el-card"> <div class="common-main el-card">
@ -31,5 +31,8 @@
} }
</script> </script>
<style> <style lang="scss" scoped>
.registerView{
background: #F6F8F9;
}
</style> </style>

View File

@ -1,59 +1,51 @@
<template> <template>
<common-page title="注册新账号"> <common-page title="注册">
<el-steps :active="stepActive" simple finish-status="success"> <el-steps :active="stepActive" simple finish-status="success">
<el-step title="基础信息" /> <el-step title="创建账户" />
<el-step title="详细信息" /> <el-step title="填写信息" />
<el-step title="完成注册" /> <el-step title="注册完成" />
</el-steps> </el-steps>
<el-form v-if="stepActive==0" ref="stepForm_0" :model="form" :rules="rules" :label-width="120"> <el-form v-if="stepActive==0" ref="stepForm_0" :model="form" :rules="rules" label-position="top">
<el-form-item label="登录账号" prop="user"> <el-form-item label="电子邮箱" prop="email">
<el-input v-model="form.user" placeholder="请输入登录账号"></el-input>
<div class="el-form-item-msg">登录账号将作为登录时的唯一凭证</div>
</el-form-item>
<el-form-item label="登录密码" prop="password">
<el-input v-model="form.password" type="password" show-password placeholder="请输入登录密码"></el-input>
<sc-password-strength v-model="form.password"></sc-password-strength>
<div class="el-form-item-msg">请输入包含英文数字的8位以上密码</div>
</el-form-item>
<el-form-item label="确认密码" prop="password2">
<el-input v-model="form.password2" type="password" show-password placeholder="请再一次输入登录密码"></el-input>
</el-form-item>
<el-form-item label="" prop="agree">
<el-checkbox v-model="form.agree" label="">已阅读并同意</el-checkbox><span class="link" @click="showAgree=true">平台服务协议</span>
</el-form-item>
</el-form>
<el-form v-if="stepActive==1" ref="stepForm_1" :model="form" :rules="rules" :label-width="120">
<el-form-item label="真实姓名" prop="userName">
<el-input v-model="form.userName" placeholder="请输入真实姓名"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱地址"></el-input> <el-input v-model="form.email" placeholder="请输入邮箱地址"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="账号类型" prop="userType"> <el-form-item label="手机号" prop="mobile">
<el-radio-group v-model="form.userType"> <el-input v-model="form.mobile" placeholder="请输入手机号"></el-input>
<el-radio-button label="1">企业开发者</el-radio-button>
<el-radio-button label="2">企业开发者</el-radio-button>
</el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="开通类别" prop="open"> <el-form-item label="验证码" prop="verify_code">
<el-checkbox-group v-model="form.open"> <el-row justify="space-between" style="width: 100%">
<el-checkbox label="1">云存储API</el-checkbox> <el-col :span="17">
<el-checkbox label="2">云检索API</el-checkbox> <el-form-item>
<el-checkbox label="3">Javescript API</el-checkbox> <el-input v-model="form.verify_code" placeholder="请输入验证码"></el-input>
</el-checkbox-group> </el-form-item>
</el-col>
<el-col :span="7" align="right">
<el-button @click="getYzm" type="primary" :disabled="disabled">获取验证码 <span v-if="disabled"> ({{ time }})</span></el-button>
</el-col>
</el-row>
</el-form-item>
</el-form>
<el-form v-if="stepActive==1" ref="stepForm_1" :model="form" :rules="rules" label-position="top">
<el-form-item label="公司名称" prop="userName">
<el-input v-model="form.userName" placeholder="请输入真实姓名"></el-input>
</el-form-item>
<el-form-item label="客户名称" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱地址"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div v-if="stepActive==2"> <div v-if="stepActive==2">
<el-result icon="success" title="注册成功" sub-title="可以使用登录账号以及手机号登录系统"> <el-result icon="success" title="账号注册成功" sub-title="可以使用登录账号以及手机号登录系统">
<template #extra> <template #extra>
<el-button type="primary" @click="goLogin">前去登录</el-button> <p class="activation" @click="goLogin">激活邮箱</p>
</template> </template>
</el-result> </el-result>
</div> </div>
<el-form style="text-align: center;"> <el-form style="text-align: center;">
<el-button v-if="stepActive>0 && stepActive<2" @click="pre">上一步</el-button> <div class="btnBox">
<el-button v-if="stepActive<1" type="primary" @click="next">下一步</el-button> <el-button class="btn" v-if="stepActive<2" type="primary" @click="next" style="width: 100%;">下一步</el-button>
<el-button v-if="stepActive==1" type="primary" @click="save">提交</el-button> <el-button class="btn" v-if="stepActive>0 && stepActive<2" @click="pre" style="width: 100%;">上一步</el-button>
<el-button class="btn" v-if="stepActive==2" type="primary" @click="save" style="width: 100%;">完成</el-button>
</div>
</el-form> </el-form>
<el-dialog v-model="showAgree" title="平台服务协议" :width="800" destroy-on-close> <el-dialog v-model="showAgree" title="平台服务协议" :width="800" destroy-on-close>
平台服务协议 平台服务协议
@ -76,35 +68,33 @@
}, },
data() { data() {
return { return {
disabled:false,
time:60,
stepActive: 0, stepActive: 0,
showAgree: false, showAgree: false,
form: { form: {
email: "",
mobile:"",
verify_code:"",
user: "", user: "",
password: "",
password2: "",
agree: false, agree: false,
userName: "", userName: "",
email: "",
userType: "1", userType: "1",
open: [] open: []
}, },
rules: { rules: {
user: [ email: [
{ required: true, message: '请输入账号名'} { required: true, message: '请输入邮箱地址'}
], ],
password: [ mobile: [
{ required: true, message: '请输入密码'} { required: true, message: '请输入手机号'}
], ],
password2: [ verify_code: [
{ required: true, message: '请再次输入密码'}, { required: true, message: '请输入验证码'}
{validator: (rule, value, callback) => {
if (value !== this.form.password) {
callback(new Error('两次输入密码不一致'));
}else{
callback();
}
}}
], ],
agree: [ agree: [
{validator: (rule, value, callback) => { {validator: (rule, value, callback) => {
if (!value) { if (!value) {
@ -117,9 +107,7 @@
userName: [ userName: [
{ required: true, message: '请输入真实姓名'} { required: true, message: '请输入真实姓名'}
], ],
email: [
{ required: true, message: '请输入邮箱地址'}
],
userType: [ userType: [
{ required: true, message: '请选择账户类型'} { required: true, message: '请选择账户类型'}
], ],
@ -133,6 +121,9 @@
}, },
methods: { methods: {
getYzm(){
},
pre(){ pre(){
this.stepActive -= 1 this.stepActive -= 1
}, },
@ -165,7 +156,14 @@
} }
</script> </script>
<style scoped> <style scoped lang="scss">
.activation{
color: var(--el-color-primary);
}
.btnBox{
display: flex;align-items: center;
.btn{
flex: 1;
}
}
</style> </style>

View File

@ -13,13 +13,13 @@
<div class="searchMain searchMainNoTop"> <div class="searchMain searchMainNoTop">
<div class="searchItem"> <div class="searchItem">
<label class="name">开通日期</label> <label class="name">开通日期</label>
<el-date-picker class="input" type="daterange" :size="size" v-model="params.activation_date" :popper-options="{ placement: 'bottom-start' }" start-placeholder="开始日期" end-placeholder="结束日期" clearable></el-date-picker> <scDatePicker :size="size" v-model:activation_date="params.activation_date" start-placeholder="开始日期" end-placeholder="结束日期"></scDatePicker>
</div> </div>
<div class="searchItem"> <div class="searchItem">
<label class="name">公司名称</label> <label class="name">公司名称</label>
<el-select class="input" :size="size" v-model="params.id" @visible-change="getCompanyList" placeholder="请选择公司名称" filterable clearable> <scMultipleSelect :size="size" v-model:select_params="params.id" @fetchData="getCompanyList" placeholder="请选择公司名称" multiple collapse-tags filterable clearable>
<el-option v-for="item in setMap.full_name" :key="item" :label="item.full_name" :value="item.id"></el-option> <el-option v-for="item in setMap.full_name" :key="item" :label="item.full_name" :value="item.id"></el-option>
</el-select> </scMultipleSelect>
</div> </div>
<div class="searchItem"> <div class="searchItem">
<label class="name">状态</label> <label class="name">状态</label>
@ -96,10 +96,13 @@ export default {
selection: [], selection: [],
params: { params: {
activation_date: { activation_date: {
operator:'in', operator:'between',
value:[]
},
id:{
operator:"in",
value:[] value:[]
}, },
id:'',
active_status:'', active_status:'',
} }
} }
@ -201,8 +204,14 @@ export default {
}, },
reset(){ reset(){
this.params = { this.params = {
activation_date: '', activation_date: {
id:'', operator:'between',
value:[]
},
id:{
operator:"in",
value:[]
},
active_status:'', active_status:'',
}; };
this.$refs.table.reload(); this.$refs.table.reload();