Browse Source

2022年5月17日13:54:31

master
wq 3 years ago
parent
commit
eda9405378

+ 50
- 45
src/crud/components/CRUD.operation.vue View File

@@ -1,61 +1,66 @@
<template>
<div class="as-layout-horizontal">
<!-- CUD 按钮组件 -->
<el-button type="primary" icon="Plus" @click="crud.toAdd(that)">
新增
</el-button>
<el-button :disabled="DEdit" type="success" icon="Edit" @click="crud.toEdit(that)">
<el-button type="primary" icon="Plus" @click="toAdd"> 新增 </el-button>
<el-button :disabled="DEdit" type="success" icon="Edit" @click="toEdit">
修改
</el-button>
<el-button :disabled="DDelete" type="danger" icon="Delete" @click="crud.toDelete(that)">
<el-button :disabled="DDelete" type="danger" icon="Delete" @click="toDelete">
删除
</el-button>
<el-button type="warning" icon="Download">
导出
</el-button>
<el-button type="warning" icon="Download"> 导出 </el-button>
<div class="as-weight" />
<!-- 搜索-刷新 default-->
<el-button-group>
<el-button plain :type="SSearch ? 'info' : 'default'" icon="Search" @click="crud.toSearch(that)" />
<el-button icon="Refresh" @click="crud.toRefresh(that)" />
<!-- 搜索-刷新-->
<el-button-group v-if="child">
<el-button plain :type="SSearch ? 'info' : 'default'" icon="Search" @click="toSearch" />
<el-button icon="Refresh" @click="toRefresh" />
</el-button-group>
</div>
</template>
<script lang="ts">
import CRUD, {
crudConfig
} from "@/crud/crud"
import * as Vue from 'vue'

export default {
mixins: [crudConfig()], //运用混入的的方法
props: { //插值
DEdit: {
default: false,
type: Boolean
},
DDelete: {
default: false,
type: Boolean
},
SSearch: {
default: true,
type: Boolean
}
},
mounted() {
<script lang="ts" setup>
import { } from 'vue'
// 声明事件
const emit = defineEmits(['toAdd', 'toEdit', 'toDelete', 'toSearch', 'toRefresh'])

},
data() { //字段
return {
that: this
}
},
methods: { //方法
}
const props = defineProps({
DEdit: {
default: false,
type: Boolean,
},
DDelete: {
default: false,
type: Boolean,
},
SSearch: {
default: true,
type: Boolean,
},
child: { //子类是否显示
default: true,
type: Boolean
}
})

const toAdd = () => {
emit('toAdd')
}

const toEdit = () => {
emit('toEdit')
}

const toDelete = () => {
emit('toDelete')
}

const toSearch = () => {
emit('toSearch')
}

const toRefresh = () => {
emit('toRefresh')
}

</script>
<style scoped>

</style>

+ 20
- 32
src/crud/components/Search.operation.vue View File

@@ -1,43 +1,31 @@
<template>
<span>
<slot />
<el-button type="success" icon="Search" @click="Search">搜索</el-button>
<el-button type="warning" icon="RefreshLeft" @click="RefreshLeft">重置</el-button>
<el-button type="success" icon="search" @click="search">搜索</el-button>
<el-button type="warning" icon="refreshLeft" @click="refreshLeft">重置</el-button>
</span>
</template>
<script>
import CRUD, {
crudConfig
} from "@/crud/crud"
<script lang="ts" setup>
import { } from 'vue'
// 声明事件
const emit = defineEmits(['search', 'refreshLeft'])

export default {
mixins: [crudConfig()], //运用混入的的方法
props: { //插值
searchCondition: {
type: Object,
default: function () {
return {}
}
}
},
mounted() {

},
data() { //字段
return {
that: this
}
},
methods: { //方法
Search() { //搜索
console.log(this.searchCondition,'=====');
},
RefreshLeft() { //重置
this.$emit('RefreshLeft')
}
const props = defineProps({
searchCondition: {
type: Object,
default: function () {
return {}
}
}
})

const search = () => { //搜索
emit('search')
}
const refreshLeft = () => { //重置
emit('refreshLeft')
}

</script>
<style scoped>

</style>

+ 59
- 50
src/crud/components/UD.operation.vue View File

@@ -14,62 +14,71 @@
</div>
</div>
<template #reference>
<el-button size="small" type="danger" @click="hintDelete(scope.$index,data)">删除</el-button>
<!-- .$index -->
<el-button size="small" type="danger" @click="hintDelete(scope, data)">删除</el-button>
</template>
</el-popover>
</template>
<script>
import CRUD, {
crudConfig
} from "@/crud/crud"
<script setup lang="ts">
import { } from 'vue'

export default {
mixins: [crudConfig()], //运用混入的的方法
emits: ['handleDelete', 'handleEdit'],
props: { //插值
scope: {
default: null,
type: Object
},
data: {
default: null,
type: Object
},
isEdit: {
default: true,
type: Boolean
},
isDelete: {
default: true,
type: Boolean
}
},
data() { //字段
return {
that: this
}
},
methods: { //方法
handleDelete(idx, data) {
this.$emit('handleDelete', idx, data)
},
//编辑
handleEdit(idx, row) {
this.$emit('handleEdit', idx, row)
},
//删除弹窗
hintDelete(idx, data) {
data.forEach((element, index) => {
if (idx === index) {
element.visible = true
} else {
element.visible = false
}
});
// 声明事件
const emit = defineEmits(['handleDelete', 'handleEdit'])

const props = defineProps({
scope: {
default: null,
type: Object
},
data: {
default: null,
type: Object
},
isEdit: {
default: true,
type: Boolean
},
isDelete: {
default: true,
type: Boolean
},
rowKey: {
default: '',
type: String
}
})

const handleDelete = (idx: number, data: any) => {
emit('handleDelete', idx, data)
}

//编辑
const handleEdit = (idx: number, row: any) => {
emit('handleEdit', idx, row)
}

//删除弹窗
const hintDelete = (scope: any, data: any) => {
data.forEach((element: any, index: number) => {
if (element.children && element.children.length > 0) {
hintDelete(scope, element.children)
} else {
if (props.rowKey) {
if (scope.row[props.rowKey] === element.title) {
element.visible = true
} else {
element.visible = false
}
} else {
if (scope.$index === index) {
element.visible = true
} else {
element.visible = false
}
}
}
}
});
}
</script>
<style scoped>

</style>

+ 0
- 88
src/crud/config.js View File

@@ -1,88 +0,0 @@
/** 此文件夹为CURD默认配置文件 */
export const config = {
/* 默认设置 */
defaultOptions: {
tag: 'default',
// id字段名
idField: 'id',
// 标题
title: '',
// 请求数据的url
url: '',
// 排序规则,默认 id 降序, 支持多字段排序 ['id,desc', 'createTime,asc']
sort: ['id,desc'],
// 按钮显示
optShow: {
add: true, //添加
edit: true, //编辑
del: true, //修改
download: true, //导出
reset: true //刷新
},
// 调试开关
debug: false
},
/* 数据状态配置 */
data: {
msg: {
submit: '提交成功',
add: '新增成功',
edit: '编辑成功',
del: '删除成功'
},
page: {
// 页码
page: 0,
// 每页数据条数
size: 10,
// 总数据条数
total: 0
},
}
};

/* 钩子事件处理 */
export const method = {
//启动添加
toAdd(that) {
that.$emit(HOOK.Add);
},
//启动编辑
toEdit(that) {
that.$emit(HOOK.Edit);
},
//启动搜索
toSearch(that) {
that.$emit(HOOK.Search);
},
//启动删除
toDelete(that) {
that.$emit(HOOK.Delete);
},
//启动刷新
toRefresh(that) {
that.$emit(HOOK.Refresh);
},
};

/* HOOK */
export const HOOK = {
/** 刷新 */
Refresh: 'refresh',
/** 删除 */
Delete: 'remove',
/** 新建 */
Add: 'add',
/** 编辑 */
Edit: 'edit',
/** 搜索 */
Search: 'search',
/** 开始 "新建/编辑" */
beforeToCU: 'beforeCrudToCU',
/** 添加取消 */
beforeAddCancel: 'beforeCrudAddCancel',
/** 编辑取消 */
beforeEditCancel: 'beforeCrudEditCancel',
/** 提交 */
Submit: 'submit'
};

+ 74
- 0
src/crud/config.ts View File

@@ -0,0 +1,74 @@
import {
mergeOptions
} from '@/utils/utils';

/**
* 合并对象
* Object.assign(crud, method);
* 冻结对象
* Object.freeze(crud);
*
* file 表格(弹窗)字段模板
*/
const field = [ //字段
{
prop: '', //字段名称
label: '', //字段标识
width: '', //字段表头宽度
overflow: false, //文本超出是否显示省略号(默认false)
form: { //表单内容
required: false, //表单是否不能为空(默认false)
type: '', //表单类型(input,select[含选择框],date)
placeholder: '', //表单提示
itemType: '', //表单type
listData: [{ //列表数据
label: '', //标题
value: '' //表单提交值
}]
}
}
];

/* extend 表头拓展模板 */
const extend = [{
type: '', //类型:selection,index,expand
width: '', //表头宽度
}]

export const defaultOptions: {} = {
search: {}, //搜索字段
searchShow: true, //是否显示搜索模块(默认true)
border: false, //是否添加边框(默认false)
dialogCustom: false, //自定义Dialog (默认false)
dialogFooter: false, //隐藏弹窗页脚显示 (默认false)
crudShow: true, //是否显示CURD操作栏 (默认true)
crudChildShow: true, //是否显示CURD子操作栏 (默认true)
operateShow: true, //是否为表格添加操作栏(默认true)
operateTitle: '', //操作栏标题(默认为"")
operateFixed: false, //操作栏是否固定(默认false)
operateWidth: '', //操作栏宽度
operate: {
edit: true, //是否编辑(默认true)
delete: true //是否删除(默认true)
},
extend: [],
field: [], //默认为空
dialogArray: [], //弹窗表格
rowKey: '' //rowKey
}

/* 设置处理 */
export function process(options: any) {
//合并用户配置参数信息
options = mergeOptions(defaultOptions, options);

//处理dialog数据
let dialogArray: any = [];
options.field.forEach((item: any) => {
if (item.form) {
dialogArray.push(item)
}
})
options.dialogArray = dialogArray
return options
}

+ 0
- 71
src/crud/crud.js View File

@@ -1,71 +0,0 @@
//增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)
/* jshint esversion: 11 */
import {
config,
method,
HOOK
} from './config';
import {
mergeOptions
} from '@/utils/utils';

/**
* CRUD 的基础配置
*
* @param {*} options 选择
*/
function CRUD(options = {}) {
const defaultOptions = config.defaultOptions;
//合并用户配置参数信息
options = mergeOptions(defaultOptions, options);
//data为系统视图配置(一般不做整合)-对象合并
const crud = Object.assign(options, config.data);
// 附加方法 CRUD操作执行方法
Object.assign(crud, method);
// 冻结处理(使得配置信息不可修改)
Object.freeze(crud);
return crud;
}

/**
* CRUD的配置参数
* @param {*} options 配置参数
* @returns
*/
function crudConfig(options = {}) {
//合并传入过来的参数
const crud = CRUD({});
return {
data() {
return {
crud
};
},
beforeRefresh() { //创建前
this.crud.registerVM(options.type, this);
},
destroy() { //销毁
this.crud.unregisterVM(options.type, this);
}
};
}

/**
* CRUD钩子
*/
CRUD.HOOK = HOOK;

/**
* CRUD状态
*/
CRUD.STATUS = {
NORMAL: 0, //正常
PREPARED: 1, //准备好的
PROCESSING: 2 //处理好的
};

export default CRUD;

export {
crudConfig
};

+ 35
- 51
src/crud/index.vue View File

@@ -1,38 +1,41 @@
<template>
<div style="opacity: 1; background-color: #fff; padding: 20px">
<div style="opacity: 1; background-color: #fff; padding: 0 20px 0 20px;">
<!-- 搜索框组件 -->
<search-operation v-show="SSearch" :searchCondition="searchCondition" @RefreshLeft="RefreshLeft">
<!-- 具名插槽 -->
<slot name="search" :searchCondition="searchCondition" />
</search-operation>

<div style="margin-bottom: 10px;" v-show="SSearch">
<search-operation :searchCondition="searchCondition" @RefreshLeft="RefreshLeft">
<!-- 具名插槽 -->
<slot name="search" :searchCondition="searchCondition" />
</search-operation>
</div>
<!-- CRUD组件 -->
<crud-operation v-if="false" style="margin-top: 10px" @add="add" @edit="edit" @remove="remove"
@refresh="refresh" @search="search" :DEdit="EStart" :DDelete="DStart" :SSearch="SSearch">
<crud-operation v-if="tableFrom.crudShow" style="margin-bottom: 10px;" @toAdd="toAdd" @toEdit="toEdit" @toDelete="toDelete"
@toRefresh="toRefresh" @toSearch="toSearch" :DEdit="EStart" :DDelete="DStart" :SSearch="SSearch"
:child="tableFrom.crudChildShow">
</crud-operation>

<!-- 表单组件 -->
<el-table ref="multipleTableRef" :data="testData" @selection-change="handleSelectionChange"
style="width: 100%; margin: 20px 0 20px 0" :border="tableFrom.border">
style="width: 100%; margin: 0 0 0 0" :border="tableFrom.border" :row-key="tableFrom.rowKey">
<!-- 表头拓展 -->
<el-table-column v-for="(item, index) in tableFrom.extend" :key="index" :type="item.type"
:width="item.width" :label="item.label" />

<!-- 字段内容 -->
<el-table-column v-for="(item, index) in tableFrom.field" :key="index" :prop="item.prop" :label="item.label"
:width="item.width" :show-overflow-tooltip="!item.overflow" />

<el-table-column :v-if="tableFrom.operateShow" :fixed="tableFrom.operateFixed ? 'right' : 'false'" :label="tableFrom.operateTitle"
:width="tableFrom.operateWidth ? tableFrom.operateWidth : ''">
<el-table-column :v-if="tableFrom.operateShow" :fixed="tableFrom.operateFixed ? 'right' : undefined"
:label="tableFrom.operateTitle" :width="tableFrom.operateWidth ? tableFrom.operateWidth : ''">
<!-- 默认插槽值 -->
<template #default="scope">
<ud-operation :scope="scope" :data="testData" :isEdit="tableFrom.operate.edit"
:isDelete="tableFrom.operate.delete" @handleEdit="handleEdit" @handleDelete="handleDelete">
<ud-operation :rowKey="tableFrom.rowKey" :scope="scope" :data="testData"
:isEdit="tableFrom.operate.edit" :isDelete="tableFrom.operate.delete" @handleEdit="handleEdit"
@handleDelete="handleDelete">
</ud-operation>
<!-- 具名插槽(自定义操作按钮) -->
<slot name="operation" :scope="scope" :tableFrom="dialogFormVisible" />
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination v-if="false" :page-size="20" :pager-count="11" layout="prev, pager, next" :total="1000" />
@@ -45,7 +48,7 @@
<div v-else>
<!-- 系统内容 -->
<el-form ref="ruleFormRef" :rules="rules" :model="form">
<el-form-item v-for="(item, index) in tableFrom.field" :key="index" :label="item.label"
<el-form-item v-for="(item, index) in tableFrom.dialogArray" :key="index" :label="item.label"
:prop="item.prop" :label-width="formLabelWidth">
<!-- 输入框 -->
<div style="width: 100%" v-if="item.form.type === 'input'">
@@ -81,9 +84,13 @@
</div>
</template>
<script lang="ts" setup>
// @ts-ignore CRUD 操作按钮
import crudOperation from '@/crud/components/CRUD.operation.vue'
// @ts-ignore SR 搜索重置
import searchOperation from '@/crud/components/Search.operation.vue'
// @ts-ignore UD 编辑删除按钮
import udOperation from '@/crud/components/UD.operation.vue'
import { process } from '@/crud/config'
import { reactive, ref, toRaw } from 'vue'

// 声明事件
@@ -121,35 +128,15 @@ const props = defineProps({
seven: '52011328220201499572',
eight: '正常',
data: '2020-12-24',
},
{
one: '李丽霞',
two: '贵ANS989',
three: '蓝色',
four: '52011328220201499572',
five: '正常',
six: '储值卡',
seven: '52011328220200034040',
eight: '正常',
data: '2021-08-24',
},
{
one: '沈波',
two: '贵ABB123',
three: '蓝色',
four: '52011328220201499572',
five: '正常',
six: '储值卡',
seven: '52011328220201499572',
eight: '正常',
data: '2022-01-22',
},
}
]
},
},
})

const tableFrom = props.homeData ? props.homeData.table : [] //表单字段
const processData = process(props.homeData)

const tableFrom: any = processData ? processData : [] //表单字段
const multipleTableRef = ref() //表单ref(清空全选)
const testData = ref(props.tableData) //表单数据
const visible = ref(false) //删除提示框是否显示
@@ -158,7 +145,7 @@ const formLabelWidth = '100px' //默认表单宽度
const title = ref('添加') //表单标题
const DStart = ref(true) //删除按钮状态
const EStart = ref(true) //编辑按钮状态
const SSearch = ref(true) //是否打开搜索框
const SSearch = ref(tableFrom.searchShow) //是否打开搜索框
let index = -1
let indexs = []
//表单校验
@@ -167,7 +154,7 @@ let initRules: any = {}
let initForm: any = {}
//初始化数据
if (tableFrom) {
tableFrom.field.forEach((element: any) => {
tableFrom.dialogArray.forEach((element: any) => {
initForm[element.prop] = ''
if (element.form.required) {
initRules[element.prop] = [
@@ -183,19 +170,16 @@ if (tableFrom) {
const rules = reactive(initRules)

//搜索条件
let searchCondition = reactive(props.homeData ? props.homeData.search : [])
let searchCondition: any = reactive(processData ? processData.search : [])

//表单字段
const form: any = ref(initForm)
form.value.four = '52011328220201499572' //赋值一条测试数据

//重置
const RefreshLeft = () => {
Object.keys(searchCondition).forEach((key) => (searchCondition[key] = ''))
}

//添加
const add = () => {
const toAdd = () => {
console.log('点击了添加按钮')
form.value = {}
title.value = '添加'
@@ -204,19 +188,19 @@ const add = () => {
}

//删除
const remove = () => {
const toDelete = () => {
console.log('点击了删除按钮')
emit('remove')
}

//刷新
const refresh = () => {
const toRefresh = () => {
console.log('点击了刷新按钮')
emit('refresh')
}

//编辑
const edit = () => {
const toEdit = () => {
console.log('点击了修改按钮')
if (index != -1) {
title.value = '编辑'
@@ -227,7 +211,7 @@ const edit = () => {
}

//搜索
const search = () => {
const toSearch = () => {
console.log('点击了搜索按钮')
SSearch.value = !SSearch.value
emit('search')

+ 91
- 94
src/data/cardAfter/cardFillDo.ts View File

@@ -4,99 +4,96 @@ export const Data = {
fileTwo: '',
fileThree: ''
},
table: {
style: '',
customDialog: true, //自定义Dialog (默认false)
footerDialog: true, //是否隐藏Dialog页脚
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'userName',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'three',
label: '车牌颜色',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌颜色'
}
}, {
prop: 'cardId',
label: '卡号',
width: '200',
form: {
required: true,
type: 'input',
placeholder: '卡号'
}
}, {
prop: 'cardStatus',
label: '卡片状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片状态'
}
}, {
prop: 'six',
label: '卡片类型',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片类型'
}
}, {
prop: 'obuId',
label: 'OBU编号',
width: '200',
form: {
required: true,
type: 'input',
placeholder: 'OBU编号'
}
}, {
prop: 'obuStatus',
label: 'OBU状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: 'OBU状态'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
isOperate: true,
operateWidth: '',
operate: {
edit: false,
delete: false
}
dialogCustom: true, //自定义Dialog (默认false)
dialogFooter: true, //是否隐藏Dialog页脚
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'userName',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'three',
label: '车牌颜色',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌颜色'
}
}, {
prop: 'cardId',
label: '卡号',
width: '200',
form: {
required: true,
type: 'input',
placeholder: '卡号'
}
}, {
prop: 'cardStatus',
label: '卡片状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片状态'
}
}, {
prop: 'six',
label: '卡片类型',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片类型'
}
}, {
prop: 'obuId',
label: 'OBU编号',
width: '200',
form: {
required: true,
type: 'input',
placeholder: 'OBU编号'
}
}, {
prop: 'obuStatus',
label: 'OBU状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: 'OBU状态'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
operateShow: true,
operateWidth: '',
operate: {
edit: false,
delete: false
}
}

+ 89
- 92
src/data/cardAfter/cardRenewal.ts View File

@@ -2,97 +2,94 @@ export const Data = {
search: {
fileOne: ''
},
table: {
style: '',
footerDialog: true,
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'one',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'five',
label: '证件类型',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入证件类型'
}
}, {
prop: 'four',
label: '证件号码123',
width: '200',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入证件号码'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'four',
label: '卡号',
width: '200',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入卡号'
}
}, {
prop: 'data',
label: '卡片状态',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入卡片状态'
}
},
{
prop: 'data',
label: '到期时间',
width: '180',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入到期时间'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
isOperate: true,
operateWidth: '',
operate: {
edit: true,
delete: false
}
style: '',
dialogfooter: true,
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'one',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'five',
label: '证件类型',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入证件类型'
}
}, {
prop: 'four',
label: '证件号码123',
width: '200',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入证件号码'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'four',
label: '卡号',
width: '200',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入卡号'
}
}, {
prop: 'data',
label: '卡片状态',
width: '120',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入卡片状态'
}
},
{
prop: 'data',
label: '到期时间',
width: '180',
form: {
required: false,
disabled: true,
type: 'input',
placeholder: '请输入到期时间'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
operateWidth: '',
operate: {
edit: true,
delete: false
}
}

+ 91
- 93
src/data/cardAfter/initiativeHangUp.ts View File

@@ -4,98 +4,96 @@ export const Data = {
fileTwo: '',
fileThree: ''
},
table: {
style: '',
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'one',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'three',
label: '车牌颜色',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌颜色'
}
}, {
prop: 'four',
label: '卡号',
width: '180',
form: {
required: true,
type: 'input',
placeholder: '卡号'
}
}, {
prop: 'five',
label: '卡片状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片状态'
}
}, {
prop: 'six',
label: '卡片类型',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片类型'
}
},
{
prop: 'seven',
label: 'OBU编号',
width: '180',
form: {
required: true,
type: 'input',
placeholder: 'OBU编号'
}
}, {
prop: 'eight',
label: 'OBU状态',
width: '',
form: {
required: true,
type: 'input',
placeholder: 'OBU状态'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
isOperate: true,
operateWidth: '180',
operate: {
edit: true,
delete: true
}
style: '',
extend: [{
type: 'index',
label: '序号',
width: '80'
}],
field: [ //表格
{
prop: 'one',
label: '客户名称',
width: '120',
overflow: true,
form: {
required: true,
type: 'input',
placeholder: '请输入客户名称'
}
}, {
prop: 'two',
label: '车牌号码',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌号码'
}
}, {
prop: 'three',
label: '车牌颜色',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入车牌颜色'
}
}, {
prop: 'four',
label: '卡号',
width: '180',
form: {
required: true,
type: 'input',
placeholder: '卡号'
}
}, {
prop: 'five',
label: '卡片状态',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片状态'
}
}, {
prop: 'six',
label: '卡片类型',
width: '120',
form: {
required: true,
type: 'input',
placeholder: '请输入卡片类型'
}
},
{
prop: 'seven',
label: 'OBU编号',
width: '180',
form: {
required: true,
type: 'input',
placeholder: 'OBU编号'
}
}, {
prop: 'eight',
label: 'OBU状态',
width: '',
form: {
required: true,
type: 'input',
placeholder: 'OBU状态'
}
},
],
border: true,
operateTitle: '操作',
operateFixed: true,
isOperate: true,
operateWidth: '180',
operate: {
edit: true,
delete: true
}
}

+ 9
- 0
src/data/menuData.ts View File

@@ -126,5 +126,14 @@ export const list = [
children: []
}]
}]
}, {
title: '系统管理',
icon: 'Notification',
children: [{
title: '菜单模块',
path: 'menu',
icon: 'User',
children: []
}]
}
];

+ 31
- 35
src/data/tableConfig.ts View File

@@ -1,41 +1,37 @@
export const cfg = {
search: { //搜索字段配置

},
table: { //table 样式配置
border: false, //是否添加边框(默认false)
dialogCustom: false, //自定义Dialog (默认false)
dialogFooter: false, //隐藏弹窗页脚显示 (默认false)
extend: [{ //表头拓展
type: '', //类型:selection,index,expand
width: '', //表头宽度
}],
field: [ //字段
{
prop: '', //字段名称
label: '', //字段标识
width: '', //字段表头宽度
overflow: false, //文本超出是否显示省略号(默认false)
form: { //表单内容
required: false, //表单是否不能为空(默认false)
type: '', //表单类型(input,select[含选择框],date)
placeholder: '', //表单提示
itemType: '', //表单type
listData: [{ //列表数据
label: '',
value: ''
}]
}
search: {}, //搜索字段
border: false, //是否添加边框(默认false)
dialogCustom: false, //自定义Dialog (默认false)
dialogFooter: false, //隐藏弹窗页脚显示 (默认false)
extend: [{ //表头拓展
type: '', //类型:selection,index,expand
width: '', //表头宽度
}],
field: [ //字段
{
prop: '', //字段名称
label: '', //字段标识
width: '', //字段表头宽度
overflow: false, //文本超出是否显示省略号(默认false)
form: { //表单内容
required: false, //表单是否不能为空(默认false)
type: '', //表单类型(input,select[含选择框],date)
placeholder: '', //表单提示
itemType: '', //表单type
listData: [{ //列表数据
label: '',
value: ''
}]
}
],
operateShow: true, //是否为表格添加操作栏(默认true)
operateTitle: '', //操作栏标题
operateFixed: false, //操作栏是否固定(默认false)
operateWidth: '', //操作栏宽度
operate: {
edit: true, //是否编辑
delete: true //是否删除
}
],
operateShow: true, //是否为表格添加操作栏(默认true)
operateTitle: '', //操作栏标题(默认为"")
operateFixed: false, //操作栏是否固定(默认false)
operateWidth: '', //操作栏宽度
operate: {
edit: true, //是否编辑S
delete: true //是否删除
}
}


+ 10
- 24
src/layout/components/TabControl.vue View File

@@ -1,27 +1,13 @@
<template>
<!-- 标签选项卡模块 :model-value="props.editableTabsValue"(只读) -->
<el-tabs
v-model="editableTabsValue.index"
type="card"
@tab-click="tabClick"
@tab-remove="removeTab"
@contextmenu.prevent="openMenu($event)"
>
<el-tab-pane
v-for="item in editableTabs"
:key="item.name"
:closable="item.start"
:label="item.title"
:name="item.name"
>
<el-tabs v-model="editableTabsValue.index" type="card" @tab-click="tabClick" @tab-remove="removeTab"
@contextmenu.prevent="openMenu($event)">
<el-tab-pane v-for="item in editableTabs" :key="item.name" :closable="item.start" :label="item.title"
:name="item.name">
<slot></slot>
</el-tab-pane>
</el-tabs>
<ul
v-show="data.visible"
:style="{ left: data.left + 'px', top: data.top + 'px' }"
class="contextmenu"
>
<ul v-show="data.visible" :style="{ left: data.left + 'px', top: data.top + 'px' }" class="contextmenu">
<li @click="updateTabs">刷新</li>
<li v-show="data.indexes !== 0" @click="closeTabs">关闭</li>
<li @click="closeOtherTabs">关闭其他</li>
@@ -33,7 +19,6 @@ import $storeTab from '@/store/tabValue' //引入tab vuex
import { ref, reactive, nextTick, watch } from 'vue'
import { useRouter } from 'vue-router'
import $store from '@/store/index' // 引入vuex
import { log } from 'console'

const router = useRouter() //router 对象
let editableTabs = ref($storeTab.state.tabArray)
@@ -104,8 +89,6 @@ function closeAllTabs() {
//关闭其他
//右键单击事件
const openMenu = (event: any) => {
console.log($store.state.data.menuIsExpansion)
event.preventDefault() //防止默认菜单弹出
let obj = event.srcElement ? event.srcElement : event.target
data.indexes = -1
if (obj.innerText) {
@@ -115,9 +98,12 @@ const openMenu = (event: any) => {
data.indexes = index
}
})
data.left = event.clientX - ($store.state.data.menuIsExpansion ? 200 : 50)
data.left = event.clientX - ($store.state.data.menuIsExpansion ? 250 : 50)
data.top = event.clientY - 65
data.visible = true
if (data.indexes != -1) {
event.preventDefault() //防止默认菜单弹出
data.visible = true
}
}
}
//点击事件监听(路由)

+ 0
- 1
src/router/index.ts View File

@@ -2,7 +2,6 @@ import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Cookies from 'js-cookie'

const routes: RouteRecordRaw[] = [

{
path: '/',
name: 'Login',

+ 5
- 5
src/utils/Export2Excel.js View File

@@ -156,12 +156,12 @@ export function export_json_to_excel({
bookType = 'xlsx'
} = {}) {
/* original data */
filename = filename || 'excel-list'
filename = filename || 'excel-list';
data = [...data]
data.unshift(header);

for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
data.unshift(multiHeader[i]);
}

var ws_name = "Sheet1";
@@ -171,8 +171,8 @@ export function export_json_to_excel({
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
ws['!merges'].push(XLSX.utils.decode_range(item));
});
}

if (autoWidth) {
@@ -194,7 +194,7 @@ export function export_json_to_excel({
'wch': val.toString().length
};
}
}))
}));
/*以第一行为初始值*/
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {

+ 39
- 0
src/utils/offLineData.ts View File

@@ -0,0 +1,39 @@
/* 离线数据工具类 */
import Cookies from 'js-cookie'

/**
* 添加
* @param key
* @param value
*/
export function add(key: string, value: any) {
let array: any = JSON.parse(Cookies.get(key) ? Cookies.get(key) + '' : '[]')
array.push(value)
Cookies.set(key, JSON.stringify(array))
}

/**
* 获取
* @param key
*/
export function get(key: string) {
return JSON.parse(Cookies.get(key) + '')
}

/**
* 删除
* @param key
* @param value
*/
function remove(key: string, value: any) {

}

/**
* 修改
* @param key
* @param value
*/
function update(key: string, value: any) {

}

+ 1
- 0
src/utils/utils.ts View File

@@ -19,6 +19,7 @@ export function mergeOptions(src: any, opts: any) {
...src
};
for (const key in src) {
//判断是否包含自己的属性
if (opts.hasOwnProperty(key)) {
optsRet[key] = opts[key];
}

+ 2
- 2
src/views/dengmingcong/cardFillDo/cardFillDo.vue View File

@@ -63,9 +63,9 @@ const {

proxy.$request.post('activeSuspend/query', { vehicleColour: '1', vehicleNumber: '2' }, {
}).then((res: {}) => {
console.log(res);
console.log(res, '====');
}).catch((err: {}) => {
console.log(err);
console.log(err, '====456');
})

const datas = reactive(Data);

+ 40
- 38
src/views/system/home/Home.vue View File

@@ -1,45 +1,47 @@
<template>
<!-- accept 限制上传文件格式 .text :auto-upload="false"-->
<el-upload ref="uploadRef" action="https://jsonplaceholder.typicode.com/posts/"
:before-upload="beforeAvatarUpload" :on-success="handleAvatarSuccess" :show-file-list="false" :file-list="fileList">
<template #trigger>
<el-button type="primary">select file</el-button>
</template>
<el-button class="ml-3" type="success"> upload to server </el-button>
<template #tip>
<div class="el-upload__tip">jpg/png files with a size less than 500kb</div>
</template>
</el-upload>
<crud-template :home-data="field" :tableData="testData">
</crud-template>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { barkFileName } from '@/utils/utils'
import { UploadProps, UploadUserFile } from 'element-plus'
import { ElMessage } from 'element-plus'
// @ts-ignore crudFrom模板
import CrudTemplate from "@/crud/index.vue"

const uploadRef = ref()
const imageUrl = ref('')
const fileList = ref<UploadUserFile[]>([])

const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile
) => {
imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}

//文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
console.log(rawFile);
if (rawFile.type !== 'image/jpeg') {
ElMessage.error('头像图片必须为JPG格式!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('头像图片大小不能超过2MB!')
return false
const testData: any = [
{
title: '黔通智联',
sort: '1',
start: '启用',
children: [{
title: '部门一',
start: '启用',
sort: '2'
}]
},
{
title: '世纪恒通',
sort: '3',
start: '启用',
children: [{
title: '部门二',
start: '启用',
sort: '4'
}]
}
return true
// uploadRef.value.clearFiles() 默认上传成功后调用
]

const field = {
rowKey: 'title',
searchShow: false,
crudShow: false,
field: [{
prop: 'title',
label: '名称',
}, {
prop: 'sort',
label: '排序',
}, {
prop: 'start',
label: '状态',
}]
}
</script>

+ 45
- 0
src/views/system/home/文件上传模板.vue View File

@@ -0,0 +1,45 @@
<template>
<!-- accept 限制上传文件格式 .text :auto-upload="false"-->
<el-upload ref="uploadRef" action="https://jsonplaceholder.typicode.com/posts/"
:before-upload="beforeAvatarUpload" :on-success="handleAvatarSuccess" :show-file-list="false" :file-list="fileList">
<template #trigger>
<el-button type="primary">select file</el-button>
</template>
<el-button class="ml-3" type="success"> upload to server </el-button>
<template #tip>
<div class="el-upload__tip">jpg/png files with a size less than 500kb</div>
</template>
</el-upload>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { barkFileName } from '@/utils/utils'
import { UploadProps, UploadUserFile } from 'element-plus'
import { ElMessage } from 'element-plus'

const uploadRef = ref()
const imageUrl = ref('')
const fileList = ref<UploadUserFile[]>([])

const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile
) => {
imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}

//文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
console.log(rawFile);
if (rawFile.type !== 'image/jpeg') {
ElMessage.error('头像图片必须为JPG格式!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('头像图片大小不能超过2MB!')
return false
}
return true
// uploadRef.value.clearFiles() 默认上传成功后调用
}
</script>

src/views/system/home/Home copy2.vue → src/views/system/home/文件导入导出模板.vue View File


+ 3
- 3
src/views/system/login/Login.vue View File

@@ -57,7 +57,7 @@

console.log(bgVideo);

const item = reactive({
const item = reactive<any>({
account: 'admin',
password: '123456',
rememberPSWD: ''
@@ -120,11 +120,11 @@
verify.value = false
})

const submitForm = (formEl) => {
const submitForm = (formEl: any) => {
if (!formEl) {
return
}
formEl.validate((valid) => {
formEl.validate((valid: any) => {
if (valid) { //是否通过表单验证
if (item.rememberPSWD) {
Cookies.set('account', item.account)

+ 22
- 62
src/views/system/menu/index.vue View File

@@ -1,67 +1,27 @@
<template>
<div style="padding: 20px;">
<div class="mb-4" style=" margin-bottom:20px">
<el-button icon="EditPen" type="primary" @click="dialogFormVisible = true">新增</el-button>
<el-button icon="Edit" type="success" @click="dialogFormVisible = true">修改</el-button>
<el-button icon="Delete" type="danger" @click="dialogFormVisible = true">删除</el-button>
</div>
<!-- default-expand-all 默认展开 -->
<el-table :data="list" style="width: 100%" row-key="path" default-expand-all>
<el-table-column type="selection" width="55" />
<el-table-column prop="title" label="菜单标题" width="180" />
<el-table-column prop="icon" label="图标" width="180" />
<el-table-column prop="order" label="排序" />
<el-table-column prop="auth" label="权限标识" />
<el-table-column prop="path" label="页面名称" />
<el-table-column prop="visible" label="可见" />
<el-table-column>
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 弹出框 -->
<el-dialog v-model="dialogFormVisible" title="菜单管理">
<el-form :model="form">
<el-form-item label="菜单名称">
<el-input v-model="form.name" autocomplete="off" />
</el-form-item>
<el-form-item label="菜单路径">
<el-input v-model="form.path" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="dialogFormVisible = false">确认</el-button>
</span>
</template>
</el-dialog>
</div>
<crud-template :home-data="field" :tableData="list">
</crud-template>
</template>

<script lang="ts" setup>
import {
list
} from '@/data/menuData.ts'
import {
reactive,
ref
} from 'vue'
const dialogFormVisible = ref(false)

const form = reactive({
name: '',
path: '',
})

// @ts-ignore crudFrom模板
import CrudTemplate from "@/crud/index.vue"
import {
list
} from '@/data/menuData'

const handleEdit = (index, row) => { //编辑
console.log(index, row)
}
const handleDelete = (index, row) => { //删除
console.log(index, row)
}
const field = {
rowKey: 'title',
searchShow: false,
crudShow: false,
field: [{
prop: 'title',
label: '菜单标题',
}, {
prop: 'icon',
label: '图标名称',
}, {
prop: 'path',
label: '页面名称',
}]
}
</script>

Loading…
Cancel
Save