Compare commits

...

26 Commits
master ... web

Author SHA1 Message Date
安虹睿 ab875ebcb3 【EDI】pc前端 5 days ago
安虹睿 de86739eb4 【EDI前端】暂存 1 week ago
安虹睿 9dc2947c94 【EDI前端】 1 week ago
安虹睿 9ae26eb470 【EDI前端】菜单修复+部分暂存 2 weeks ago
安虹睿 74325bfadc 【EDI前端】暂存 2 weeks ago
安虹睿 cf42ddbccc 【EDI前端】缺陷,页面更改及封装暂存 2 weeks ago
安虹睿 8f541f4305 【edi前端】页面更改+缺陷+组件暂存 3 weeks ago
安虹睿 75483bceba 【EDI前端】log页面+任务+其他优化 3 weeks ago
安虹睿 84ef947e56 【EDI】前端暂存 3 weeks ago
安虹睿 03bbbf44b1 【EDI前端】暂存 3 weeks ago
安虹睿 ea1165ae08 【EDI前端】暂存 4 weeks ago
安虹睿 e69fbed185 【EQI】前端暂存 4 weeks ago
安虹睿 cda5da22f6 暂存 4 weeks ago
安虹睿 bf1dd3ccde 【EQI前端】部分暂存 4 weeks ago
安虹睿 3a265eb2ef 【EQI】前端开发 1 month ago
安虹睿 42520a2811 【EQI前端】功能页面+table编辑方式暂存 1 month ago
安虹睿 b82827bf71 【EQI前端】功能开发 1 month ago
安虹睿 5f53b4be6e 【EQI前端】编辑/新增/删除封装 + 功能页面等开发 1 month ago
安虹睿 a330fee7d7 【EQI前端】手动传出+明细+任务等功能开发 1 month ago
安虹睿 ab46d560ac 【EQI前端】编辑,导入等暂存 1 month ago
安虹睿 5e6ae267df 【EQI前端】table,tablePage组件更新,根据filter格式封装,表头封装,页面开发 1 month ago
安虹睿 36d57e116d 【EQI前端】普通头部查询,及通用导出功能封装开发,已开发页面使用新封装联调开发,表格排序封装开发 1 month ago
安虹睿 341097ef6f 【EQI】查询条件格式更改 1 month ago
安虹睿 2f59b9a618 【EQI接口】配置文件提出处理 1 month ago
安虹睿 f6b37e4cb5 【EQI前端】table+pager+tablePage组件及部分页面开发 1 month ago
安虹睿 b190182cc4 前端分支 2 months ago
  1. 2
      Web/.env.development
  2. 2
      Web/.env.production
  3. 1
      Web/index.html
  4. 5
      Web/public/config.js
  5. BIN
      Web/public/favicon.ico
  6. BIN
      Web/public/logo.png
  7. BIN
      Web/public/logoSmall.png
  8. BIN
      Web/public/logo_op.png
  9. 123
      Web/src/api/common/index.js
  10. 10
      Web/src/api/system/customlog.js
  11. 10
      Web/src/api/system/taskConifgureApi.js
  12. 10
      Web/src/api/system/taskSubApi.js
  13. 2
      Web/src/components/Uploads/importErrorDialog.vue
  14. 2
      Web/src/components/Uploads/multipleImgUpload.vue
  15. 2
      Web/src/components/Uploads/singleImgUpload.vue
  16. 218
      Web/src/components/apiEditPop/index.vue
  17. 920
      Web/src/components/ediTtablePage/index.vue
  18. 998
      Web/src/components/ediTtablePage/index_oldExport.vue
  19. 65
      Web/src/components/elPager/index.vue
  20. 368
      Web/src/components/elTable/index.vue
  21. 336
      Web/src/components/elTable/index_norule.vue
  22. 353
      Web/src/components/elTable/index_rulr.vue
  23. 154
      Web/src/components/importPop/index.vue
  24. 216
      Web/src/components/setColumsPop/index.vue
  25. 690
      Web/src/components/tablePage/index.vue
  26. 689
      Web/src/components/tablePage/index_oldExport.vue
  27. 4
      Web/src/layout/components/Footer/index.vue
  28. 14
      Web/src/layout/components/Sidebar/Logo.vue
  29. 2
      Web/src/layout/components/Sidebar/index.vue
  30. 6
      Web/src/layout/components/SidebarColumn/index.vue
  31. 5
      Web/src/main.js
  32. 6
      Web/src/settings.js
  33. 2
      Web/src/styles/element-ui.scss
  34. 2
      Web/src/styles/index.scss
  35. 2
      Web/src/styles/variables.module.scss
  36. 196
      Web/src/utils/common/apiServeNames.js
  37. 1094
      Web/src/utils/common/apiTableColumns.js
  38. 125
      Web/src/utils/common/enumList.js
  39. 96
      Web/src/utils/common/index.js
  40. 11
      Web/src/utils/common/localStorage.js
  41. 12
      Web/src/utils/formatTime.js
  42. 2
      Web/src/utils/get-page-title.js
  43. 14
      Web/src/utils/request.js
  44. 37
      Web/src/views/dashboard/index.vue
  45. 72
      Web/src/views/dashboard/menuItem.vue
  46. 63
      Web/src/views/demo/tablePageDemo.vue
  47. 38
      Web/src/views/logisticsPlan/supplierConDate/index.vue
  48. 38
      Web/src/views/logisticsPlan/supplierConMmrp/index.vue
  49. 38
      Web/src/views/logisticsPlan/supplierConPo/index.vue
  50. 26
      Web/src/views/logisticsPlan/supplierDelState/index.vue
  51. 26
      Web/src/views/logisticsPlan/supplierInvData/index.vue
  52. 26
      Web/src/views/logisticsPlan/supplierMrpDate/index.vue
  53. 26
      Web/src/views/logisticsPlan/supplierMrpMonth/index.vue
  54. 26
      Web/src/views/logisticsPlan/supplierMrpState/index.vue
  55. 26
      Web/src/views/logisticsPlan/supplierMrpWarning/index.vue
  56. 26
      Web/src/views/logisticsPlan/supplierPo/index.vue
  57. 26
      Web/src/views/logisticsPlan/supplierProCschedul/index.vue
  58. 26
      Web/src/views/logisticsPlan/supplierProHschedul/index.vue
  59. 26
      Web/src/views/logisticsPlan/supplierProPlaning/index.vue
  60. 26
      Web/src/views/logisticsPlan/supplierProTschedul/index.vue
  61. 26
      Web/src/views/logisticsPlan/supplierReturn/index.vue
  62. 26
      Web/src/views/logisticsPlan/supplierSaWeek/index.vue
  63. 29
      Web/src/views/logisticsPlan/supplierSinvData/index.vue
  64. 29
      Web/src/views/productionQuality/supplierBom/index.vue
  65. 30
      Web/src/views/productionQuality/supplierEmployee/index.vue
  66. 30
      Web/src/views/productionQuality/supplierInfo/index.vue
  67. 30
      Web/src/views/productionQuality/supplierProAttachmentData/index.vue
  68. 30
      Web/src/views/productionQuality/supplierProCps/index.vue
  69. 30
      Web/src/views/productionQuality/supplierProData/index.vue
  70. 30
      Web/src/views/productionQuality/supplierProFirstPassyield/index.vue
  71. 30
      Web/src/views/productionQuality/supplierProFlaw/index.vue
  72. 30
      Web/src/views/productionQuality/supplierProMaterialStock/index.vue
  73. 29
      Web/src/views/productionQuality/supplierProProcess/index.vue
  74. 30
      Web/src/views/productionQuality/supplierProProcessEquipment/index.vue
  75. 26
      Web/src/views/productionQuality/supplierProScheduling/index.vue
  76. 29
      Web/src/views/productionQuality/upplierProMaterialData/index.vue
  77. 30
      Web/src/views/productionQuality/upplierProStationFirstPassyield/index.vue
  78. 2
      Web/src/views/system/autoJob/components/deferredJobDialog.vue
  79. 2
      Web/src/views/system/autoJob/index.vue
  80. 2
      Web/src/views/system/components/orgCascader.vue
  81. 2
      Web/src/views/system/components/orgTree.vue
  82. 2
      Web/src/views/system/components/userSelect.vue
  83. 2
      Web/src/views/system/components/userSelectDialog.vue
  84. 2
      Web/src/views/system/dataDict/components/dictDetailDialog.vue
  85. 2
      Web/src/views/system/dataDict/components/editDialog.vue
  86. 2
      Web/src/views/system/dataDict/components/editDictDetailDialog.vue
  87. 2
      Web/src/views/system/dataDict/index.vue
  88. 2
      Web/src/views/system/log/logDiffIndex.vue
  89. 2
      Web/src/views/system/log/logEventIndex.vue
  90. 2
      Web/src/views/system/log/logExceptionIndex.vue
  91. 2
      Web/src/views/system/log/logJobIndex.vue
  92. 2
      Web/src/views/system/log/logLoginIndex.vue
  93. 2
      Web/src/views/system/log/logOperateIndex.vue
  94. 2
      Web/src/views/system/login/components/tenantDialog.vue
  95. 4
      Web/src/views/system/login/index.vue
  96. 27
      Web/src/views/system/menu/components/editDialog.vue
  97. 1
      Web/src/views/system/menu/index.vue
  98. 2
      Web/src/views/system/message/components/editDialog.vue
  99. 3
      Web/src/views/system/message/components/publishDialog.vue
  100. 2
      Web/src/views/system/message/components/viewDialog.vue

2
Web/.env.development

@ -2,4 +2,4 @@
ENV = 'development'
# base api
VITE_API_BASE_URL = 'http://127.0.0.1:7001'
VITE_API_BASE_URL = 'http://192.168.1.228:7629'

2
Web/.env.production

@ -2,5 +2,5 @@
ENV = 'production'
# base api
VITE_API_BASE_URL = 'http://127.0.0.1:5001'
VITE_API_BASE_URL = 'http://192.168.1.228:7629'

1
Web/index.html

@ -5,6 +5,7 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script src="/config.js"></script>
</head>
<body>
<div id="app"></div>

5
Web/public/config.js

@ -0,0 +1,5 @@
let systemConfig = {
title:'EDI接口平台',
// 请求路径
baseUrl: 'http://192.168.1.228:7629',
}

BIN
Web/public/favicon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
Web/public/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
Web/public/logoSmall.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Web/public/logo_op.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

123
Web/src/api/common/index.js

@ -0,0 +1,123 @@
// 公用API
import request from '@/utils/request'
// 通用post
export function getCommonPost(url,data) {
return request({
url: url,
method: 'post',
data
})
}
// 获取分页
export function getCommonPaged(urlName,data) {
return request({
url: `/api/${urlName}/getdatapaged`,
method: 'post',
data
})
}
// 通过id获取实体
export function getCommonInfoById(urlName,id) {
return request({
url: `/api/${urlName}/getbyid`,
method: 'get',
params:{id:id}
})
}
// 新增提交
export function postCommonCreate(urlName,data) {
return request({
url: `/api/${urlName}/create`,
method: 'post',
data
})
}
// 修改提交
export function putCommonUpdate(urlName,data) {
return request({
url: `/api/${urlName}/update`,
method: 'put',
data
})
}
// 删除提交
export function deleteCommonApi(urlName,id) {
return request({
url: `/api/${urlName}/delete`,
method: 'DELETE',
headers:{
'content-type':'application/json-patch+json'
},
data:id
})
}
// 导出
export function postCommonExport(urlName,data) {
return request({
url: `/api/${urlName}/exportdata`,
method: 'post',
responseType:'blob',
data
})
}
// 获取导入模板
export function getCommonImportTemplate(urlName) {
return request({
url: `/api/${urlName}/getimporttemplate`,
method: 'get',
responseType:'blob',
})
}
// 手动开关
export function getCommonCustominvoke(params) {
return request({
url: `/api/taskconifgure/custominvoke`,
method: 'get',
params:params
})
}
// 获取明细列表-如:任务列表-查看详情
export function getCommonDeatailPaged(urlName,data) {
return request({
url: `/api/${urlName}/getdetail`,
method: 'post',
data
})
}
// 通过id获取详情实体
export function getCommonDetailById(urlName,id) {
return request({
url: `/api/${urlName}/getdetialbyid`,
method: 'get',
params:{id:id}
})
}
// 手动传出(批量)
export function postCommonConfirmMany(urlName,data) {
return request({
url: `/api/${urlName}/confirm`,
method: 'post',
data
})
}
// 保存页面(批量)
export function postCommonUpdateMany(urlName,data) {
return request({
url: `/api/${urlName}/batchupdate`,
method: 'post',
data
})
}

10
Web/src/api/system/customlog.js

@ -0,0 +1,10 @@
import request from '@/utils/request'
// 下载JSON
export function getLogJsonList(uid) {
return request({
url: `/api/customlog/getlogrequestjsonlist`,
method: 'get',
params:{uId:uid},
})
}

10
Web/src/api/system/taskConifgureApi.js

@ -0,0 +1,10 @@
import request from '@/utils/request'
// 是否自动执行
export function getSetisautoByUid(params) {
return request({
url: `/api/taskconifgure/setisauto`,
method: 'get',
params:params
})
}

10
Web/src/api/system/taskSubApi.js

@ -0,0 +1,10 @@
import request from '@/utils/request'
// 是否自动执行
export function getCanceltaskByUid(id) {
return request({
url: `/api/tasksub/canceltask`,
method: 'get',
params:{taskId:id}
})
}

2
Web/src/components/Uploads/importErrorDialog.vue

@ -44,7 +44,7 @@
</el-dialog>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { reactive,defineExpose } from 'vue'
import * as XLSX from 'xlsx'
const state = reactive({

2
Web/src/components/Uploads/multipleImgUpload.vue

@ -18,7 +18,7 @@
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted,defineExpose } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import { getFileUploadPath, getFiles } from '@/api/system/fileApi'
import { ElMessage } from 'element-plus'

2
Web/src/components/Uploads/singleImgUpload.vue

@ -12,7 +12,7 @@
</el-upload>
</template>
<script setup>
import { ref } from 'vue'
import { ref,defineExpose } from 'vue'
import { ElMessage } from 'element-plus'
import { getFileUploadPath, getFiles } from '@/api/system/fileApi'
import store from '@/stores'

218
Web/src/components/apiEditPop/index.vue

@ -0,0 +1,218 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="handleType=='create' ? '新增' : '编辑'"
width="70%"
:close-on-click-modal="false"
top="10vh"
>
<div v-loading="formLoading" style="height:calc(70vh - 50px);overflow:auto">
<el-form
ref="editFormRef"
v-if="!formLoading"
:model="formData"
:size="'large'"
:rules="formRulesData">
<el-row :gutter="40">
<el-col
v-for="(item, index) in formConfig"
:span="getItemConfig(item,'colSpan') || 12"
:key="index"
>
<el-form-item
:prop="getItemConfig(item,'prop')"
:label="getItemConfig(item,'title')"
:label-width="getItemConfig(item,'labelWidth') || 180"
>
<!-- 文本 -->
<el-input
v-if="!getItemConfig(item) || getItemConfig(item) == 'input'"
v-model="formData[getItemConfig(item,'prop')]"
:placeholder="'请输入'"
:clearable="!getItemConfig(item,'noClear')"
:disabled="getItemConfig(item,'disabled')"
/>
<!-- 数字 -->
<el-input-number
v-if="getItemConfig(item) == 'number'"
v-model="formData[getItemConfig(item,'prop')]"
:min="getItemConfig(item,'min')"
:max="getItemConfig(item,'max')"
:clearable="!getItemConfig(item,'noClear')"
:disabled="getItemConfig(item,'disabled')"
/>
<!-- 时间 -->
<el-date-picker
v-if="getItemConfig(item) == 'datetime'"
v-model="formData[getItemConfig(item,'prop')]"
style="width:100%"
type="datetime"
:format="item.format || 'YYYY-MM-DD HH:mm:ss'"
:value-format="item.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
:clearable="!getItemConfig(item,'noClear')"
:disabled="getItemConfig(item,'disabled')"
/>
<!-- 选择框 -->
<el-select
v-if="getItemConfig(item) == 'select' || getItemConfig(item) == 'tagFilter' || getItemConfig(item) == 'filter'"
v-model="formData[getItemConfig(item,'prop')]"
:filterable="!getItemConfig(item,'noSearch')"
placeholder="请选择"
:clearable="!getItemConfig(item,'noClear')"
:disabled="getItemConfig(item,'disabled')"
>
<el-option
v-for="(op,op_index) in getItemConfig(item,'options')"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<template #footer>
<div style="padding:10px">
<el-button el-button @click="close">取消</el-button>
<el-button :disabled="formLoading" type="primary" @click="submitForm">确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
defineOptions({ name: 'apiEditPop' })
import { reactive, ref, onMounted,nextTick,defineExpose } from 'vue'
import { ElDialog,ElMessage } from 'element-plus'
import { getCommonInfoById } from '@/api/common/index'
import apiTableColumns from '@/utils/common/apiTableColumns'
import { useRoute } from 'vue-router'
const route = useRoute()
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formData = ref(null)//
const formConfig = ref(null)//
const handleType = ref(null)//
const formRulesData = ref(null)
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
//
formRules:{
type: Object,
default: null
}
})
/** 重置表单 */
const resetForm = () => {
//
formLoading.value = false
formData.value = null
formConfig.value = null
}
/** 打开弹窗 */
const open = (configs,row) => {
resetForm()
getFormRules()
nextTick(() => {
dialogVisible.value = true
formConfig.value = configs
//
if(row){
handleType.value='edit'
getFormData(row.uId)
}else{
handleType.value='create'
//
formData.value = {}
configs.forEach(item=>{
if(item.type && item.type == 'number'){
formData.value[item.prop] = 0
}else{
formData.value[item.prop] = ""
}
})
}
})
}
/** 关闭弹窗 */
const close = () => {
//
resetForm()
dialogVisible.value = false
}
//
const changeLoading = (data) => {
formLoading.value = data
}
const editFormRef = ref(null)//
//
const validate = (data) => {
return editFormRef.value.validate(data)
}
defineExpose({ open,close,changeLoading,validate })
//
const getFormRules = () => {
if(props.formRules) {
formRulesData.value = props.formRules
}else{
formRulesData.value = {}
apiTableColumns[props.apiName].forEach(item=>{
if(item.required || (item.searchFilter && item.searchFilter.required)){
formRulesData.value[item.prop] = [{ required: true, message: '必填项', trigger: 'blur' }]
}
})
}
}
/** 获取表单 */
const getFormData = async (uId) => {
formLoading.value = true
getCommonInfoById(props.apiName,uId)
.then(res=>{
formData.value = res.data
formLoading.value = false
})
.catch(err=>{
dialogVisible.value = false
ElMessage.error('获取失败,请重试')
})
.finally(()=>{formLoading.value = false})
}
//
const getItemConfig = (item,type='type') => {
if(item.formConfig && item.formConfig[type]){
return item.formConfig[type]
}else{
return item[type]
}
}
const emits = defineEmits(['submitEditForm'])
/** 提交表单 */
const submitForm = async () => {
emits('submitEditForm',handleType.value,formData.value,formConfig.value)
}
</script>
<style lang="scss" scoped>
::v-deep .el-row{
margin:0 !important
}
</style>

920
Web/src/components/ediTtablePage/index.vue

@ -0,0 +1,920 @@
<template>
<div class="app-container" v-loading="state.loading">
<!-- 查询头部 -->
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)">
<el-form :inline="true" v-if="!props.hideSearch">
<el-form-item
v-auth="props.apiName + state.searchBtnOptions['search'].auth"
v-for="(item,index) in props.searchOptions"
:key="index"
:label="item.label">
<!-- 文本 -->
<el-input
v-if="item.type == 'input'"
v-model="props.searchFilter[item.prop]"
:placeholder="item.label"
:clearable="!item.noClear"
/>
<!-- 数字 -->
<el-input-number
v-if="item.type == 'number'"
v-model="props.searchFilter[item.prop]"
:min="item.min"
:max="item.max"
/>
<!-- 时间区域 -->
<el-date-picker
v-if="item.type == 'datetimerange'"
v-model="props.searchFilter[item.prop]"
type="datetimerange"
start-placeholder="起始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width:370px"
/>
<!-- 选择框 -->
<el-select
v-if="item.type == 'select'"
v-model="props.searchFilter[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
style="width: 240px"
:clearable="!item.noClear"
>
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
v-for="(btn,btn_key) in props.searchButtons"
:key="btn_key"
:icon="state.searchBtnOptions[btn].icon"
v-auth="state.searchBtnOptions[btn].sAuth || props.apiName + state.searchBtnOptions[btn].auth"
:type="state.searchBtnOptions[btn].type"
@click="searchBtnHandle(btn)"
>{{state.searchBtnOptions[btn].label}}</el-button>
</el-form-item>
</el-form>
<!-- 右侧按钮(保存页面) -->
<div>
<el-button
v-for="(btn,btn_key) in state.searchRightBtn"
:key="btn_key"
:icon="btn.icon"
v-auth="btn.sAuth || props.apiName + btn.auth"
:type="btn.type"
@click="searchRightBtnHandle(btn)"
style="margin-right: 10px"
>{{btn.label}}</el-button>
<!-- 字段设置 -->
<setColumsPop
style="margin-left: auto;"
:localTableColumnsName="state.localTableColumnsName"
:initTableColums="state.initTableColums"
:tableColumns="getTableColumns()"
v-if="!props.hideSetColums"
></setColumsPop>
</div>
</el-card>
<!-- 头部详情 -->
<el-card v-loading="state.detailLoading" class="headerInfo-container" v-if="!props.hideHeaderInfo">
<el-descriptions label-width="120" :title="`当前页【第${getIndexById()}行】数据信息`" :border="true" :column="5" v-if="state.headerInfoData && state.headerInfoData.length > 0">
<el-descriptions-item
v-for="(item,index) in state.headerInfoData"
:key="index"
:label="item.label">
{{item.value}}
</el-descriptions-item>
</el-descriptions>
<el-empty v-else description="暂无数据" class="headerInfoEmpty"/>
</el-card>
<!-- 列表 -->
<el-card class="paged-table-container">
<elTable
ref="table_Ref"
:columnWidth="props.columnWidth"
:columnHeaderAlign="props.columnHeaderAlign"
:columnAlign="props.columnAlign"
:tableData="state.tableData"
:tableColumns="getTableColumns()"
@sortChange="sortChange"
:leftOperation="props.leftOperation"
@leftOperationHadel="leftOperationHadel"
:rightOperation="getRightOperation()"
@rightOperationHadel="rightOperationHadel"
:multipleTable="props.multipleTable"
@tableSelectionHandle="tableSelectionHandle"
@editItemFocusHandle="(item,scope,event)=>{getItemDetail(item.type,scope.row,'focus')}"
@editItemChangeHandle="editItemChangeHandle"
@cell-click="(row,column,cell,event)=>{getItemDetail('cell',row,'cellClick')}"
@editItemClearHandle="(item,scope)=>{getItemDetail(item.type,scope.row,'clear')}"
:getEditItemDisabled="getEditItemDisabled"
:selectableDisabled="selectableDisabled"
:tableRowClassName="tableRowClassName"
:showTableIndex="props.showTableIndex"
></elTable>
<!-- :tableFormRules="state.tableFormRulesData" -->
<elPager
v-loading="state.pageLoading"
style="margin-top: 15px;float:right"
:pager="state.pager"
@size-change="pageSizeChange"
@current-change="pageCurrentChange"
></elPager>
</el-card>
<!-- 导入弹窗 -->
<importPop
ref="importPopRef"
:apiName="props.apiName"
@success="importSuccess"
/>
<!-- 编辑弹窗 -->
<apiEditPop
ref="apiEditPopRef"
:apiName="props.apiName"
@submitEditForm="submitEditForm"
:formRules="props.apiEditFormRules"
/>
</div>
</template>
<script setup>
defineOptions({ name: 'ediTtablePage' })
import store from '@/stores'
import apiTableColumns from '@/utils/common/apiTableColumns'
import { reactive, ref, onMounted,computed } from 'vue'
import {
getCommonPaged,
getCommonDeatailPaged,
postCommonExport,
postCommonCreate,
putCommonUpdate,
deleteCommonApi,
getCommonCustominvoke,
getCommonDetailById,
postCommonConfirmMany,
postCommonUpdateMany
} from '@/api/common/index'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import elTable from '@/components/elTable/index.vue'
import elPager from '@/components/elPager/index.vue'
import setColumsPop from '@/components/setColumsPop/index.vue'
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index'
import { downloadByData } from '@/utils/download'
import importPop from '@/components/importPop/index.vue'
import apiEditPop from '@/components/apiEditPop/index.vue'
import { formatDate } from '@/utils/formatTime'
import apiServeNames from '@/utils/common/apiServeNames'
import { useRoute } from 'vue-router'
const route = useRoute()
const userStore = store.userStore()
const userInfo = userStore.state
const auths = store.permissionStore()
const state = reactive({
loading:false,
detailLoading:false,
pageLoading:false,
searchBtnOptions:{
search:{icon:'Search',auth:':page',label:'查询',type:null},
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'},
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'},
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'},
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'},
outputMany:{icon:'Position',auth:':outputMany',label:'手动传出',type:'primary'},
},
searchRightBtn:[{name:'pageSave',icon:'Check',auth:':pageSave',label:'保存页面',type:'warning'}],
tableData:[],
// table
sortFilter:{
sortBy:undefined,
isAscending:undefined
},
pager:{
page: 1,
pageSize: 10,
total: 1,
},
tableSelectList:[],
leaveSaveTip:'此操作将重新渲染页面,检测有数据【未保存】,操作后将【清空未保存数据】,是否确定继续?',
//
headerInfoData:[],
currentDetailId:null,//id
//
stage_tableData:[],
//
stage_indexs:[],
//
initTableColums:[],
localTableColumnsName:null,
//tabel
tableFormRulesData:null,
})
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
// colum
detailColumName:{
type: String,
default: null
},
// api detailApigetdetailpageApigetdatapaged
apiType: {
type: String,
default: null
},
//
hideSearch:{
type: Boolean,
default: false
},
//
multipleTable:{
type: Boolean,
default: false
},
//
showTableIndex:{
type: Boolean,
default: true
},
//
leftOperation:{
type: Object,
default: null
},
//
rightOperation:{
type: [Object,String],
default: null
},
// api
showApiRightOperation:{
type: Object,
default: null
},
// readState=true
// 使,=
apiRightHideConfig:{
type: Object,
default: {
apiUpdate:{prop:'readState',ruleValue:true},
apiDelete:{prop:'readState',ruleValue:true},
}
},
// table
tableColumns: {
type: Object,
default: null
},
//
searchOptions: {
type: Object,
default: []
},
//
searchButtons: {
type: Object,
default: ['search','export']
},
// tablefilter
searchFilter: {
type: Object,
default: {}
},
//
columnWidth:{
type: Number,
default: 120
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
apiEditFormRules:{
type: Object,
default: null
},
// table
tableFormRules:{
type: Object,
default: null
},
//
hideHeaderInfo:{
type: Boolean,
default: false
},
// readState=true
// 使,=
editDisabledConfig:{
type: Object,
default: [
{prop:'readState',ruleValue:true},
// {prop:'releaseEdition',ruleValue:'2024121901'},
]
},
//
hideSetColums:{
type: Boolean,
default: false
}
})
// noFilter
function getTableColumns(noFilter){
if(noFilter){
return props.tableColumns || apiTableColumns[props.apiName]
}else{
state.localTableColumnsName = getLocalTableColumnsName(useRoute().name)
if(props.apiType == 'detailApi'){
state.localTableColumnsName = getLocalTableColumnsName(props.apiName+'Detail')
}
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName))
state.initTableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _local && _local != null && _local != undefined ? _local : JSON.parse(JSON.stringify(state.initTableColums))
return _list
}
// return props.tableColumns || apiTableColumns[props.apiName]
}
const emits = defineEmits([
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle'
])
// table
function tableSelectionHandle (val){
state.tableSelectList = val
emits('tableSelectionHandle',val)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getRightOperation() {
// api
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){
return props.rightOperation
}
// api
else if(
(typeof props.rightOperation == 'object' && props.showApiRightOperation)
|| typeof props.rightOperation == 'string'
){
// api
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',')
let _config = {
apiUpdate:{label:'编辑',type:'warning'},
apiDelete:{label:'删除',type:'danger'},
}
let _btns = []
if(_apiArr && _apiArr.length > 0){
_apiArr.forEach(item => {
_btns.push({
label:_config[item].label,
name:item,
link:true,
type:_config[item].type,
auth:props.apiName+':'+item,
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue}
})
});
}
// api
if(typeof props.rightOperation == 'object'){
_btns = [..._btns,...props.rightOperation]
}
return _btns
}
}
//
const apiEditPopRef = ref()
function rightOperationHadel(btn,scope) {
//
if(btn.name == 'apiUpdate'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list,scope.row)
}
//
if(btn.name == 'apiDelete'){
ElMessageBox.confirm(`是否确定删除?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
deleteCommonApi(props.apiName,scope.row.uId)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{state.loading = false})
})
}
emits('rightOperationHadel',btn,scope)
}
//
const submitEditForm = async (type,formData,formConfig) => {
apiEditPopRef.value.validate((valid) => {
if(valid){
//
if(type == 'create'){
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName}
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName}
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
apiEditPopRef.value.changeLoading(true)
postCommonCreate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}else{
//
if(
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime'))
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime'))
){
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName}
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName}
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
}else{
//
let _notChange=['taskconifgure']
if(_notChange.indexOf(props.apiName) < 0){
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}`
}
}
apiEditPopRef.value.changeLoading(true)
putCommonUpdate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}
}
})
}
//
function getPageParams(){
let _filters = []
if(props.hideSearch){
_filters = props.searchFilter
}else{
for(let i in props.searchFilter){
let _item = props.searchOptions.filter(item=>item.prop == i)
let _type = (_item && _item.length > 0) ? _item[0].type : null
if(props.searchFilter[i] || props.searchFilter[i] == 0){
//
if(_type == 'datetimerange'){
_filters.push(
{
logic: "And",
column: i,
action: '>=',
value: props.searchFilter[i][0]
}
)
_filters.push(
{
logic: "And",
column: i,
action: '<=',
value: props.searchFilter[i][1]
}
)
}else{
let _action = 'like'
let _EqualTypes = ['tagFilter','filter','number','select']//
if(_EqualTypes.indexOf(_type) >= 0){
_action = '=='
}
_filters.push(
{
logic: "And",
column: i,
action: _action,
value: props.searchFilter[i]
}
)
}
}
}
}
let _pageParams = getPageParamsForFilter({
pageNumber:state.pager.page,
pageSize:state.pager.pageSize,
sortBy:state.sortFilter.sortBy,
isAscending:state.sortFilter.isAscending,
condition:{
filters:_filters
}
})
return _pageParams
}
//
function getTableData(page) {
state.stage_indexs = []
state.currentDetailId = null
state.headerInfoData = []
state.tableSelectList = []
if(props.apiType == 'detailApi'){
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
getCommonDeatailPaged(props.apiName,getPageParams())
.then((resp) => {
state.headerInfoData = []
state.tableData = resp.data.data
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data))
state.pager.total = resp.data.totalCount
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}else{
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
getCommonPaged(props.apiName,getPageParams())
.then((resp) => {
state.headerInfoData = []
state.tableData = resp.data.data
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data))
state.pager.total = resp.data.totalCount
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
}
const importPopRef = ref()
//
function searchBtnHandle(btn){
//
if(btn == 'search'){
beforClearEdit().then(() => {
getTableData()
})
}
//
else if (btn == 'create'){
beforClearEdit().then(() => {
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list)
})
}
//
else if (btn == 'import'){
beforClearEdit().then(() => {
importPopRef.value.open()
})
}
//
else if (btn == 'export'){
beforClearEdit().then(() => {
state.loading = true
getTableData()//
postCommonExport(props.apiName,getPageParams())
.then((res) => {
downloadByData(res.data,route.meta.title+'.xlsx')
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(() => (state.loading = false))
})
}
//
else if (btn == 'custominvoke'){
beforClearEdit().then(() => {
state.loading = true
let _data = {
taskName:apiServeNames[props.apiName].taskName,
client:'Chery'
}
getCommonCustominvoke(_data)
.then((res) => {
ElMessage.success('操作成功!')
getTableData(1)//
})
.finally(() => (state.loading = false))
})
}
//
else if (btn == 'outputMany'){
let _idEditData = checkPageEditList()
if(_idEditData && _idEditData.length > 0){
return ElMessage.warning('当前有未保存修改项,请先保存页面')
}
if(!state.tableSelectList || state.tableSelectList.length <= 0 ){
return ElMessage.warning('未选中任何数据')
}
ElMessageBox.confirm('是否确定手动传出?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
postCommonConfirmMany(props.apiName,state.tableSelectList)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1)
})
.finally(()=>{state.loading = false})
})
}
}
const table_Ref = ref(null)
//
function searchRightBtnHandle(btn){
//
if(btn.name == 'pageSave'){
// table_Ref.value.tableForm_Ref.validate((valid)=>{
// if(valid){
let _idEditData = checkPageEditList()
if(!_idEditData || _idEditData.length <= 0)return ElMessage.warning('暂无数据修改')
//
// [feedbackResults]=1[ventureType],[ventureSpecific],[measures]
let _indexs = []
_idEditData.forEach(item=>{
if(item.feedbackResults == '1' && (
!item.ventureType || item.ventureType == '' ||
!item.ventureSpecific || item.ventureSpecific == '' ||
!item.measures || item.measures == ''
)){
_indexs.push(getIndexById(item.id))
}
})
if(_indexs && _indexs.length > 0){
return ElMessage.error(`修改数据中【第${_indexs}行】数据中,【反馈结果】为异常,但【风险类型】或【具体风险】或【应对措施】为空,请修改后重新提交!`)
}
ElMessageBox.confirm('是否确定提交更改?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
postCommonUpdateMany(props.apiName,_idEditData)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1)
})
.finally(()=>{state.loading = false})
})
// }
// })
}
}
//
function sortChange(data) {
beforClearEdit().then(() => {
const { prop, order } = data;
if (!prop || !order) {
state.sortFilter.sortBy = undefined;
state.sortFilter.isAscending = undefined;
getTableData(1);
return;
}
state.sortFilter.sortBy = prop;
state.sortFilter.isAscending = (order == "ascending");
getTableData(1);
})
}
//
function importSuccess(response,importDate){
getTableData()
}
// size-change
function pageSizeChange(pageSize,returnSize){
state.pageLoading=true
let _oldSize = state.pager.pageSize
state.pager.pageSize = pageSize
beforClearEdit()
.then(res => {
getTableData(1)
state.pageLoading=false
})
.catch(res=>{
state.pager.pageSize = _oldSize
state.pageLoading=false
})
}
// current-change
function pageCurrentChange(page){
beforClearEdit().then(res => {
getTableData(page)
})
}
//
function getIndexById(id){
let _id = id || state.currentDetailId
for(let i=0;i<state.stage_tableData.length;i++){
if(state.stage_tableData[i].id == _id){
return i + 1
}
}
}
//
function checkDisableByRowRule(row){
let hasDisable = false
for(let i = 0;i<props.editDisabledConfig.length;i++){
if(row[props.editDisabledConfig[i].prop] == props.editDisabledConfig[i].ruleValue){
hasDisable = true
break
}
}
return hasDisable
}
//
function getEditItemDisabled(item,row,index){
//
let _auth = auths.hasPermission(props.apiName+':pageSave')
if(item.disabled || !_auth){
return true
}
//
if(state.tableSelectList && state.tableSelectList.length > 0){
return true
}
//
return checkDisableByRowRule(row)
}
// table
function selectableDisabled(row,index){
//
let _auth = auths.hasPermission(props.apiName+':outputMany')
//
let _idEditData = checkPageEditList()
// ()
let checkRow = checkDisableByRowRule(row)
return _auth && (!_idEditData || _idEditData.length <= 0) && !checkRow
}
// Focus todo:
function getItemDetail(type,row,eventType) {
if(!row.id){return ElMessage.error('该数据无id')}
// id
if(row.id == state.currentDetailId){return}
let _focuseExt = ['input','numberInput']
// focus_focuseExtcell
if(eventType == 'focus' && _focuseExt.indexOf(type) >= 0){return}
console.log(type,row,eventType)
console.log('------------')
state.currentDetailId = row.id
state.detailLoading = true
getCommonDetailById(props.apiName,row.id)
.then((res) => {
state.headerInfoData = []
let _colums = apiTableColumns[props.detailColumName]
_colums.forEach(item=>{
state.headerInfoData.push({
label:item.title,
value:res.data[item.prop]
})
})
})
.finally(() => (state.detailLoading = false))
}
// change
function editItemChangeHandle(item,scope,data) {
if(state.stage_indexs.indexOf(scope.$index) < 0){
state.stage_indexs.push(scope.$index)
}
}
//
function beforClearEdit(){
return new Promise((resolve, reject) => {
let _idEditData = checkPageEditList()
if(!_idEditData || _idEditData.length <= 0){
resolve()
}else{
ElMessageBox.confirm(state.leaveSaveTip, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
resolve()
}).catch(()=>{
reject()
})
}
})
}
//
function checkPageEditList(){
if(!state.stage_indexs || state.stage_indexs.length<=0){
return false
}
else{
let _changeArr = []
state.stage_indexs.forEach(item=>{
if(JSON.stringify(state.stage_tableData[item]) != JSON.stringify(state.tableData[item])){
_changeArr.push(state.tableData[item])
}
})
return _changeArr
}
}
//
function tableRowClassName(data){
if(data.row.id && (data.row.id == state.currentDetailId)){return 'current-select-tableRow'}
else{return 'normal-tableRow'}
}
// apiTableColumnstable
function getTableFormRules(){
if(props.tableFormRules) {
state.tableFormRulesData = props.tableFormRules
}else{
state.tableFormRulesData = {}
apiTableColumns[props.apiName].forEach(item=>{
if(item.required){
state.tableFormRulesData[item.prop] = [{ required: true, message: '必填项', trigger: 'change' }]
}
})
}
}
onMounted(() => {
// getTableFormRules()
getTableData()
})
</script>
<style scoped lang="scss">
::v-deep .search-container{
.el-card__body{
width: 100%;
display: flex;
justify-content: space-between;
}
}
::v-deep .headerInfo-container{
margin-top:10px;
.el-card__body{
padding-bottom: 10px !important;
min-height:66px
}
}
::v-deep .headerInfoEmpty{
height:195px;
.el-empty__image{
width:90px !important
}
}
::v-deep .el-descriptions__body{
max-height: 165px;
overflow: auto;
}
</style>

998
Web/src/components/ediTtablePage/index_oldExport.vue

@ -0,0 +1,998 @@
<template>
<div class="app-container" v-loading="state.loading">
<!-- 查询头部 -->
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)">
<el-form :inline="true" v-if="!props.hideSearch">
<el-form-item
v-auth="props.apiName + state.searchBtnOptions['search'].auth"
v-for="(item,index) in props.searchOptions"
:key="index"
:label="item.label">
<!-- 文本 -->
<el-input
v-if="item.type == 'input'"
v-model="props.searchFilter[item.prop]"
:placeholder="item.label"
:clearable="!item.noClear"
/>
<!-- 数字 -->
<el-input-number
v-if="item.type == 'number'"
v-model="props.searchFilter[item.prop]"
:min="item.min"
:max="item.max"
/>
<!-- 时间区域 -->
<el-date-picker
v-if="item.type == 'datetimerange'"
v-model="props.searchFilter[item.prop]"
type="datetimerange"
start-placeholder="起始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width:370px"
/>
<!-- 选择框 -->
<el-select
v-if="item.type == 'select'"
v-model="props.searchFilter[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
style="width: 240px"
:clearable="!item.noClear"
>
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<div style="margin-right:10px" v-for="(btn,btn_key) in props.searchButtons" :key="btn_key">
<!-- 导出 -->
<!-- <el-dropdown
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:hide-on-click="false"
v-if="state.searchBtnOptions[btn].auth == ':export'"
>
<el-button
:icon="state.searchBtnOptions[btn].icon"
:type="state.searchBtnOptions[btn].type">
{{state.searchBtnOptions[btn].label}}
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="exportHandle()">按条件导出当前页</el-dropdown-item>
<el-dropdown-item divided @click="exportHandle(true)">按条件导出全部</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> -->
<!-- 其他按钮 -->
<el-button
:icon="state.searchBtnOptions[btn].icon"
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:type="state.searchBtnOptions[btn].type"
@click="searchBtnHandle(btn)"
>{{state.searchBtnOptions[btn].label}}</el-button>
</div>
</el-form-item>
</el-form>
<!-- 右侧按钮(保存页面) -->
<div>
<el-button
v-for="(btn,btn_key) in state.searchRightBtn"
:key="btn_key"
:icon="btn.icon"
v-auth="btn.sAuth || props.apiName + btn.auth"
:type="btn.type"
@click="searchRightBtnHandle(btn)"
style="margin-right: 10px"
>{{btn.label}}</el-button>
<!-- 字段设置 -->
<setColumsPop
style="margin-left: auto;"
:localTableColumnsName="state.localTableColumnsName"
:initTableColums="state.initTableColums"
:tableColumns="getTableColumns()"
v-if="!props.hideSetColums"
></setColumsPop>
</div>
</el-card>
<!-- 头部详情 -->
<el-card v-loading="state.detailLoading" class="headerInfo-container" v-if="!props.hideHeaderInfo">
<el-descriptions label-width="120" :title="`当前页【第${getIndexById()}行】数据信息`" :border="true" :column="5" v-if="state.headerInfoData && state.headerInfoData.length > 0">
<el-descriptions-item
v-for="(item,index) in state.headerInfoData"
:key="index"
:label="item.label">
{{item.value}}
</el-descriptions-item>
</el-descriptions>
<el-empty v-else description="暂无数据" class="headerInfoEmpty"/>
</el-card>
<!-- 列表 -->
<el-card class="paged-table-container">
<elTable
ref="table_Ref"
:columnWidth="props.columnWidth"
:columnHeaderAlign="props.columnHeaderAlign"
:columnAlign="props.columnAlign"
:tableData="state.tableData"
:tableColumns="getTableColumns()"
@sortChange="sortChange"
:leftOperation="props.leftOperation"
@leftOperationHadel="leftOperationHadel"
:rightOperation="getRightOperation()"
@rightOperationHadel="rightOperationHadel"
:multipleTable="props.multipleTable"
@tableSelectionHandle="tableSelectionHandle"
@editItemFocusHandle="(item,scope,event)=>{getItemDetail(item.type,scope.row,'focus')}"
@editItemChangeHandle="editItemChangeHandle"
@cell-click="(row,column,cell,event)=>{getItemDetail('cell',row,'cellClick')}"
@editItemClearHandle="(item,scope)=>{getItemDetail(item.type,scope.row,'clear')}"
:getEditItemDisabled="getEditItemDisabled"
:selectableDisabled="selectableDisabled"
:tableRowClassName="tableRowClassName"
:showTableIndex="props.showTableIndex"
></elTable>
<!-- :tableFormRules="state.tableFormRulesData" -->
<elPager
v-loading="state.pageLoading"
style="margin-top: 15px;float:right"
:pager="state.pager"
@size-change="pageSizeChange"
@current-change="pageCurrentChange"
></elPager>
</el-card>
<!-- 导入弹窗 -->
<importPop
ref="importPopRef"
:apiName="props.apiName"
@success="importSuccess"
/>
<!-- 编辑弹窗 -->
<apiEditPop
ref="apiEditPopRef"
:apiName="props.apiName"
@submitEditForm="submitEditForm"
:formRules="props.apiEditFormRules"
/>
</div>
</template>
<script setup>
defineOptions({ name: 'ediTtablePage' })
import store from '@/stores'
import apiTableColumns from '@/utils/common/apiTableColumns'
import { reactive, ref, onMounted,computed } from 'vue'
import {
getCommonPaged,
getCommonDeatailPaged,
postCommonExport,
postCommonCreate,
putCommonUpdate,
deleteCommonApi,
getCommonCustominvoke,
getCommonDetailById,
postCommonConfirmMany,
postCommonUpdateMany
} from '@/api/common/index'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import elTable from '@/components/elTable/index.vue'
import elPager from '@/components/elPager/index.vue'
import setColumsPop from '@/components/setColumsPop/index.vue'
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index'
import { downloadByData } from '@/utils/download'
import importPop from '@/components/importPop/index.vue'
import apiEditPop from '@/components/apiEditPop/index.vue'
import { formatDate } from '@/utils/formatTime'
import apiServeNames from '@/utils/common/apiServeNames'
import { useRoute } from 'vue-router'
const route = useRoute()
const userStore = store.userStore()
const userInfo = userStore.state
const auths = store.permissionStore()
const state = reactive({
loading:false,
detailLoading:false,
pageLoading:false,
searchBtnOptions:{
search:{icon:'Search',auth:':page',label:'查询',type:null},
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'},
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'},
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'},
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'},
outputMany:{icon:'Position',auth:':outputMany',label:'手动传出',type:'primary'},
},
searchRightBtn:[{name:'pageSave',icon:'Check',auth:':pageSave',label:'保存页面',type:'warning'}],
tableData:[],
// table
sortFilter:{
sortBy:undefined,
isAscending:undefined
},
pager:{
page: 1,
pageSize: 10,
total: 1,
},
tableSelectList:[],
leaveSaveTip:'此操作将重新渲染页面,检测有数据【未保存】,操作后将【清空未保存数据】,是否确定继续?',
//
headerInfoData:[],
currentDetailId:null,//id
//
stage_tableData:[],
//
stage_indexs:[],
//
initTableColums:[],
localTableColumnsName:null,
//tabel
tableFormRulesData:null,
})
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
// colum
detailColumName:{
type: String,
default: null
},
// api detailApigetdetailpageApigetdatapaged
apiType: {
type: String,
default: null
},
//
hideSearch:{
type: Boolean,
default: false
},
//
multipleTable:{
type: Boolean,
default: false
},
//
showTableIndex:{
type: Boolean,
default: true
},
//
leftOperation:{
type: Object,
default: null
},
//
rightOperation:{
type: [Object,String],
default: null
},
// api
showApiRightOperation:{
type: Object,
default: null
},
// readState=true
// 使,=
apiRightHideConfig:{
type: Object,
default: {
apiUpdate:{prop:'readState',ruleValue:true},
apiDelete:{prop:'readState',ruleValue:true},
}
},
// table
tableColumns: {
type: Object,
default: null
},
//
searchOptions: {
type: Object,
default: []
},
//
searchButtons: {
type: Object,
default: ['search','export']
},
// tablefilter
searchFilter: {
type: Object,
default: {}
},
//
columnWidth:{
type: Number,
default: 120
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
apiEditFormRules:{
type: Object,
default: null
},
// table
tableFormRules:{
type: Object,
default: null
},
//
hideHeaderInfo:{
type: Boolean,
default: false
},
// /readState=true
// 使,=
editDisabledConfig:{
type: Object,
default: [
{prop:'readState',ruleValue:true},
// {prop:'releaseEdition',ruleValue:'2024121901'},
]
},
//
hideSetColums:{
type: Boolean,
default: false
}
})
// noFilter
function getTableColumns(noFilter){
if(noFilter){
return props.tableColumns || apiTableColumns[props.apiName]
}else{
state.localTableColumnsName = getLocalTableColumnsName(useRoute().name)
if(props.apiType == 'detailApi'){
state.localTableColumnsName = getLocalTableColumnsName(props.apiName+'Detail')
}
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName))
state.initTableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _local && _local != null && _local != undefined ? _local : JSON.parse(JSON.stringify(state.initTableColums))
return _list
}
// return props.tableColumns || apiTableColumns[props.apiName]
}
const emits = defineEmits([
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle'
])
// table
function tableSelectionHandle (val){
state.tableSelectList = val
emits('tableSelectionHandle',val)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getRightOperation() {
// api
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){
return props.rightOperation
}
// api
else if(
(typeof props.rightOperation == 'object' && props.showApiRightOperation)
|| typeof props.rightOperation == 'string'
){
// api
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',')
let _config = {
apiUpdate:{label:'编辑',type:'warning'},
apiDelete:{label:'删除',type:'danger'},
}
let _btns = []
if(_apiArr && _apiArr.length > 0){
_apiArr.forEach(item => {
_btns.push({
label:_config[item].label,
name:item,
link:true,
type:_config[item].type,
auth:props.apiName+':'+item,
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue}
})
});
}
// api
if(typeof props.rightOperation == 'object'){
_btns = [..._btns,...props.rightOperation]
}
return _btns
}
}
//
const apiEditPopRef = ref()
function rightOperationHadel(btn,scope) {
//
if(btn.name == 'apiUpdate'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list,scope.row)
}
//
if(btn.name == 'apiDelete'){
ElMessageBox.confirm(`是否确定删除?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
deleteCommonApi(props.apiName,scope.row.uId)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{state.loading = false})
})
}
emits('rightOperationHadel',btn,scope)
}
//
const submitEditForm = async (type,formData,formConfig) => {
apiEditPopRef.value.validate((valid) => {
if(valid){
//
if(type == 'create'){
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName}
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName}
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
apiEditPopRef.value.changeLoading(true)
postCommonCreate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}else{
//
if(
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime'))
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime'))
){
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName}
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName}
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
}else{
//
let _notChange=['taskconifgure']
if(_notChange.indexOf(props.apiName) < 0){
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}`
}
}
apiEditPopRef.value.changeLoading(true)
putCommonUpdate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}
}
})
}
//
function getPageParams(pageSize){
let _filters = []
if(props.hideSearch){
_filters = props.searchFilter
}else{
for(let i in props.searchFilter){
let _item = props.searchOptions.filter(item=>item.prop == i)
let _type = (_item && _item.length > 0) ? _item[0].type : null
if((props.searchFilter[i] || props.searchFilter[i] == 0) && props.searchFilter[i] != ""){
//
if(_type == 'datetimerange'){
_filters.push(
{
logic: "And",
column: i,
action: '>=',
value: props.searchFilter[i][0]
}
)
_filters.push(
{
logic: "And",
column: i,
action: '<=',
value: props.searchFilter[i][1]
}
)
}else{
let _action = 'like'
let _EqualTypes = ['tagFilter','filter','number','select']//
if(_EqualTypes.indexOf(_type) >= 0){
_action = '=='
}
_filters.push(
{
logic: "And",
column: i,
action: _action,
value: props.searchFilter[i]
}
)
}
}
}
}
let _pageParams = getPageParamsForFilter({
pageNumber:state.pager.page,
pageSize:pageSize || state.pager.pageSize,
sortBy:state.sortFilter.sortBy,
isAscending:state.sortFilter.isAscending,
condition:{
filters:_filters
}
})
return _pageParams
}
//
function getTableData(page,callback) {
state.stage_indexs = []
state.currentDetailId = null
state.headerInfoData = []
state.tableSelectList = []
if(props.apiType == 'detailApi'){
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
getCommonDeatailPaged(props.apiName,getPageParams())
.then((resp) => {
state.headerInfoData = []
state.tableData = resp.data.data
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data))
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}else{
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
getCommonPaged(props.apiName,getPageParams())
.then((resp) => {
state.headerInfoData = []
state.tableData = resp.data.data
state.stage_tableData = JSON.parse(JSON.stringify(resp.data.data))
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
}
//
function exportHandle(isAll){
state.loading = true
//
getTableData(1,(res=>{
let _params = getPageParams()
if(isAll){_params = getPageParams(res.data.totalCount)}
postCommonExport(props.apiName,_params)
.then((res) => {
let _str = isAll ? '全部' : '当页'
downloadByData(res.data,route.meta.title+`.xlsx`)
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(() => (state.loading = false))
}))
}
const importPopRef = ref()
//
function searchBtnHandle(btn){
//
if(btn == 'search'){
beforClearEdit().then(() => {
getTableData()
})
}
//
else if (btn == 'create'){
beforClearEdit().then(() => {
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list)
})
}
//
else if (btn == 'import'){
beforClearEdit().then(() => {
importPopRef.value.open()
})
}
//
else if (btn == 'export'){
exportHandle()
}
//
else if (btn == 'custominvoke'){
beforClearEdit().then(() => {
state.loading = true
let _data = {
taskName:apiServeNames[props.apiName].taskName,
client:'Chery'
}
getCommonCustominvoke(_data)
.then((res) => {
ElMessage.success('操作成功!')
getTableData(1)//
})
.finally(() => (state.loading = false))
})
}
//
else if (btn == 'outputMany'){
let _idEditData = checkPageEditList()
if(_idEditData && _idEditData.length > 0){
return ElMessage.warning('当前有未保存修改项,请先保存页面')
}
if(!state.tableSelectList || state.tableSelectList.length <= 0 ){
return ElMessage.warning('未选中任何数据')
}
ElMessageBox.confirm('是否确定手动传出?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
postCommonConfirmMany(props.apiName,state.tableSelectList)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1)
})
.finally(()=>{state.loading = false})
})
}
}
const table_Ref = ref(null)
//
function searchRightBtnHandle(btn){
//
if(btn.name == 'pageSave'){
// table_Ref.value.tableForm_Ref.validate((valid)=>{
// if(valid){
let _idEditData = checkPageEditList()
if(!_idEditData || _idEditData.length <= 0)return ElMessage.warning('暂无数据修改')
//
// [feedbackResults]=1[ventureType],[ventureSpecific],[measures]
let _indexs = []
_idEditData.forEach(item=>{
if(item.feedbackResults == '1' && (
!item.ventureType || item.ventureType == '' ||
!item.ventureSpecific || item.ventureSpecific == '' ||
!item.measures || item.measures == ''
)){
_indexs.push(getIndexById(item.id))
}
})
if(_indexs && _indexs.length > 0){
return ElMessage.error(`修改数据中【第${_indexs}行】数据中,【反馈结果】为异常,但【风险类型】或【具体风险】或【应对措施】为空,请修改后重新提交!`)
}
ElMessageBox.confirm('是否确定提交更改?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
postCommonUpdateMany(props.apiName,_idEditData)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1)
})
.finally(()=>{state.loading = false})
})
// }
// })
}
}
//
function sortChange(data) {
beforClearEdit().then(() => {
const { prop, order } = data;
if (!prop || !order) {
state.sortFilter.sortBy = undefined;
state.sortFilter.isAscending = undefined;
getTableData(1);
return;
}
state.sortFilter.sortBy = prop;
state.sortFilter.isAscending = (order == "ascending");
getTableData(1);
})
}
//
function importSuccess(response,importDate){
getTableData()
}
// size-change
function pageSizeChange(pageSize,returnSize){
state.pageLoading=true
let _oldSize = state.pager.pageSize
state.pager.pageSize = pageSize
beforClearEdit()
.then(res => {
getTableData(1)
state.pageLoading=false
})
.catch(res=>{
state.pager.pageSize = _oldSize
state.pageLoading=false
})
}
// current-change
function pageCurrentChange(page){
beforClearEdit().then(res => {
getTableData(page)
})
}
//
function getIndexById(id){
let _id = id || state.currentDetailId
for(let i=0;i<state.stage_tableData.length;i++){
if(state.stage_tableData[i].id == _id){
return i + 1
}
}
}
//
function checkDisableByRowRule(row,item){
let hasDisable = false
// editDisabledConfig
for(let i = 0;i<props.editDisabledConfig.length;i++){
if(row[props.editDisabledConfig[i].prop] == props.editDisabledConfig[i].ruleValue){
hasDisable = true
break
}
}
//
//
//
if(!hasDisable && row.feedbackResults == '0' && item.prop != 'feedbackResults'){
hasDisable = true
}
return hasDisable
}
//
function checkDisableCheckByRowRule(row){
// editDisabledConfig
let hasDisable = false
// editDisabledConfig
for(let i = 0;i<props.editDisabledConfig.length;i++){
if(row[props.editDisabledConfig[i].prop] == props.editDisabledConfig[i].ruleValue){
hasDisable = true
break
}
}
return hasDisable
}
//
function getEditItemDisabled(item,row,index){
//
let _auth = auths.hasPermission(props.apiName+':pageSave')
if(item.disabled || !_auth){
return true
}
//
if(state.tableSelectList && state.tableSelectList.length > 0){
return true
}
//
return checkDisableByRowRule(row,item)
}
// table
function selectableDisabled(row,index){
//
let _auth = auths.hasPermission(props.apiName+':outputMany')
//
let _idEditData = checkPageEditList()
//
let checkRow = checkDisableCheckByRowRule(row)
return _auth && (!_idEditData || _idEditData.length <= 0) && !checkRow
}
// Focus todo:
function getItemDetail(type,row,eventType) {
if(!row.id){return ElMessage.error('该数据无id')}
// id
if(row.id == state.currentDetailId){return}
let _focuseExt = ['input','numberInput']
// focus_focuseExtcell
if(eventType == 'focus' && _focuseExt.indexOf(type) >= 0){return}
console.log(type,row,eventType)
console.log('------------')
state.currentDetailId = row.id
state.detailLoading = true
getCommonDetailById(props.apiName,row.id)
.then((res) => {
state.headerInfoData = []
let _colums = apiTableColumns[props.detailColumName]
_colums.forEach(item=>{
state.headerInfoData.push({
label:item.title,
value:res.data[item.prop],
prop:item.prop
})
})
})
.finally(() => (state.detailLoading = false))
}
// change
function editItemChangeHandle(item,scope,data) {
if(state.stage_indexs.indexOf(scope.$index) < 0){
state.stage_indexs.push(scope.$index)
}
//
//
if(item.prop == "feedbackResults"){
//
if(scope.row.feedbackResults == '0'){
//
scope.row.ventureType = ""
scope.row.ventureSpecific = ""
scope.row.measures = ""
// ()
// prop
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
for(let prop in scope.row){
let _item = _tableColums.filter(item=>item.prop == prop)
if(_item && _item.length > 0 && _item[0].relevProp){
let _relevProp = _item[0].relevProp
let _list = state.headerInfoData.filter(item=>item.prop == _relevProp)
if(_list && _list.length>0){
scope.row[prop] = _list[0].value
}
}
}
}
}
}
//
function beforClearEdit(){
return new Promise((resolve, reject) => {
let _idEditData = checkPageEditList()
if(!_idEditData || _idEditData.length <= 0){
resolve()
}else{
ElMessageBox.confirm(state.leaveSaveTip, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
resolve()
}).catch(()=>{
reject()
})
}
})
}
//
function checkPageEditList(){
if(!state.stage_indexs || state.stage_indexs.length<=0){
return false
}
else{
let _changeArr = []
state.stage_indexs.forEach(item=>{
if(JSON.stringify(state.stage_tableData[item]) != JSON.stringify(state.tableData[item])){
_changeArr.push(state.tableData[item])
}
})
return _changeArr
}
}
//
function tableRowClassName(data){
if(data.row.id && (data.row.id == state.currentDetailId)){return 'current-select-tableRow'}
else{return 'normal-tableRow'}
}
// apiTableColumnstable
function getTableFormRules(){
if(props.tableFormRules) {
state.tableFormRulesData = props.tableFormRules
}else{
state.tableFormRulesData = {}
apiTableColumns[props.apiName].forEach(item=>{
if(item.required){
state.tableFormRulesData[item.prop] = [{ required: true, message: '必填项', trigger: 'change' }]
}
})
}
}
onMounted(() => {
// getTableFormRules()
getTableData()
})
</script>
<style scoped lang="scss">
::v-deep .search-container{
.el-card__body{
width: 100%;
display: flex;
justify-content: space-between;
}
}
::v-deep .headerInfo-container{
margin-top:10px;
.el-card__body{
padding-bottom: 10px !important;
min-height:66px
}
}
::v-deep .headerInfoEmpty{
height:195px;
.el-empty__image{
width:90px !important
}
}
::v-deep .el-descriptions__body{
max-height: 165px;
overflow: auto;
}
</style>

65
Web/src/components/elPager/index.vue

@ -0,0 +1,65 @@
<template>
<el-pagination
:currentPage="props.pager.page"
:page-size="props.pager.pageSize"
:total="props.pager.total"
:background="props.pageBackGround"
:layout="props.pageLayout"
:hide-on-single-page="props.isHideOnlyOne"
:page-sizes="props.pageSizeList"
@size-change="pageSizeChange"
@current-change="pageCurrentChange"
/>
</template>
<script setup>
defineOptions({ name: 'elPager' })
import { reactive, ref, onMounted,watch } from 'vue'
import { ElMessageBox, ElMessage,ElPagination } from 'element-plus'
const props = defineProps({
// table
pager: {
type: Object,
default: {}
},
//
pageLayout: {
type: String,
default: 'total, sizes,prev, pager, next'
},
//
isHideOnlyOne:{
type:Boolean,
default: false
},
//
pageBackGround:{
type:Boolean,
default: true
},
//
pageSizeList:{
type: Object,
default: [10, 20, 50, 100]
},
})
const emits = defineEmits(['pageSizeChange', 'pageCurrentChange'])
// size-change
function pageSizeChange(pageSize){
emits('pageSizeChange',pageSize)
}
// current-change
function pageCurrentChange(page){
emits('pageCurrentChange',page)
}
onMounted(() => {})
</script>
<style></style>

368
Web/src/components/elTable/index.vue

@ -0,0 +1,368 @@
<template>
<el-table
ref="table_Ref"
row-key="id"
:data="props.tableData"
:border="true"
@sort-change="sortChange"
@selection-change="tableSelectionHandle"
:row-class-name="props.tableRowClassName"
:cell-class-name="props.tableCellClassName"
>
<!-- 多选框 -->
<el-table-column
v-if="props.multipleTable"
type="selection"
:fixed="'left'"
width="55"
:selectable="selectableDisabled"
/>
<!-- 序号 -->
<el-table-column v-if="props.showTableIndex" :fixed="'left'" type="index" width="50" />
<!-- 左侧操作列 -->
<el-table-column
v-if="props.leftOperation && props.leftOperation.length > 0"
:fixed="'left'"
:width="props.leftOperationColumnWidth"
label="操作"
:align="'center'">
<template #default="scope">
<el-button
v-for="(btn,index) in props.leftOperation"
:key="index"
:type="btn.type"
:link="btn.link"
@click="leftOperationHadel(btn,scope)"
:disabled="typeof btn.disabled == 'function' ? btn.disabled(scope.row,scope) : btn.disabled"
v-show="typeof btn.hide == 'function' ? !btn.hide(scope.row,scope) : !btn.hide"
>{{btn.label}}</el-button>
</template>
</el-table-column>
<template v-for="(item, index) in innerTableColums" :key="index">
<!-- 数据列 -->
<el-table-column
v-if="!item.setNoShow"
:label="item.title"
:prop="item.prop"
:sortable="item.sortable || 'custom'"
:fixed="item.fixed"
:width="item.width || props.columnWidth"
:align="item.align || props.columnAlign"
:show-overflow-tooltip="item.tooltip"
:header-align="item.headerAlign || props.columnHeaderAlign">
<template #default="scope">
<!-- 时间格式 -->
<span v-if="item.type == 'datetime'"> {{ formatTableDate(scope.row[item.prop]) }} </span>
<!-- 标签格式 -->
<el-tag
v-else-if="item.type == 'tagFilter'"
:type="formatTableTagFilter('type',scope.row,item)"
>
{{ formatTableTagFilter('label',scope.row,item) }}
</el-tag>
<!-- 字典 -->
<span v-else-if="item.type == 'filter'">{{ formatTableTagFilter('label',scope.row,item) }}</span>
<!-- 可编辑文本 -->
<el-input
v-else-if="item.type == 'input'"
v-model="scope.row[item.prop]"
:placeholder="item.label"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑字典选择 -->
<el-select
v-else-if="item.type == 'filterSelect'"
v-model="scope.row[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)">
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
<!-- 可编辑时间 -->
<el-date-picker
v-else-if="item.type == 'datetimeInput'"
v-model="scope.row[item.prop]"
style="width:100%"
:type="item.inputType || 'datetime'"
:format="item.format || 'YYYY-MM-DD HH:mm:ss'"
:value-format="item.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
:clearable="!item.noClear"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑数字 -->
<el-input-number
v-else-if="item.type == 'numberInput'"
v-model="scope.row[item.prop]"
:min="item.min"
:max="item.max"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
/>
<!-- 正常直接显示 -->
<span v-else> {{ scope.row[item.prop] }} </span>
</template>
</el-table-column>
</template>
<!-- 右侧操作列 -->
<el-table-column
v-if="props.rightOperation && props.rightOperation.length > 0"
v-auth-any="getShowRightOpera()"
:fixed="'right'"
:width="props.rightOperationColumnWidth"
:align="'center'"
label="操作">
<template #default="scope">
<el-button
v-for="(btn,index) in props.rightOperation"
v-show="typeof btn.hide == 'function' ? !btn.hide(scope.row,scope) : !btn.hide"
:key="index"
:type="btn.type"
:link="btn.link"
@click="rightOperationHadel(btn,scope)"
v-auth="btn.auth"
>{{btn.label}}</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
defineOptions({ name: 'elTable' })
import { useRoute } from 'vue-router'
import { h,reactive, ref, onMounted,defineExpose,nextTick } from 'vue'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import { formatTimeStrToStr } from "@/utils/formatTime";
import { getLocalTableColumnsName } from '@/utils/common/index'
const props = defineProps({
// column
specialLocalColumnName:{
type: String,
default: null
},
//
multipleTable:{
type: Boolean,
default: false
},
//
showTableIndex:{
type: Boolean,
default: false
},
//
leftOperation:{
type: Object,
default: null
},
//
leftOperationColumnWidth:{
type: Number,
default: 120
},
//
rightOperation:{
type: Object,
default: null
},
//
rightOperationColumnWidth:{
type: Number,
default: 150
},
// table
tableData: {
type: Object,
default: []
},
// table
tableColumns: {
type: Object,
default: []
},
//
columnWidth:{
type: Number,
default: null
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
getEditItemDisabled:{
type: [Function,Boolean],
default: false
},
// table
selectableDisabled:{
type: [Function,Boolean],
default: true
},
// class
tableRowClassName:{
type: Function,
default: null
},
// class
tableCellClassName:{
type: Function,
default: null
},
})
const innerTableColums = ref([])
innerTableColums.value = props.tableColumns
const emits = defineEmits([
'sortChange',
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle',
'editItemFocusHandle',
'editItemChangeHandle',
'editItemClearHandle',
])
const table_Ref = ref(null)
let _localColumName = props.specialLocalColumnName || useRoute().name
const localTableColumnsName = getLocalTableColumnsName(_localColumName)
window.addEventListener('setItemEvent', (data) => {
// console.log("localStorage.setItem",data)
nextTick(() => {
if(data.key == localTableColumnsName){
innerTableColums.value = JSON.parse(data.newValue)
if(table_Ref.value)table_Ref.value.doLayout()
}
})
})
//
function tableSelectionHandle (val){
emits('tableSelectionHandle',val)
}
//
function formatTableDate(time) {
let _time = '-'
if (time) { _time = formatTimeStrToStr(time) }
return _time
}
// TagFilter
function formatTableTagFilter(type,row,item){
let _op = item.options.filter(op=>op.value == row[item.prop])
if(!_op || _op.length <=0 || !_op[0][type]){
if(type=='type'){return 'info'}
else{return '--'}
}else{
return _op[0][type]
}
}
//
function sortChange(data) {
emits('sortChange',data)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getShowRightOpera(){
let _arr = []
props.rightOperation.forEach(item=>{_arr.push(item.auth)})
return _arr
}
//
function getEditItemDisabled(item,row,scope){
if(typeof props.getEditItemDisabled == 'boolean'){
return props.getEditItemDisabled
}else{
return props.getEditItemDisabled(item,row,scope.$index)
}
}
// table
function selectableDisabled(row,index){
if(typeof props.selectableDisabled == 'function'){
return props.selectableDisabled(row,index)
}else{
return props.selectableDisabled
}
}
// Focus
function editItemFocusHandle(item,scope,event) {
emits('editItemFocusHandle',item,scope,event)
}
// change
function editItemChangeHandle(item,scope,data) {
emits('editItemChangeHandle',item,scope,data)
}
// clear
function editItemClearHandle(item,scope) {
emits('editItemClearHandle',item,scope)
}
//
function rightOperationHadel(btn,scope) {
emits('rightOperationHadel',btn,scope)
}
defineExpose({
table_Ref,
})
onMounted(() => {})
</script>
<style scope lang="scss">
.current-select-tableRow{
background:#e1f3d8 !important;
td{
background:#e1f3d8 !important;
}
}
.normal-tableRow{
td{
background:#fff;
}
}
.table-danger-row{
background:#ffe8e8 !important;
}
</style>

336
Web/src/components/elTable/index_norule.vue

@ -0,0 +1,336 @@
<template>
<el-table
ref="tableRef"
row-key="id"
:data="props.tableData"
:border="true"
@sort-change="sortChange"
@selection-change="tableSelectionHandle"
:row-class-name="props.tableRowClassName"
:cell-class-name="props.tableCellClassName"
>
<!-- 多选框 -->
<el-table-column
v-if="props.multipleTable"
type="selection"
:fixed="'left'"
width="55"
:selectable="selectableDisabled"
/>
<!-- 序号 -->
<el-table-column v-if="props.showTableIndex" :fixed="'left'" type="index" width="50" />
<!-- 左侧操作列 -->
<el-table-column
v-if="props.leftOperation && props.leftOperation.length > 0"
:fixed="'left'"
:width="props.leftOperationColumnWidth"
label="操作"
:align="'center'">
<template #default="scope">
<el-button
v-for="(btn,index) in props.leftOperation"
:key="index"
:type="btn.type"
:link="btn.link"
@click="leftOperationHadel(btn,scope)"
>{{btn.label}}</el-button>
</template>
</el-table-column>
<!-- 数据列 -->
<el-table-column
v-for="(item, index) in props.tableColumns"
:key="index"
:label="item.title"
:prop="item.prop"
:sortable="item.sortable || 'custom'"
:fixed="item.fixed"
:width="item.width || props.columnWidth"
:align="item.align || props.columnAlign"
:header-align="item.headerAlign || props.columnHeaderAlign">
<template #default="scope">
<!-- 时间格式 -->
<span v-if="item.type == 'datetime'"> {{ formatTableDate(scope.row[item.prop]) }} </span>
<!-- 标签格式 -->
<el-tag
v-else-if="item.type == 'tagFilter'"
:type="formatTableTagFilter('type',scope.row,item)"
>
{{ formatTableTagFilter('label',scope.row,item) }}
</el-tag>
<!-- 字典 -->
<span v-else-if="item.type == 'filter'">{{ formatTableTagFilter('label',scope.row,item) }}</span>
<!-- 可编辑文本 -->
<el-input
v-else-if="item.type == 'input'"
v-model="scope.row[item.prop]"
:placeholder="item.label"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑字典选择 -->
<el-select
v-else-if="item.type == 'filterSelect'"
v-model="scope.row[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)">
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
<!-- 可编辑时间 -->
<el-date-picker
v-else-if="item.type == 'datetimeInput'"
v-model="scope.row[item.prop]"
style="width:100%"
:type="item.inputType || 'datetime'"
:format="item.format || 'YYYY-MM-DD HH:mm:ss'"
:value-format="item.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
:clearable="!item.noClear"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑数字 -->
<el-input-number
v-else-if="item.type == 'numberInput'"
v-model="scope.row[item.prop]"
:min="item.min"
:max="item.max"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
/>
<!-- 正常直接显示 -->
<span v-else> {{ scope.row[item.prop] }} </span>
</template>
</el-table-column>
<!-- 右侧操作列 -->
<el-table-column
v-if="props.rightOperation && props.rightOperation.length > 0"
v-auth-any="getShowRightOpera()"
:fixed="'right'"
:width="props.rightOperationColumnWidth"
:align="'center'"
label="操作">
<template #default="scope">
<el-button
v-for="(btn,index) in props.rightOperation"
v-show="typeof btn.hide == 'function' ? !btn.hide(scope.row,scope) : !btn.hide"
:key="index"
:type="btn.type"
:link="btn.link"
@click="rightOperationHadel(btn,scope)"
v-auth="btn.auth"
>{{btn.label}}</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
defineOptions({ name: 'elTable' })
import { reactive, ref, onMounted } from 'vue'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import { formatTimeStrToStr } from "@/utils/formatTime";
const state = reactive({})
const props = defineProps({
//
multipleTable:{
type: Boolean,
default: false
},
//
showTableIndex:{
type: Boolean,
default: false
},
//
leftOperation:{
type: Object,
default: null
},
//
leftOperationColumnWidth:{
type: Number,
default: 120
},
//
rightOperation:{
type: Object,
default: null
},
//
rightOperationColumnWidth:{
type: Number,
default: 150
},
// table
tableData: {
type: Object,
default: []
},
// table
tableColumns: {
type: Object,
default: []
},
//
columnWidth:{
type: Number,
default: null
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
getEditItemDisabled:{
type: [Function,Boolean],
default: false
},
// table
selectableDisabled:{
type: [Function,Boolean],
default: true
},
// class
tableRowClassName:{
type: Function,
default: null
},
// class
tableCellClassName:{
type: Function,
default: null
},
})
const emits = defineEmits([
'sortChange',
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle',
'editItemFocusHandle',
'editItemChangeHandle',
'editItemClearHandle',
])
//
function tableSelectionHandle (val){
emits('tableSelectionHandle',val)
}
//
function formatTableDate(time) {
let _time = '-'
if (time) { _time = formatTimeStrToStr(time) }
return _time
}
// TagFilter
function formatTableTagFilter(type,row,item){
let _op = item.options.filter(op=>op.value == row[item.prop])
if(!_op || _op.length <=0 || !_op[0][type]){
if(type=='type'){return 'info'}
else{return '--'}
}else{
return _op[0][type]
}
}
//
function sortChange(data) {
emits('sortChange',data)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getShowRightOpera(){
let _arr = []
props.rightOperation.forEach(item=>{_arr.push(item.auth)})
return _arr
}
//
function getEditItemDisabled(item,row,scope){
if(typeof props.getEditItemDisabled == 'boolean'){
return props.getEditItemDisabled
}else{
return props.getEditItemDisabled(item,row,scope.$index)
}
}
// table
function selectableDisabled(row,index){
if(typeof props.selectableDisabled == 'function'){
return props.selectableDisabled(row,index)
}else{
return props.selectableDisabled
}
}
// Focus
function editItemFocusHandle(item,scope,event) {
emits('editItemFocusHandle',item,scope,event)
}
// change
function editItemChangeHandle(item,scope,data) {
emits('editItemChangeHandle',item,scope,data)
}
// clear
function editItemClearHandle(item,scope) {
emits('editItemClearHandle',item,scope)
}
//
function rightOperationHadel(btn,scope) {
emits('rightOperationHadel',btn,scope)
}
onMounted(() => {})
</script>
<style scope lang="scss">
.current-select-tableRow{
background:#e1f3d8 !important;
td{
background:#e1f3d8 !important;
}
}
.normal-tableRow{
td{
background:#fff;
}
}
</style>

353
Web/src/components/elTable/index_rulr.vue

@ -0,0 +1,353 @@
<template>
<el-form style="height:calc(100% - 45px)" :model="props" :rules="props.tableFormRules" ref="tableForm_Ref">
<el-table
style="height:100%"
row-key="id"
:data="props.tableData"
:border="true"
@sort-change="sortChange"
@selection-change="tableSelectionHandle"
:row-class-name="props.tableRowClassName"
:cell-class-name="props.tableCellClassName"
>
<!-- 多选框 -->
<el-table-column
v-if="props.multipleTable"
type="selection"
:fixed="'left'"
width="55"
:selectable="selectableDisabled"
/>
<!-- 序号 -->
<el-table-column v-if="props.showTableIndex" :fixed="'left'" type="index" width="50" />
<!-- 左侧操作列 -->
<el-table-column
v-if="props.leftOperation && props.leftOperation.length > 0"
:fixed="'left'"
:width="props.leftOperationColumnWidth"
label="操作"
:align="'center'">
<template #default="scope">
<el-button
v-for="(btn,index) in props.leftOperation"
:key="index"
:type="btn.type"
:link="btn.link"
@click="leftOperationHadel(btn,scope)"
>{{btn.label}}</el-button>
</template>
</el-table-column>
<!-- 数据列 -->
<el-table-column
v-for="(item, index) in props.tableColumns"
:key="index"
:label="item.title"
:prop="item.prop"
:sortable="item.sortable || 'custom'"
:fixed="item.fixed"
:width="item.width || props.columnWidth"
:align="item.align || props.columnAlign"
:header-align="item.headerAlign || props.columnHeaderAlign">
<template #default="scope">
<!-- `tableData[${scope.$index}][${item.prop}]` -->
<el-form-item
:prop="'tableData.'+ scope.$index + '.' + item.prop"
:rules="props.tableFormRules[item.prop]"
>
<!-- 时间格式 -->
<span v-if="item.type == 'datetime'"> {{ formatTableDate(scope.row[item.prop]) }} </span>
<!-- 标签格式 -->
<el-tag
v-else-if="item.type == 'tagFilter'"
:type="formatTableTagFilter('type',scope.row,item)"
>
{{ formatTableTagFilter('label',scope.row,item) }}
</el-tag>
<!-- 字典 -->
<span v-else-if="item.type == 'filter'">{{ formatTableTagFilter('label',scope.row,item) }}</span>
<!-- 可编辑文本 -->
<el-input
v-else-if="item.type == 'input'"
v-model="scope.row[item.prop]"
:placeholder="item.label"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑字典选择 -->
<el-select
v-else-if="item.type == 'filterSelect'"
v-model="scope.row[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
:disabled="getEditItemDisabled(item,scope.row,scope)"
:clearable="!item.noClear"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)">
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
<!-- 可编辑时间 -->
<el-date-picker
v-else-if="item.type == 'datetimeInput'"
v-model="scope.row[item.prop]"
style="width:100%"
:type="item.inputType || 'datetime'"
:format="item.format || 'YYYY-MM-DD HH:mm:ss'"
:value-format="item.valueFormat || 'YYYY-MM-DD HH:mm:ss'"
:clearable="!item.noClear"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
@clear="editItemClearHandle(item,scope)"
/>
<!-- 可编辑数字 -->
<el-input-number
v-else-if="item.type == 'numberInput'"
v-model="scope.row[item.prop]"
:min="item.min"
:max="item.max"
:disabled="getEditItemDisabled(item,scope.row,scope)"
@focus="(event)=>{editItemFocusHandle(item,scope,event)}"
@change="editItemChangeHandle(item,scope,arguments)"
/>
<!-- 正常直接显示 -->
<span v-else> {{ scope.row[item.prop] }} </span>
</el-form-item>
</template>
</el-table-column>
<!-- 右侧操作列 -->
<el-table-column
v-if="props.rightOperation && props.rightOperation.length > 0"
v-auth-any="getShowRightOpera()"
:fixed="'right'"
:width="props.rightOperationColumnWidth"
:align="'center'"
label="操作">
<template #default="scope">
<el-button
v-for="(btn,index) in props.rightOperation"
v-show="typeof btn.hide == 'function' ? !btn.hide(scope.row,scope) : !btn.hide"
:key="index"
:type="btn.type"
:link="btn.link"
@click="rightOperationHadel(btn,scope)"
v-auth="btn.auth"
>{{btn.label}}</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
</template>
<script setup>
defineOptions({ name: 'elTable' })
import { reactive, ref, onMounted,defineExpose } from 'vue'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import { formatTimeStrToStr } from "@/utils/formatTime";
const state = reactive({})
const props = defineProps({
//
multipleTable:{
type: Boolean,
default: false
},
//
showTableIndex:{
type: Boolean,
default: false
},
//
leftOperation:{
type: Object,
default: null
},
//
leftOperationColumnWidth:{
type: Number,
default: 120
},
//
rightOperation:{
type: Object,
default: null
},
//
rightOperationColumnWidth:{
type: Number,
default: 150
},
// table
tableData: {
type: Object,
default: []
},
// table
tableColumns: {
type: Object,
default: []
},
//
columnWidth:{
type: Number,
default: null
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
// tablerules
tableFormRules: {
type: Object,
default: null
},
//
getEditItemDisabled:{
type: [Function,Boolean],
default: false
},
// table
selectableDisabled:{
type: [Function,Boolean],
default: true
},
// class
tableRowClassName:{
type: Function,
default: null
},
// class
tableCellClassName:{
type: Function,
default: null
},
})
const emits = defineEmits([
'sortChange',
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle',
'editItemFocusHandle',
'editItemChangeHandle',
'editItemClearHandle',
])
//
function tableSelectionHandle (val){
emits('tableSelectionHandle',val)
}
//
function formatTableDate(time) {
let _time = '-'
if (time) { _time = formatTimeStrToStr(time) }
return _time
}
// TagFilter
function formatTableTagFilter(type,row,item){
let _op = item.options.filter(op=>op.value == row[item.prop])
if(!_op || _op.length <=0 || !_op[0][type]){
if(type=='type'){return 'info'}
else{return '--'}
}else{
return _op[0][type]
}
}
//
function sortChange(data) {
emits('sortChange',data)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getShowRightOpera(){
let _arr = []
props.rightOperation.forEach(item=>{_arr.push(item.auth)})
return _arr
}
//
function getEditItemDisabled(item,row,scope){
if(typeof props.getEditItemDisabled == 'boolean'){
return props.getEditItemDisabled
}else{
return props.getEditItemDisabled(item,row,scope.$index)
}
}
// table
function selectableDisabled(row,index){
if(typeof props.selectableDisabled == 'function'){
return props.selectableDisabled(row,index)
}else{
return props.selectableDisabled
}
}
// Focus
function editItemFocusHandle(item,scope,event) {
emits('editItemFocusHandle',item,scope,event)
}
// change
function editItemChangeHandle(item,scope,data) {
emits('editItemChangeHandle',item,scope,data)
}
// clear
function editItemClearHandle(item,scope) {
emits('editItemClearHandle',item,scope)
}
//
function rightOperationHadel(btn,scope) {
emits('rightOperationHadel',btn,scope)
}
const tableForm_Ref = ref(null)
defineExpose({
tableForm_Ref,
});
onMounted(() => {})
</script>
<style scope lang="scss">
.current-select-tableRow{
background:#e1f3d8 !important;
td{
background:#e1f3d8 !important;
}
}
.normal-tableRow{
td{
background:#fff;
}
}
</style>

154
Web/src/components/importPop/index.vue

@ -0,0 +1,154 @@
<template>
<el-dialog
v-model="dialogVisible"
title="导入"
width="600"
:close-on-click-modal="false"
>
<el-upload
ref="uploadRef"
v-model:file-list="fileList"
:action="importUrl"
:auto-upload="false"
:disabled="formLoading"
:headers="uploadHeaders"
:limit="1"
:on-error="submitFormError"
:on-exceed="handleExceed"
:on-success="submitFormSuccess"
:accept="accept"
drag
style="width: 300px; margin: 0 auto"
v-loading="formLoading"
>
<el-icon color="#c0c4cc" :size="60"><UploadFilled /></el-icon>
<div class="el-upload__text">将文件拖到此处'<em>点击上传</em></div>
</el-upload>
<template #footer>
<div class="footerBtns">
<div>
<el-button type="success" plain @click="importTemplate">
<el-icon><Download /></el-icon>
</el-button>
</div>
<div>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button :disabled="formLoading" type="primary" @click="submitForm">确定</el-button>
</div>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
defineOptions({ name: 'importPop' })
import { reactive, ref, onMounted,defineExpose } from 'vue'
import { ElDialog,ElMessage } from 'element-plus'
import { downloadByData } from '@/utils/download'
import { getCommonImportTemplate } from '@/api/common/index'
import { useRoute } from 'vue-router'
const route = useRoute()
const dialogVisible = ref(false) //
const fileList = ref([]) //
const uploadRef = ref()
const formLoading = ref(false) //
const uploadHeaders = ref() // Header
// const importUrl = getBaseUrl() + import.meta.env.VITE_API_URL + (props.url || '/finance/common-excel-in/import')
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
//
accept: {
type: String,
required: false,
default: '.xlsx,.xls'
},
})
const mode = import.meta.env.MODE
let app_base_api = mode == 'production' ? systemConfig.baseUrl : import.meta.env.VITE_API_BASE_URL
const importUrl = `${app_base_api}/api/${props.apiName}/import`
console.log('importUrl',importUrl)
/** 重置表单 */
const resetForm = () => {
//
formLoading.value = false
uploadRef.value?.clearFiles()
fileList.value = []
}
/** 打开弹窗 */
const open = () => {
dialogVisible.value = true
resetForm()
}
defineExpose({ open }) // open
/** 上传错误提示 */
const submitFormError = (): void => {
ElMessage.error('上传失败,请您重新上传!')
formLoading.value = false
}
/** 文件数超出提示 */
const handleExceed = (): void => {
ElMessage.error('最多只能上传一个文件!')
}
/** 下载模板操作 */
const importTemplate = () => {
formLoading.value = true
getCommonImportTemplate(props.apiName)
.then(res=>{
downloadByData(res.data,route.meta.title+'_模板.xlsx')
})
.catch(err=>{ElMessage.error('获取失败,请重试!')})
.finally(() => (formLoading.value = false))
}
// /** */
const submitForm = async () => {
if (fileList.value.length == 0) {
ElMessage.error('请上传文件')
return
}
//
// uploadHeaders.value = {
// Authorization: 'Bearer ' + getAccessToken(),
// 'tenant-id': getTenantId()
// }
formLoading.value = true
uploadRef.value!.submit()
}
// /** */
const emits = defineEmits(['success'])
//
const submitFormSuccess = (response: any) => {
formLoading.value = false
if (response) {
if(response.code == '200' || response.code == '1'){
ElMessage.success('导入成功!')
}else{
ElMessage.error(response.message)
}
}
//
formLoading.value = false
emits('success')
dialogVisible.value = false
}
</script>
<style lang="scss" scoped>
.footerBtns{
display: flex;
padding: 20px;
justify-content: space-between;
}
</style>

216
Web/src/components/setColumsPop/index.vue

@ -0,0 +1,216 @@
<template>
<el-dropdown :hide-on-click="false">
<el-button :icon="'Setting'" plain :type="hasChange ? 'primary' : null">字段设置</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<el-checkbox
v-model="checkAll"
@change="handleCheckAllChange"
:indeterminate="isIndeterminate"
><span style="color:#333">全选</span></el-checkbox>
</el-dropdown-item>
<el-checkbox-group
class="columsList"
v-model="checkedItems"
>
<el-dropdown-item
v-for="(colum,index) in columsList"
:key="index"
:draggable="true"
@dragstart="dragstart(colum)"
@dragenter="dragenter(colum,$event)"
@dragend="dragend(colum,$event)"
@dragover="dragover($event)"
>
<el-checkbox @change="(data)=>{handleCheckedItemChange(data,colum)}" :label="colum.title" :value="colum.prop"></el-checkbox>
</el-dropdown-item>
</el-checkbox-group>
</el-dropdown-menu>
<el-button class="restBtn" @click="reset">重置</el-button>
</template>
</el-dropdown>
</template>
<script setup>
defineOptions({ name: 'setColumsPop' })
import { reactive, ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
const props = defineProps({
// table
tableColumns: {
type: Object,
default: null
},
//
initTableColums: {
type: Object,
default: null
},
localTableColumnsName: {
type: String,
default: null
},
})
const checkAll = ref(false)//
const isIndeterminate = ref(false)//
const checkedItems = ref([])
const columsList = ref([])
const hasChange = ref(false)//
//
const getHasChange = () => {
hasChange.value = false
let _noShow = columsList.value.filter(item=>item.setNoShow == true)
//
if(_noShow && _noShow.length > 0){
hasChange.value = true
}
//
else{
let _initIndex = []
props.initTableColums.forEach(item=>{_initIndex.push(item.prop)})
let _nowIndex = []
columsList.value.forEach(item=>{ _nowIndex.push(item.prop)})
hasChange.value = _initIndex.join(",") != _nowIndex.join(",")
}
}
//
const getLocalColumsList = () => {
//
columsList.value = props.tableColumns
checkedItems.value = []
//
columsList.value.forEach(item=>{ if(!item.setNoShow)checkedItems.value.push(item.prop) })
//
setCheckAllSta()
//
getHasChange()
}
//
const setCheckAllSta = () => {
checkAll.value = checkedItems.value.length === columsList.value.length
isIndeterminate.value = (checkedItems.value.length < columsList.value.length) && checkedItems.value.length != 0
}
// /
const handleCheckAllChange = (val) => {
//
if(val){
hasChange.value = false
checkedItems.value = []
columsList.value.forEach(item=>{
checkedItems.value.push(item.prop)
item.setNoShow = false
})
save()
}
//
else{
hasChange.value = true
checkedItems.value = []
columsList.value.forEach(item=>{ item.setNoShow = true})
save()
}
}
//
const handleCheckedItemChange = (isCheck,colum) => {
let _prop = colum.prop
checkedItems.value = []
columsList.value.forEach(item=>{
if(item.prop == _prop){item.setNoShow = !isCheck}
if(!item.setNoShow)checkedItems.value.push(item.prop)
})
setCheckAllSta()
getHasChange()
save()
}
//
const reset = () => {
hasChange.value = false
checkedItems.value = []
columsList.value = JSON.parse(JSON.stringify(props.initTableColums))
columsList.value.forEach(item=>{ checkedItems.value.push(item.prop) })
setCheckAllSta()
save()
}
//
const save = () => {
localStorage.setItem(props.localTableColumnsName,JSON.stringify(columsList.value))
//
getHasChange()
//
setCheckAllSta()
}
const dragOldData = ref(null)
const dragNewData = ref(null)
//
const dragstart = (value) => {
dragOldData.value = value
}
//
const dragenter = (value, e) => {
dragNewData.value = value
e.preventDefault()
}
const dragend = (value, e) => {
//
if (dragOldData.value !== dragNewData.value) {
let oldIndex = columsList.value.indexOf(dragOldData.value)
let newIndex = columsList.value.indexOf(dragNewData.value)
let newItems = [...columsList.value]
//
newItems.splice(oldIndex, 1)
//
newItems.splice(newIndex, 0, dragOldData.value)
columsList.value = [...newItems]
save()
}
}
const dragover = (e) => {
//
e.preventDefault()
}
onMounted(() => {
getLocalColumsList()
})
</script>
<style scoped lang="scss">
.columsList{
height:calc(100vh - 400px) !important;
overflow:auto !important;
padding:10 20px !important;
}
::v-deep .el-checkbox{
min-width:200px !important;
}
.restBtn{
width:calc(100% - 20px);
margin:10px;
text-align:center
}
::-webkit-scrollbar{
width:6px;
height:6px;
}
::-webkit-scrollbar-track{
border-radius: 10px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb {
border-radius:10px;
background-color:#ddd;
}
</style>

690
Web/src/components/tablePage/index.vue

@ -0,0 +1,690 @@
<template>
<div class="app-container" v-loading="state.loading">
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)">
<el-form :inline="true" v-if="!props.hideSearch">
<el-form-item
v-auth="(props.authName || props.apiName) + state.searchBtnOptions['search'].auth"
v-for="(item,index) in props.searchOptions"
:key="index"
:label="item.label">
<!-- 文本 -->
<el-input
v-if="item.type == 'input' && !item.hide"
v-model="props.searchFilter[item.prop]"
:placeholder="item.label"
:clearable="!item.noClear"
/>
<!-- 数字 -->
<el-input-number
v-if="item.type == 'number' && !item.hide"
v-model="props.searchFilter[item.prop]"
:min="item.min"
:max="item.max"
/>
<!-- 时间区域 -->
<el-date-picker
v-if="item.type == 'datetimerange' && !item.hide"
v-model="props.searchFilter[item.prop]"
type="datetimerange"
start-placeholder="起始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width:370px"
/>
<!-- 选择框 -->
<el-select
v-if="item.type == 'select' && !item.hide"
v-model="props.searchFilter[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
style="width: 240px"
:clearable="!item.noClear"
>
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<div style="margin-right:10px" v-for="(btn,btn_key) in props.searchButtons" :key="btn_key">
<!-- 导出 -->
<el-dropdown
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:hide-on-click="false"
v-if="state.searchBtnOptions[btn].auth == ':export'"
>
<el-button
:icon="state.searchBtnOptions[btn].icon"
:type="state.searchBtnOptions[btn].type">
{{state.searchBtnOptions[btn].label}}
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="exportHandle()">按条件导出当前页</el-dropdown-item>
<el-dropdown-item divided @click="exportHandle(true)">按条件导出全部</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 其他按钮 -->
<el-button
v-else
:icon="state.searchBtnOptions[btn].icon"
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:type="state.searchBtnOptions[btn].type"
@click="searchBtnHandle(btn)"
>{{state.searchBtnOptions[btn].label}}</el-button>
</div>
</el-form-item>
</el-form>
<!-- 字段设置 -->
<setColumsPop
style="margin-left: auto;"
v-if="!props.hideSetColums && state.innerTableColumns"
:localTableColumnsName="state.localTableColumnsName"
:initTableColums="state.initTableColums"
:tableColumns="state.innerTableColumns"
></setColumsPop>
</el-card>
<el-card class="paged-table-container">
<elTable
v-if="state.innerTableColumns"
:specialLocalColumnName="props.specialLocalColumnName"
:columnWidth="props.columnWidth"
:columnHeaderAlign="props.columnHeaderAlign"
:columnAlign="props.columnAlign"
:tableData="state.tableData"
:tableColumns="state.innerTableColumns"
@sortChange="sortChange"
:leftOperation="props.leftOperation"
@leftOperationHadel="leftOperationHadel"
:leftOperationColumnWidth="props.leftOperationColumnWidth"
:rightOperation="getRightOperation()"
@rightOperationHadel="rightOperationHadel"
:multipleTable="props.multipleTable"
@tableSelectionHandle="tableSelectionHandle"
:tableRowClassName="props.tableRowClassName"
:tableCellClassName="props.tableCellClassName"
></elTable>
<elPager
style="margin-top: 15px;float:right"
:pager="state.pager"
@pageSizeChange="pageSizeChange"
@pageCurrentChange="pageCurrentChange"
></elPager>
</el-card>
<!-- 导入弹窗 -->
<importPop
ref="importPopRef"
:apiName="props.apiName"
@success="importSuccess"
/>
<!-- 编辑弹窗 -->
<apiEditPop
ref="apiEditPopRef"
:apiName="props.apiName"
@submitEditForm="submitEditForm"
:formRules="props.apiEditFormRules"
/>
</div>
</template>
<script setup>
defineOptions({ name: 'tablePage' })
import store from '@/stores'
import apiTableColumns from '@/utils/common/apiTableColumns'
import { reactive, ref, onMounted,computed,defineExpose } from 'vue'
import {
getCommonPost,
getCommonPaged,
getCommonDeatailPaged,
postCommonExport,
postCommonCreate,
putCommonUpdate,
deleteCommonApi,
getCommonCustominvoke
} from '@/api/common/index'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import elTable from '@/components/elTable/index.vue'
import elPager from '@/components/elPager/index.vue'
import setColumsPop from '@/components/setColumsPop/index.vue'
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index'
import { downloadByData } from '@/utils/download'
import importPop from '@/components/importPop/index.vue'
import apiEditPop from '@/components/apiEditPop/index.vue'
import { formatDate } from '@/utils/formatTime'
import apiServeNames from '@/utils/common/apiServeNames'
import { useRoute } from 'vue-router'
const route = useRoute()
const userStore = store.userStore()
const userInfo = userStore.state
const state = reactive({
loading:false,
searchBtnOptions:{
search:{icon:'Search',auth:':page',label:'查询',type:null},
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'},
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'},
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'},
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'},
},
innerTableColumns:null,
tableData:[],
// table
sortFilter:{
sortBy:undefined,
isAscending:undefined
},
pager:{
page: 1,
pageSize: 10,
total: 1,
},
tableSelectList:[],
initTableColums:[],//
localTableColumnsName:null
})
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
// api
specialPageApi:{
type: String,
default: null
},
// columnapiName
specialColumnName:{
type: String,
default: null
},
// columnapiName
specialLocalColumnName:{
type: String,
default: null
},
// 使apiName
authName:{
type: String,
default: null
},
// api detailApigetdetailpageApigetdatapaged
apiType: {
type: String,
default: null
},
//
hideSearch:{
type: Boolean,
default: false
},
// class
tableRowClassName:{
type: Function,
default: null
},
// class
tableCellClassName:{
type: Function,
default: null
},
//
multipleTable:{
type: Boolean,
default: false
},
//
leftOperation:{
type: Object,
default: null
},
//
leftOperationColumnWidth:{
type: Number,
default: 120
},
//
rightOperation:{
type: [Object,String],
default: null
},
// api
showApiRightOperation:{
type: Object,
default: null
},
// writeState=true
// 使,=
apiRightHideConfig:{
type: Object,
default: {
apiUpdate:{prop:'writeState',ruleValue:true},
apiDelete:{prop:'writeState',ruleValue:true},
}
},
// table
tableColumns: {
type: Object,
default: null
},
//
searchOptions: {
type: Object,
default: []
},
//
searchButtons: {
type: Object,
default: ['search','export']
},
// tablefilter
searchFilter: {
type: Object,
default: {}
},
// tablefiltercolum
// infoSearchFilterOptions:{ TableName:{action:'=='}},
searchFilterOptions: {
type: Object,
default: {}
},
//
columnWidth:{
type: Number,
default: 120
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
apiEditFormRules:{
type: Object,
default: null
},
//
hideSetColums:{
type: Boolean,
default: false
}
})
// noFilter
function getTableColumns(noFilter){
if(noFilter){
return props.tableColumns || apiTableColumns[props.apiName]
}else{
// location
let _localColumName = props.specialLocalColumnName || useRoute().name
state.localTableColumnsName = getLocalTableColumnsName(_localColumName)
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName))
//
let _apiColums = props.specialColumnName || props.apiName
state.initTableColums = props.tableColumns || apiTableColumns[_apiColums]
let _list = (_local && _local != null && _local != undefined) ? _local : JSON.parse(JSON.stringify(state.initTableColums))
state.innerTableColumns = _list
return _list
}
}
const emits = defineEmits([
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle'
])
// table
function tableSelectionHandle (val){
state.tableSelectList = val
emits('tableSelectionHandle',val)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getRightOperation() {
// api
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){
return props.rightOperation
}
// api
else if(
(typeof props.rightOperation == 'object' && props.showApiRightOperation)
|| typeof props.rightOperation == 'string'
){
// api
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',')
let _config = {
apiUpdate:{label:'编辑',type:'warning'},
apiDelete:{label:'删除',type:'danger'},
}
let _btns = []
if(_apiArr && _apiArr.length > 0){
_apiArr.forEach(item => {
_btns.push({
label:_config[item].label,
name:item,
link:true,
type:_config[item].type,
auth:(props.authName || props.apiName)+':'+item,
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue}
})
});
}
// api
if(typeof props.rightOperation == 'object'){
_btns = [..._btns,...props.rightOperation]
}
return _btns
}
}
//
const apiEditPopRef = ref()
function rightOperationHadel(btn,scope) {
//
if(btn.name == 'apiUpdate'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list,scope.row)
}
//
if(btn.name == 'apiDelete'){
ElMessageBox.confirm(`是否确定删除?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
deleteCommonApi(props.apiName,scope.row.uId)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1);
})
.finally(()=>{state.loading = false})
})
}
emits('rightOperationHadel',btn,scope)
}
//
const submitEditForm = async (type,formData,formConfig) => {
apiEditPopRef.value.validate((valid) => {
if(valid){
//
if(type == 'create'){
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName}
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName}
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
apiEditPopRef.value.changeLoading(true)
postCommonCreate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}else{
//
if(
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime'))
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime'))
){
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName}
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName}
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
}else{
//
let _notChange=['taskconifgure','customlog']
if(_notChange.indexOf(props.apiName) < 0){
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}`
}
}
apiEditPopRef.value.changeLoading(true)
putCommonUpdate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}
}
})
}
//
function getPageParams(pageSize){
let _filters = []
if(props.hideSearch){
_filters = props.searchFilter
}else{
function __getAction (prop,action){
if(props.searchFilterOptions && props.searchFilterOptions[prop] && props.searchFilterOptions[prop].action){
return props.searchFilterOptions[prop].action
}else{
return action
}
}
for(let i in props.searchFilter){
let _item = props.searchOptions.filter(item=>item.prop == i)
let _type = (_item && _item.length > 0) ? _item[0].type : null
if((props.searchFilter[i] || props.searchFilter[i] == 0) && props.searchFilter[i] != ""){
//
if(_type == 'datetimerange'){
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,'>='),
value: props.searchFilter[i][0]
}
)
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,'<='),
value: props.searchFilter[i][1]
}
)
}else{
let _action = 'like'
let _EqualTypes = ['tagFilter','filter','number','select']//
if(_EqualTypes.indexOf(_type) >= 0){
_action = '=='
}
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,_action),
value: props.searchFilter[i]
}
)
}
}
}
}
let _pageParams = getPageParamsForFilter({
pageNumber:state.pager.page,
pageSize:pageSize || state.pager.pageSize,
sortBy:state.sortFilter.sortBy,
isAscending:state.sortFilter.isAscending,
condition:{
filters:_filters
}
})
return _pageParams
}
//
function getTableData(page,callback) {
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
if(props.apiType == 'detailApi'){
getCommonDeatailPaged(props.apiName,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}else if(props.specialPageApi){
getCommonPost(props.specialPageApi,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
else{
getCommonPaged(props.apiName,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
}
//
function exportHandle(isAll){
state.loading = true
//
getTableData(1,(res=>{
let _params = getPageParams()
if(isAll){_params = getPageParams(res.data.totalCount)}
postCommonExport(props.apiName,_params)
.then((res) => {
let _str = isAll ? '全部' : '当页'
downloadByData(res.data,route.meta.title+`_按条件导出${_str}.xlsx`)
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(() => (state.loading = false))
}))
}
const importPopRef = ref()
//
function searchBtnHandle(btn){
//
if(btn == 'search'){
getTableData(1)
}
//
else if (btn == 'create'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list)
}
//
else if (btn == 'import'){
importPopRef.value.open()
}
//
// else if (btn == 'export'){
// exportHandle()
// }
//
else if (btn == 'custominvoke'){
ElMessageBox.confirm('是否确定操作手动开关?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
let _data = {
taskName:apiServeNames[props.apiName].taskName,
client:'Chery'
}
getCommonCustominvoke(_data)
.then((res) => {
ElMessage.success('操作成功!')
getTableData(1)//
})
.finally(() => (state.loading = false))
})
}
}
//
function sortChange(data) {
const { prop, order } = data;
if (!prop || !order) {
state.sortFilter.sortBy = undefined;
state.sortFilter.isAscending = undefined;
getTableData(1);
return;
}
state.sortFilter.sortBy = prop;
state.sortFilter.isAscending = (order == "ascending");
getTableData(1);
}
// todo
function importSuccess(response,importDate){
getTableData()
}
// size-change
function pageSizeChange(pageSize){
state.pager.pageSize = pageSize
getTableData(1)
}
// current-change
function pageCurrentChange(page){
getTableData(page)
}
onMounted(() => {
getTableColumns()
getTableData()
})
defineExpose({
state,
getTableData
});
</script>
<style scoped lang="scss">
::v-deep .search-container {
.el-card__body{
display:flex;
justify-content: space-between;
}
}
</style>

689
Web/src/components/tablePage/index_oldExport.vue

@ -0,0 +1,689 @@
<template>
<div class="app-container" v-loading="state.loading">
<el-card class="search-container" v-if="!(props.hideSearch && props.hideSetColums)">
<el-form :inline="true" v-if="!props.hideSearch">
<el-form-item
v-auth="(props.authName || props.apiName) + state.searchBtnOptions['search'].auth"
v-for="(item,index) in props.searchOptions"
:key="index"
:label="item.label">
<!-- 文本 -->
<el-input
v-if="item.type == 'input' && !item.hide"
v-model="props.searchFilter[item.prop]"
:placeholder="item.label"
:clearable="!item.noClear"
/>
<!-- 数字 -->
<el-input-number
v-if="item.type == 'number' && !item.hide"
v-model="props.searchFilter[item.prop]"
:min="item.min"
:max="item.max"
/>
<!-- 时间区域 -->
<el-date-picker
v-if="item.type == 'datetimerange' && !item.hide"
v-model="props.searchFilter[item.prop]"
type="datetimerange"
start-placeholder="起始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width:370px"
/>
<!-- 选择框 -->
<el-select
v-if="item.type == 'select' && !item.hide"
v-model="props.searchFilter[item.prop]"
:filterable="!item.noSearch"
placeholder="请选择"
style="width: 240px"
:clearable="!item.noClear"
>
<el-option
v-for="(op,op_index) in item.options"
:key="op_index"
:label="op.label"
:value="op.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<div style="margin-right:10px" v-for="(btn,btn_key) in props.searchButtons" :key="btn_key">
<!-- 导出 -->
<!-- <el-dropdown
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:hide-on-click="false"
v-if="state.searchBtnOptions[btn].auth == ':export'"
>
<el-button
:icon="state.searchBtnOptions[btn].icon"
:type="state.searchBtnOptions[btn].type">
{{state.searchBtnOptions[btn].label}}
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="exportHandle()">按条件导出当前页</el-dropdown-item>
<el-dropdown-item divided @click="exportHandle(true)">按条件导出全部</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> -->
<!-- 其他按钮 -->
<el-button
:icon="state.searchBtnOptions[btn].icon"
v-auth="(props.authName || props.apiName) + state.searchBtnOptions[btn].auth"
:type="state.searchBtnOptions[btn].type"
@click="searchBtnHandle(btn)"
>{{state.searchBtnOptions[btn].label}}</el-button>
</div>
</el-form-item>
</el-form>
<!-- 字段设置 -->
<setColumsPop
style="margin-left: auto;"
v-if="!props.hideSetColums && state.innerTableColumns"
:localTableColumnsName="state.localTableColumnsName"
:initTableColums="state.initTableColums"
:tableColumns="state.innerTableColumns"
></setColumsPop>
</el-card>
<el-card class="paged-table-container">
<elTable
v-if="state.innerTableColumns"
:specialLocalColumnName="props.specialLocalColumnName"
:columnWidth="props.columnWidth"
:columnHeaderAlign="props.columnHeaderAlign"
:columnAlign="props.columnAlign"
:tableData="state.tableData"
:tableColumns="state.innerTableColumns"
@sortChange="sortChange"
:leftOperation="props.leftOperation"
@leftOperationHadel="leftOperationHadel"
:leftOperationColumnWidth="props.leftOperationColumnWidth"
:rightOperation="getRightOperation()"
@rightOperationHadel="rightOperationHadel"
:multipleTable="props.multipleTable"
@tableSelectionHandle="tableSelectionHandle"
:tableRowClassName="props.tableRowClassName"
:tableCellClassName="props.tableCellClassName"
></elTable>
<elPager
style="margin-top: 15px;float:right"
:pager="state.pager"
@pageSizeChange="pageSizeChange"
@pageCurrentChange="pageCurrentChange"
></elPager>
</el-card>
<!-- 导入弹窗 -->
<importPop
ref="importPopRef"
:apiName="props.apiName"
@success="importSuccess"
/>
<!-- 编辑弹窗 -->
<apiEditPop
ref="apiEditPopRef"
:apiName="props.apiName"
@submitEditForm="submitEditForm"
:formRules="props.apiEditFormRules"
/>
</div>
</template>
<script setup>
defineOptions({ name: 'tablePage' })
import store from '@/stores'
import apiTableColumns from '@/utils/common/apiTableColumns'
import { reactive, ref, onMounted,computed,defineExpose } from 'vue'
import {
getCommonPost,
getCommonPaged,
getCommonDeatailPaged,
postCommonExport,
postCommonCreate,
putCommonUpdate,
deleteCommonApi,
getCommonCustominvoke
} from '@/api/common/index'
import { ElMessageBox, ElMessage,ElTable, ElTableColumn } from 'element-plus'
import elTable from '@/components/elTable/index.vue'
import elPager from '@/components/elPager/index.vue'
import setColumsPop from '@/components/setColumsPop/index.vue'
import { getPageParamsForFilter,getLocalTableColumnsName } from '@/utils/common/index'
import { downloadByData } from '@/utils/download'
import importPop from '@/components/importPop/index.vue'
import apiEditPop from '@/components/apiEditPop/index.vue'
import { formatDate } from '@/utils/formatTime'
import apiServeNames from '@/utils/common/apiServeNames'
import { useRoute } from 'vue-router'
const route = useRoute()
const userStore = store.userStore()
const userInfo = userStore.state
const state = reactive({
loading:false,
searchBtnOptions:{
search:{icon:'Search',auth:':page',label:'查询',type:null},
create:{icon:'Plus',auth:':create',label:'新增',type:'primary'},
import:{icon:'BottomRight',auth:':import',label:'导入',type:'warning'},
export:{icon:'TopRight',auth:':export',label:'导出',type:'success'},
custominvoke:{icon:'Position',auth:':custominvoke',label:'手动开关',type:'primary'},
},
innerTableColumns:null,
tableData:[],
// table
sortFilter:{
sortBy:undefined,
isAscending:undefined
},
pager:{
page: 1,
pageSize: 10,
total: 1,
},
tableSelectList:[],
initTableColums:[],//
localTableColumnsName:null
})
const props = defineProps({
// api
apiName: {
type: String,
default: null
},
// api
specialPageApi:{
type: String,
default: null
},
// columnapiName
specialColumnName:{
type: String,
default: null
},
// columnapiName
specialLocalColumnName:{
type: String,
default: null
},
// 使apiName
authName:{
type: String,
default: null
},
// api detailApigetdetailpageApigetdatapaged
apiType: {
type: String,
default: null
},
//
hideSearch:{
type: Boolean,
default: false
},
// class
tableRowClassName:{
type: Function,
default: null
},
// class
tableCellClassName:{
type: Function,
default: null
},
//
multipleTable:{
type: Boolean,
default: false
},
//
leftOperation:{
type: Object,
default: null
},
//
leftOperationColumnWidth:{
type: Number,
default: 120
},
//
rightOperation:{
type: [Object,String],
default: null
},
// api
showApiRightOperation:{
type: Object,
default: null
},
// writeState=true
// 使,=
apiRightHideConfig:{
type: Object,
default: {
apiUpdate:{prop:'writeState',ruleValue:true},
apiDelete:{prop:'writeState',ruleValue:true},
}
},
// table
tableColumns: {
type: Object,
default: null
},
//
searchOptions: {
type: Object,
default: []
},
//
searchButtons: {
type: Object,
default: ['search','export']
},
// tablefilter
searchFilter: {
type: Object,
default: {}
},
// tablefiltercolum
// infoSearchFilterOptions:{ TableName:{action:'=='}},
searchFilterOptions: {
type: Object,
default: {}
},
//
columnWidth:{
type: Number,
default: 120
},
//
columnHeaderAlign:{
type: String,
default: 'center'
},
//
columnAlign:{
type: String,
default: 'center'
},
//
apiEditFormRules:{
type: Object,
default: null
},
//
hideSetColums:{
type: Boolean,
default: false
}
})
// noFilter
function getTableColumns(noFilter){
if(noFilter){
return props.tableColumns || apiTableColumns[props.apiName]
}else{
// location
let _localColumName = props.specialLocalColumnName || useRoute().name
state.localTableColumnsName = getLocalTableColumnsName(_localColumName)
let _local = JSON.parse(localStorage.getItem(state.localTableColumnsName))
//
let _apiColums = props.specialColumnName || props.apiName
state.initTableColums = props.tableColumns || apiTableColumns[_apiColums]
let _list = (_local && _local != null && _local != undefined) ? _local : JSON.parse(JSON.stringify(state.initTableColums))
state.innerTableColumns = _list
return _list
}
}
const emits = defineEmits([
'leftOperationHadel',
'rightOperationHadel',
'tableSelectionHandle'
])
// table
function tableSelectionHandle (val){
state.tableSelectList = val
emits('tableSelectionHandle',val)
}
//
function leftOperationHadel(btn,scope) {
emits('leftOperationHadel',btn,scope)
}
//
function getRightOperation() {
// api
if(typeof props.rightOperation == 'object' && !props.showApiRightOperation){
return props.rightOperation
}
// api
else if(
(typeof props.rightOperation == 'object' && props.showApiRightOperation)
|| typeof props.rightOperation == 'string'
){
// api
let _apiArr = props.showApiRightOperation || props.rightOperation.split(',')
let _config = {
apiUpdate:{label:'编辑',type:'warning'},
apiDelete:{label:'删除',type:'danger'},
}
let _btns = []
if(_apiArr && _apiArr.length > 0){
_apiArr.forEach(item => {
_btns.push({
label:_config[item].label,
name:item,
link:true,
type:_config[item].type,
auth:(props.authName || props.apiName)+':'+item,
hide:(row,scope) => {return row[props.apiRightHideConfig[item].prop] == props.apiRightHideConfig[item].ruleValue}
})
});
}
// api
if(typeof props.rightOperation == 'object'){
_btns = [..._btns,...props.rightOperation]
}
return _btns
}
}
//
const apiEditPopRef = ref()
function rightOperationHadel(btn,scope) {
//
if(btn.name == 'apiUpdate'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list,scope.row)
}
//
if(btn.name == 'apiDelete'){
ElMessageBox.confirm(`是否确定删除?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
deleteCommonApi(props.apiName,scope.row.uId)
.then(res=>{
ElMessage.success('操作成功!')
getTableData(1);
})
.finally(()=>{state.loading = false})
})
}
emits('rightOperationHadel',btn,scope)
}
//
const submitEditForm = async (type,formData,formConfig) => {
apiEditPopRef.value.validate((valid) => {
if(valid){
//
if(type == 'create'){
if(formData.hasOwnProperty('createUser')){formData.createUser = userInfo.realName}
if(formData.hasOwnProperty('createByUser')){formData.createByUser = userInfo.realName}
if(formData.hasOwnProperty('createTime')){formData.createTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
apiEditPopRef.value.changeLoading(true)
postCommonCreate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}else{
//
if(
(formData.hasOwnProperty('updateByUser') && formData.hasOwnProperty('updateTime'))
|| (formData.hasOwnProperty('updateUser') && formData.hasOwnProperty('updateTime'))
){
if(formData.hasOwnProperty('updateByUser')){formData.updateByUser = userInfo.realName}
if(formData.hasOwnProperty('updateUser')){formData.updateUser = userInfo.realName}
if(formData.hasOwnProperty('updateTime')){formData.updateTime = formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}
}else{
//
let _notChange=['taskconifgure','customlog']
if(_notChange.indexOf(props.apiName) < 0){
formData.remark= `修改信息:${userInfo.realName} ${formatDate(new Date(), "YYYY-mm-dd HH:MM:SS")}`
}
}
apiEditPopRef.value.changeLoading(true)
putCommonUpdate(props.apiName,formData)
.then(res=>{
apiEditPopRef.value.close()
ElMessage.success('操作成功!')
getTableData(1);
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(()=>{apiEditPopRef.value.changeLoading(false)})
}
}
})
}
//
function getPageParams(pageSize){
let _filters = []
if(props.hideSearch){
_filters = props.searchFilter
}else{
function __getAction (prop,action){
if(props.searchFilterOptions && props.searchFilterOptions[prop] && props.searchFilterOptions[prop].action){
return props.searchFilterOptions[prop].action
}else{
return action
}
}
for(let i in props.searchFilter){
let _item = props.searchOptions.filter(item=>item.prop == i)
let _type = (_item && _item.length > 0) ? _item[0].type : null
if((props.searchFilter[i] || props.searchFilter[i] == 0) && props.searchFilter[i] != ""){
//
if(_type == 'datetimerange'){
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,'>='),
value: props.searchFilter[i][0]
}
)
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,'<='),
value: props.searchFilter[i][1]
}
)
}else{
let _action = 'like'
let _EqualTypes = ['tagFilter','filter','number','select']//
if(_EqualTypes.indexOf(_type) >= 0){
_action = '=='
}
_filters.push(
{
logic: "And",
column: i,
action: __getAction(i,_action),
value: props.searchFilter[i]
}
)
}
}
}
}
let _pageParams = getPageParamsForFilter({
pageNumber:state.pager.page,
pageSize:pageSize || state.pager.pageSize,
sortBy:state.sortFilter.sortBy,
isAscending:state.sortFilter.isAscending,
condition:{
filters:_filters
}
})
return _pageParams
}
//
function getTableData(page,callback) {
state.loading = true
if(!page)page = state.pager.page
if(page)state.pager.page = page
if(props.apiType == 'detailApi'){
getCommonDeatailPaged(props.apiName,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}else if(props.specialPageApi){
getCommonPost(props.specialPageApi,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
else{
getCommonPaged(props.apiName,getPageParams())
.then((resp) => {
state.tableData = resp.data.data
state.pager.total = resp.data.totalCount
if(callback)callback(resp)
})
.catch(err=>{ElMessage.error('数据获取失败!')})
.finally(() => (state.loading = false))
}
}
//
function exportHandle(isAll){
state.loading = true
//
getTableData(1,(res=>{
let _params = getPageParams()
if(isAll){_params = getPageParams(res.data.totalCount)}
postCommonExport(props.apiName,_params)
.then((res) => {
let _str = isAll ? '全部' : '当页'
downloadByData(res.data,route.meta.title+`.xlsx`)
})
.catch(err=>{ElMessage.error('操作失败!')})
.finally(() => (state.loading = false))
}))
}
const importPopRef = ref()
//
function searchBtnHandle(btn){
//
if(btn == 'search'){
getTableData(1)
}
//
else if (btn == 'create'){
let _tableColums = props.tableColumns || apiTableColumns[props.apiName]
let _list = _tableColums.filter(item => !item.noEdit)
apiEditPopRef.value.open(_list)
}
//
else if (btn == 'import'){
importPopRef.value.open()
}
//
else if (btn == 'export'){
exportHandle()
}
//
else if (btn == 'custominvoke'){
ElMessageBox.confirm('是否确定操作手动开关?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
state.loading = true
let _data = {
taskName:apiServeNames[props.apiName].taskName,
client:'Chery'
}
getCommonCustominvoke(_data)
.then((res) => {
ElMessage.success('操作成功!')
getTableData(1)//
})
.finally(() => (state.loading = false))
})
}
}
//
function sortChange(data) {
const { prop, order } = data;
if (!prop || !order) {
state.sortFilter.sortBy = undefined;
state.sortFilter.isAscending = undefined;
getTableData(1);
return;
}
state.sortFilter.sortBy = prop;
state.sortFilter.isAscending = (order == "ascending");
getTableData(1);
}
// todo
function importSuccess(response,importDate){
getTableData()
}
// size-change
function pageSizeChange(pageSize){
state.pager.pageSize = pageSize
getTableData(1)
}
// current-change
function pageCurrentChange(page){
getTableData(page)
}
onMounted(() => {
getTableColumns()
getTableData()
})
defineExpose({
state,
getTableData
});
</script>
<style scoped lang="scss">
::v-deep .search-container {
.el-card__body{
display:flex;
justify-content: space-between;
}
}
</style>

4
Web/src/layout/components/Footer/index.vue

@ -1,7 +1,7 @@
<template>
<div class="layout-footer">
<div style="margin-top:5px"><span>vue3-admin-template</span> </div>
<div style="margin-top:5px">Copyright © 2023 Daming All rights reserved.</div>
<div style="margin-top:20px"><span>常熟安通林汽车饰件有限公司</span> </div>
<!-- <div style="margin-top:5px">Copyright © 2023 Daming All rights reserved.</div> -->
</div>
</template>

14
Web/src/layout/components/Sidebar/Logo.vue

@ -2,12 +2,12 @@
<div class="sidebar-logo-container">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo&&showLogo" :src="logo" class="sidebar-logo">
<img v-if="showLogo" src="/logo.png">
<h1 v-else class="sidebar-title">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo&&showLogo" :src="logo" class="sidebar-logo">
<h1 class="sidebar-title">{{ title }} </h1>
<img v-if="showLogo" src="/logo.png" class="sidebar-logo">
<h1 v-else class="sidebar-title">{{ title }} </h1>
</router-link>
</transition>
</div>
@ -15,6 +15,8 @@
<script>
import store from '@/stores'
import getPageTitle from '@/utils/get-page-title'
export default {
name: 'SidebarLogo',
setup() {
@ -34,8 +36,7 @@ export default {
},
data() {
return {
title: 'Vue Admin Template',
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png'
title: getPageTitle(),
}
}
}
@ -64,8 +65,7 @@ export default {
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
width: 100px;
vertical-align: middle;
margin-right: 12px;
}

2
Web/src/layout/components/Sidebar/index.vue

@ -113,7 +113,7 @@ div.el-scrollbar__view {
}
.aside-container:not(.collapsed) {
width: 210px; /* 默认宽度 */
width: 260px; /* 默认宽度 */
}
.el-menu{

6
Web/src/layout/components/SidebarColumn/index.vue

@ -1,7 +1,7 @@
<template lang="">
<el-aside width="70px" class="sidebar-column-container">
<div class="sidebar-logo-container" v-if="settingsStore.sidebarLogo">
<img :src="state.logo" class="sidebar-logo" />
<img src="/logo_op.png" class="sidebar-logo" />
</div>
<div class="menu-container">
<ul class="menu-list">
@ -34,7 +34,6 @@ const emits = defineEmits(['modulesChange'])
const route = useRoute()
const state = reactive({
logo: 'https://wpimg.wallstcn.com/69a1c46c-eb1c-4b46-8bd4-e9e686ef5251.png',
highlightId: 0,
modules: []
})
@ -83,8 +82,7 @@ function columnModulesChange(modules) {
}
.sidebar-logo {
width: 32px;
height: 32px;
width: 60px;
}
.sidebar-logo-container {

5
Web/src/main.js

@ -25,6 +25,11 @@ import { directive } from '@/directive/index'
// 上传附件注册
import { Boot } from '@wangeditor/editor'
import attachmentModule from '@wangeditor/plugin-upload-attachment'
// localStorage监听
import { dispatchEventStroage } from "@/utils/common/localStorage"
dispatchEventStroage()
// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。
Boot.registerModule(attachmentModule)

6
Web/src/settings.js

@ -1,5 +1,7 @@
const mode = import.meta.env.MODE
const _title = mode == 'production' ? systemConfig.title : 'EDI接口平台'
export default {
title: 'Vue Admin Template',
title: _title,
/**
* @type {boolean} true | false
@ -16,7 +18,7 @@ export default {
/***
* 是否显示页脚
*/
showFooter: true,
showFooter: false,
/**
* @type {string | array} 'production' | ['production', 'development']

2
Web/src/styles/element-ui.scss

@ -46,7 +46,7 @@
margin: var(--el-dialog-margin-top,15vh) auto 0px;
header {
background: var(--el-color-primary);
// background: var(--el-color-primary);
color: #fff;
padding: 10px;

2
Web/src/styles/index.scss

@ -87,7 +87,7 @@ div:focus {
}
//全局input输入框长度不设置时clearable会导致宽度自动变更
.el-input {
width: 200px !important;
width: 180px !important;
}
}
}

2
Web/src/styles/variables.module.scss

@ -15,7 +15,7 @@ $menuHover_dark: #1e1e1e;
$subMenuBg_dark: #3c3c3c;
$subMenuHover_dark: #1e1e1e;
$sideBarWidth: 210px;
$sideBarWidth: 260px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass

196
Web/src/utils/common/apiServeNames.js

@ -0,0 +1,196 @@
const apiServeNames = {
// M+6月物料需求计划风险确认
cherysupplierconmmrp:{
tableName:'SUPPLIER_CON_MMRP',
taskName:'M+6月物料需求计划风险确认',
},
// 日物料需求计划风险确认
cherysuppliercondate:{
tableName:'SUPPLIER_CON_DATE',
taskName:'日物料需求计划风险确认'
},
// 采购订单风险确认
cherysupplierconpo:{
tableName:'SUPPLIER_CON_PO',
taskName:'采购订单风险确认'
},
// 供应商共享库存
cherysuppliersinvdata:{
tableName:'SUPPLIER_SINV_DATA',
taskName:'供应商共享库存'
},
// 来料检验数据
supplierpromaterialstock:{
tableName:'SUPPLIER_PRO_MATERIAL_STOCK',
taskName:'来料检验数据'
},
// 排产数据
cherysupplierproscheduling:{
tableName:'SUPPLIER_PRO_SCHEDULING',
taskName:'排产数据'
},
// 供应商基础信息
supplierinfodt:{
tableName:'SUPPLIER_INFO',
taskName:'供应商基础信息'
},
// 人员资质信息
supplieremployeedt:{
tableName:'SUPPLIER_EMPLOYEE',
taskName:'人员资质信息'
},
// BOM主数据
cherysupplierbom:{
tableName:'SUPPLIER_BOM',
taskName:'BOM主数据'
},
// 过程控制项质量数据
cherysupplierprocps:{
tableName:'SUPPLIER_PRO_CPS',
taskName:'过程控制项质量数据'
},
// 生产过程数据
cherysupplierprodata:{
tableName:'SUPPLIER_PRO_DATA',
taskName:'生产过程数据'
},
// 产品一次合格率
cherysupplierprofirstpassyield:{
tableName:'SUPPLIER_PRO_FIRST_PASSYIELD',
taskName:'产品一次合格率'
},
// 工位一次合格率
cherysupplierprostationfirstpassyield:{
tableName:'SUPPLIER_PRO_STATION_FIRST_PASSYIELD',
taskName:'工位一次合格率'
},
// 缺陷业务数据
cherysupplierproflaw:{
tableName:'SUPPLIER_PRO_FLAW',
taskName:'缺陷业务数据'
},
// 物料主数据
cherysupplierpromaterialdata:{
tableName:'SUPPLIER_PRO_MATERIAL_DATA',
taskName:'物料主数据'
},
// 附件类数据
cherysupplierproattachmentdata:{
tableName:'SUPPLIER_PRO_ATTACHMENT_DATA',
taskName:'附件类数据'
},
// 工艺装备
supplierproprocessequipmentdt:{
tableName:'SUPPLIER_PRO_PROCESS_EQUIPMENT',
taskName:'工艺装备'
},
// 工艺
cherysupplierproprocess:{
tableName:'SUPPLIER_PRO_PROCESS',
taskName:'工艺'
},
/*无页面,供任务明细页面使用 */
// 环境业务数据
cherysupplierproenvironment:{
tableName:'SUPPLIER_PRO_ENVIRONMENT',
taskName:'环境业务数据'
},
// 设备OEE达成率
cherysupplierprooeeachievementrate:{
tableName:'SUPPLIER_PRO_OEE_ACHIEVEMENT_RATE',
taskName:'设备OEE达成率'
},
// OEE时间明细
cherysupplierprooeetimedetails:{
tableName:'SUPPLIER_PRO_OEE_TIME_DETAILS',
taskName:'OEE时间明细'
},
// 整车月度生产计划2
supplierproplaning:{
taskName:'整车月度生产计划2'
},
// M+6月物料需求计划
cherysuppliermrpmonth:{
taskName:'M+6月物料需求计划'
},
// 日物料需求计划
cherysuppliermrpdata:{
taskName:'日物料需求计划'
},
// 计划协议
cherysuppliersaweek:{
taskName:'计划协议'
},
// 采购订单
cherysupplierpo:{
taskName:'采购订单'
},
// 过焊装未过总装
cherysupplierporhschedul:{
taskName:'过焊装未过总装'
},
// 过涂装未过总装
cherysupplierprotschedul:{
taskName:'过涂装未过总装'
},
// 退货单
cherysupplierreturn:{
taskName:'退货单'
},
// 奇瑞RDC共享库存
supplierinvdata:{
taskName:'奇瑞RDC共享库存'
},
// 日MRP状态监控
cherysuppliermrp:{
taskName:'日MRP状态监控'
},
// 日MRP预警推移
cherysuppliermrpwarning:{
taskName:'日MRP预警推移'
},
// 看板送货单
cherysupplierdelstate:{
taskName:'看板送货单'
},
// 排序供货
cherysupplierprocschedul:{
taskName:'排序供货'
},
}
export default apiServeNames

1094
Web/src/utils/common/apiTableColumns.js

File diff suppressed because it is too large

125
Web/src/utils/common/enumList.js

@ -0,0 +1,125 @@
const EnumList = {
// 是否
whether:[
{label:'是',value:1,type:'success'},
{label:'否',value:0,type:'danger'}
],
// 是否Y/N
whetherByYN:[
{label:'是',value:'Y',type:'success'},
{label:'否',value:'N',type:'danger'},
],
// 是否boolean
whetherBoolean:[
{label:'是',value:true,type:'success'},
{label:'否',value:false,type:'danger'}
],
// 退货类型
returnType:[
{label:'合格品',value:1},
{label:'不合格品',value:0}
],
// 物料类型
materialType:[
{label:'成品',value:'成品'},
{label:'半成品',value:'半成品'},
{label:'原材料',value:'原材料'},
],
// 父件(供应商总成)类型
vendorProductType:[
{label:'成品',value:'成品'},
{label:'半成品',value:'半成品'},
],
// 子件类型
subMaterialType:[
{label:'半成品',value:'半成品'},
{label:'原材料',value:'原材料'},
],
// 库存状态
inventoryStatus:[
{label:'生产件',value:'生产件'},
{label:'呆滞件',value:'呆滞件'},
{label:'备件',value:'备件'},
{label:'KD件',value:'KD件'},
],
// 反馈结果
feedbackResults:[
{label:'异常',value:'1'},
{label:'无异常',value:'0'},
],
// 风险类型
ventureType:[
{label:'生产节拍不足',value:'1'},
{label:'人员不足',value:'2'},
{label:'原材料不足',value:'3'},
{label:'设备异常',value:'4'},
{label:'其他',value:'5'},
],
// 批次的最终判定结果
checkResult:[
{label:'合格',value:'OK'},
{label:'不合格',value:'NG'},
],
// 排产状态
planStatus:[
{label:'未生产',value:'0'},
{label:'生产中',value:'1'},
{label:'已完工',value:'2'},
{label:'已取消',value:'3'},
{label:'已终止',value:'4'},
],
// 在线检测
detectionMode:[
{label:'在生产线上进行检测',value:'inline'},
{label:'从生产线上拿下来进行检测',value:'offline'},
{label:'同时存在',value:'both'},
],
// 班次
workShift:[
{label:'白班',value:'白班'},
{label:'晚班',value:'晚班'},
{label:'中班',value:'中班'},
],
// 检测方式
checkMode:[
{label:'人工',value:'人工'},
{label:'设备',value:'设备'},
],
// 缺陷分类
defectsClass:[
{label:'外观',value:'外观'},
{label:'尺寸',value:'尺寸'},
{label:'材料',value:'材料'},
{label:'功能',value:'功能'},
{label:'性能',value:'性能'},
{label:'其他',value:'其他'},
],
// 缺陷等级
defectsLevel:[
{label:'严重',value:'1'},
{label:'一般',value:'2'},
{label:'轻微',value:'3'},
],
// 附件数据类型
attachmentType:[
{label:'产前管理',value:'1'},
{label:'人员资质',value:'2'},
{label:'监控视频',value:'3'},
],
// 工艺装备类型分类
deviceType:[
{label:'模具',value:'1'},
{label:'检具',value:'2'},
{label:'夹具',value:'3'},
],
// OEE时间明细-大类(供任务明细页面使用)
OEETimeType:[
{label:'计划工作',value:'1'},
{label:'计划停机',value:'2'},
{label:'非计划停机',value:'3'},
],
}
export default EnumList

96
Web/src/utils/common/index.js

@ -0,0 +1,96 @@
import apiServeNames from '@/utils/common/apiServeNames'
import apiTableColumns from '@/utils/common/apiTableColumns'
import store from '@/stores'
const userStore = store.userStore()
const userInfo = userStore.state
// filter中空字符转义
export function getPageParamsForFilter(pageParams){
if(pageParams.filters && JSON.stringify(pageParams.filters) != "{}"){
for(let i in pageParams.filters){
if(pageParams.filters[i] == ""){
pageParams.filters[i] = null
}
}
}
return pageParams
}
// 下载字符串以json文件格式
/**
* @param {*} stringData 字符串
* @param {*} title 文件名
*/
export async function downLoadJSONByString(stringData,title){
// dada 表示要转换的字符串数据,type 表示要转换的数据格式
const blob = new Blob([stringData], {
type: 'application/json'
})
// 根据 blob生成 url链接
const objectURL = URL.createObjectURL(blob)
// 创建一个 a 标签Tag
const aTag = document.createElement('a')
// 设置文件的下载地址
aTag.href = objectURL
// 设置保存后的文件名称
aTag.download = title
// 给 a 标签添加点击事件
aTag.click()
// 释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。
// 当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。
URL.revokeObjectURL(objectURL)
}
// 法根据tableName获取api
export function getApiByServeName(value,prop='tableName'){
let _api = null
// taskName 特殊处理
if(prop == 'taskName'){
let _special = {
'整车月度生产计划1':'supplierproplaning',
'M+6月物料需求计划1':'cherysuppliermrpmonth',
'M+6月物料需求计划2':'cherysuppliermrpmonth',
'供应商共享库存-上午':'cherysuppliersinvdata',
'供应商共享库存-晚上':'cherysuppliersinvdata',
}
for(let i in _special){
if(i == value){
_api = _special[i]
}
}
}
if(!_api){
for(let i in apiServeNames){
if(apiServeNames[i][prop] == value){
_api = i
}
}
}
return _api
}
// 法根据tableName获取api对应的Coloums
export function getColoumsByServeName(value,prop='tableName',noEdit){
let _api = getApiByServeName(value,prop)
let __colums = null
if(_api){
__colums = JSON.parse(JSON.stringify(apiTableColumns[_api]))
if(noEdit){
__colums.forEach(item => {
if(item.type == 'input' || item.type == 'numberInput' || item.type == 'datetimeInput'){
item.type = null
}
if(item.type == 'filterSelect'){
item.type = 'filter'
}
});
}
}
return __colums
}
// 获取字段设置暂存的key值
export function getLocalTableColumnsName(pageName){
return `tableColumns_${userInfo.userName}_${pageName}`
}

11
Web/src/utils/common/localStorage.js

@ -0,0 +1,11 @@
// 重写setItem事件,当使用setItem的时候,触发,window.dispatchEvent派发事件
export function dispatchEventStroage () {
const signSetItem = localStorage.setItem
localStorage.setItem = function (key, val) {
let setEvent = new Event('setItemEvent')
setEvent.key = key
setEvent.newValue = val
window.dispatchEvent(setEvent)
signSetItem.apply(this, arguments)
}
}

12
Web/src/utils/formatTime.js

@ -258,3 +258,15 @@ export function diffInSeconds(startDate, endDate) {
const millisecondsPerSecond = 1000;
return Math.floor((endDate - startDate) / millisecondsPerSecond);
}
// 2022-08-31T09:45:51.9340433 转 2022-08-31 09:45:51
export function formatTimeStrToStr(timeStr) {
if (!timeStr || !new Date(timeStr)) {
return ''
}
if (timeStr.lastIndexOf('.') == -1) {
return timeStr.replace('T',' ').substring(0,timeStr.length)
}
return timeStr.replace('T',' ').substring(0,timeStr.lastIndexOf('.'))
}

2
Web/src/utils/get-page-title.js

@ -1,6 +1,6 @@
import defaultSettings from '@/settings'
const title = defaultSettings.title || 'Vue Admin Template'
const title = defaultSettings.title || 'EDI接口平台'
export default function getPageTitle(pageTitle) {
if (pageTitle) {

14
Web/src/utils/request.js

@ -1,8 +1,12 @@
import axios from 'axios'
import { ElMessage } from 'element-plus'
import store from '@/stores'
const app_base_api = import.meta.env.VITE_API_BASE_URL
const mode = import.meta.env.MODE
console.log('mode',mode)
let app_base_api = import.meta.env.VITE_API_BASE_URL
if(mode == 'production'){
app_base_api = systemConfig.baseUrl
}
// create an axios instance
const service = axios.create({
baseURL: app_base_api, // url = base url + request url
@ -56,14 +60,14 @@ service.interceptors.response.use(
return response
}
// 1 是正确 .
if (res.code != 1) {
if (res.code != 1 && res.code != 200) {
//报错
ElMessage({
message: res.message || 'Error',
message: res.message || res.Message || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(res.message || 'Error'))
return Promise.reject(new Error(res.message || res.Message || 'Error'))
} else {
return res
}

37
Web/src/views/dashboard/index.vue

@ -1,28 +1,39 @@
<template>
<div class="dashboard-container">
<div class="dashboard-text">name: {{ name }}</div>
<div class="homeMenuPage">
<menu-Item
v-for="(item,index) in treeData"
:key="index"
:item="item"
></menu-Item>
</div>
</template>
<script setup>
defineOptions({ name: 'dashboardIndex' })
import { getCurrentMenu } from '@/api/system/userApi'
import store from '@/stores'
import { computed } from 'vue'
import menuItem from './menuItem.vue'
import { onMounted,computed,ref } from 'vue'
import { asyncRoutes } from '@/router/index'
const userStore = store.userStore()
const name = computed(() => userStore.state.name)
// const name = computed(() => userStore.state.name)
let loading = ref(false)
let treeData = asyncRoutes
const defaultProps = ref({
children: 'children',
label: 'menuName',
})
onMounted(() => {
})
</script>
<style lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
}
&-text {
font-size: 30px;
line-height: 46px;
}
.homeMenuPage{
width:100%;
overflow:auto
}
</style>

72
Web/src/views/dashboard/menuItem.vue

@ -0,0 +1,72 @@
<template>
<div :class="[(!props.item.children || props.item.children.length <= 0) ? 'childBlock':'menuBlock clearfix']">
<div class="firstTitle" v-if="props.item.children && props.item.children.length > 0">{{props.item.meta.title}}</div>
<router-link v-else class="itemTitle" :to="props.item.path">
{{props.item.meta.title}}</router-link>
<div v-if="props.item.children && props.item.children.length > 0" class="isNestBolck">
<menu-Item
v-for="child in props.item.children"
:key="child.path"
:item="child"
/>
</div>
</div>
</template>
<script setup>
defineOptions({ name: 'menuItem' })
import menuItem from './menuItem.vue'
import { onMounted,ref } from 'vue'
const props = defineProps({
//
item:{
type: Object,
default: null
},
})
onMounted(() => {
console.log(props.item)
})
</script>
<style lang="scss" scoped>
.clearfix{
zoom:1;
}
.clearfix:after{
clear:both;
display:block;
visibility:hidden;
height:0;
line-height:0;
content:'';
}
.menuBlock{
margin-bottom:16px;
border-bottom:#e5e5e5 solid 1px;
box-shadow:#f2f2f2 1px 3px 5px;
padding:20px 20px 0;
.childBlock{
.itemTitle{
float:left;
margin-bottom:13px;
margin-right:30px;
color:#555;
&:hover{
color:var(--el-color-primary)
}
}
}
.firstTitle{
border-left: var(--el-color-primary) solid 5px;
padding-left:15px;
margin-bottom:20px;
color:#333;
font-weight:bold
}
}
</style>

63
Web/src/views/demo/tablePageDemo.vue

@ -0,0 +1,63 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// tablePage 使demo
defineOptions({ name: 'tablePageDemo' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'tablePageDemo',
searchFilter: {
materialCode: null,
// createTime:null,
// isDelete:null,
// quantity1:null
},
searchOptions:[
{type:'input',prop:'materialCode',label:'物料号'},
// {type:'datetimerange',prop:'createTime',label:''},
// {type:'number',prop:'quantity1',label:'1'},
// {type:'select',prop:'isDelete',label:'',options:EnumList.whether,noSearch:true},
],
// , view/task/taskConifgure.vue
// leftOperation:[
// {label:'',name:'showInfo',link:true,type:'primary'}
// ],
// 1api
// rightOperation:'apiUpdate,apiDelete',
//2,api使showApiRightOperation
// rightOperation:[],
// showApiRightOperation:['apiUpdate']
// /rule
// apiEditFormRules:{
// supplierCode: [{ required: true, message: '', trigger: 'blur' }],
// supplierName: [{ required: true, message: '', trigger: 'blur' }],
// deadLine: [{ required: true, message: '', trigger: 'blur' }],
// }
})
//
// function leftOperationHadel(btn,scope) {
// console.log(btn,scope)
// }
//2
// state.rightOperation = [{label:'2',name:'edit',link:true,type:'danger',auth:state.apiName+':page'}]
//
// :leftOperation="state.leftOperation"
// @leftOperationHadel="leftOperationHadel"
// :rightOperation="state.rightOperation"
// :showApiRightOperation="state.showApiRightOperation"
// :apiEditFormRules="state.apiEditFormRules"
</script>

38
Web/src/views/logisticsPlan/supplierConDate/index.vue

@ -0,0 +1,38 @@
<template>
<ediTtablePage
:columnWidth="200"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:detailColumName="'cherysuppliercondateDetail'"
:searchButtons="['search','export','outputMany']"
:multipleTable="state.auths.hasPermission(state.apiName+':outputMany')"
></ediTtablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierConDate' })
import store from '@/stores'
import { reactive, ref, onMounted } from 'vue'
import ediTtablePage from '@/components/ediTtablePage/index.vue'
const state = reactive({
apiName:'cherysuppliercondate',
searchFilter: {
supplierCode: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
auths:store.permissionStore(),
// :tableFormRules="state.tableFormRules"
// tableFormRules:{
// plantId:[{ required: true, message: '', trigger: 'change' },]
// }
})
</script>

38
Web/src/views/logisticsPlan/supplierConMmrp/index.vue

@ -0,0 +1,38 @@
<template>
<ediTtablePage
:columnWidth="200"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:detailColumName="'cherysupplierconmmrpDetail'"
:searchButtons="['search','export','outputMany']"
:multipleTable="state.auths.hasPermission(state.apiName+':outputMany')"
></ediTtablePage>
</template>
<script setup>
// M+6
defineOptions({ name: 'supplierConMmrp' })
import store from '@/stores'
import { reactive, ref, onMounted } from 'vue'
import ediTtablePage from '@/components/ediTtablePage/index.vue'
const state = reactive({
apiName:'cherysupplierconmmrp',
searchFilter: {
supplierCode: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
auths:store.permissionStore(),
// :tableFormRules="state.tableFormRules"
// tableFormRules:{
// plantId:[{ required: true, message: '', trigger: 'change' },]
// }
})
</script>

38
Web/src/views/logisticsPlan/supplierConPo/index.vue

@ -0,0 +1,38 @@
<template>
<ediTtablePage
:columnWidth="200"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:detailColumName="'cherysupplierconpoDetail'"
:searchButtons="['search','export','outputMany']"
:multipleTable="state.auths.hasPermission(state.apiName+':outputMany')"
></ediTtablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierConPo' })
import store from '@/stores'
import { reactive, ref, onMounted } from 'vue'
import ediTtablePage from '@/components/ediTtablePage/index.vue'
const state = reactive({
apiName:'cherysupplierconpo',
searchFilter: {
supplierCode: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
auths:store.permissionStore(),
// :tableFormRules="state.tableFormRules"
// tableFormRules:{
// plantId:[{ required: true, message: '', trigger: 'change' },]
// }
})
</script>

26
Web/src/views/logisticsPlan/supplierDelState/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierDelState' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierdelstate',
searchFilter: {
deliveryNumber: null,
createTime:null,
},
searchOptions:[
{type:'input',prop:'deliveryNumber',label:'配送单号'},
{type:'datetimerange',prop:'createTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierInvData/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// RDC
defineOptions({ name: 'supplierInvData' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplierinvdata',
searchFilter: {
plantId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'plantId',label:'工厂代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierMrpDate/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierMrpDate' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliermrpdata',
searchFilter: {
materialCode: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'materialCode',label:'零件号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierMrpMonth/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// M+6
defineOptions({ name: 'supplierMrpMonth' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliermrpmonth',
searchFilter: {
materialCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'materialCode',label:'零件号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierMrpState/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// MRP
defineOptions({ name: 'supplierMrpState' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliermrp',
searchFilter: {
plantId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'plantId',label:'工厂代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierMrpWarning/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// MRP
defineOptions({ name: 'supplierMrpWarning' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliermrpwarning',
searchFilter: {
plantId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'plantId',label:'工厂代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierPo/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierPo' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierpo',
searchFilter: {
purchaseOrder: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'purchaseOrder',label:'采购订单号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierProCschedul/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProCschedul' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprocschedul',
searchFilter: {
materialCode: null,
creationTime:null,
},
searchOptions:[
{type:'input',prop:'materialCode',label:'物料编码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierProHschedul/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProHschedul' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierporhschedul',
searchFilter: {
productionLineId: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'productionLineId',label:'产线代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierProPlaning/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// 2
defineOptions({ name: 'supplierProPlaning' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplierproplaning',
searchFilter: {
materialCode: null,
creationTime:null,
},
searchOptions:[
{type:'input',prop:'materialCode',label:'物料号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierProTschedul/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProTschedul' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprotschedul',
searchFilter: {
productionLineId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'productionLineId',label:'产线代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierReturn/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
// 退
defineOptions({ name: 'supplierReturn' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierreturn',
searchFilter: {
returnNumber: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'returnNumber',label:'退货单号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

26
Web/src/views/logisticsPlan/supplierSaWeek/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierSaWeek' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliersaweek',
searchFilter: {
scheduleAgreement: null,
creationTime: null
},
searchOptions:[
{type:'input',prop:'scheduleAgreement',label:'计划协议号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

29
Web/src/views/logisticsPlan/supplierSinvData/index.vue

@ -0,0 +1,29 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierSinvData' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysuppliersinvdata',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

29
Web/src/views/productionQuality/supplierBom/index.vue

@ -0,0 +1,29 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:apiEditFormRules="state.apiEditFormRules"
></tablePage>
</template>
<script setup>
// BOM
defineOptions({ name: 'supplierBom' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierbom',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

30
Web/src/views/productionQuality/supplierEmployee/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','create','import','export']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierEmployee' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplieremployeedt',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate,apiDelete',
})
</script>

30
Web/src/views/productionQuality/supplierInfo/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','create','import','export']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierInfo' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplierinfodt',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate,apiDelete',
})
</script>

30
Web/src/views/productionQuality/supplierProAttachmentData/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','create','import','export']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProAttachmentData' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierproattachmentdata',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate,apiDelete',
})
</script>

30
Web/src/views/productionQuality/supplierProCps/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProCps' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprocps',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

30
Web/src/views/productionQuality/supplierProData/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProData' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprodata',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

30
Web/src/views/productionQuality/supplierProFirstPassyield/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProFirstPassyield' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprofirstpassyield',
searchFilter: {
cheryProductNo: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'cheryProductNo',label:'奇瑞零件号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

30
Web/src/views/productionQuality/supplierProFlaw/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProFlaw' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierproflaw',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

30
Web/src/views/productionQuality/supplierProMaterialStock/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProMaterialStock' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplierpromaterialstock',
searchFilter: {
supplierCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'supplierCode',label:'供应商代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

29
Web/src/views/productionQuality/supplierProProcess/index.vue

@ -0,0 +1,29 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:apiEditFormRules="state.apiEditFormRules"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProProcess' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierproprocess',
searchFilter: {
techCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'techCode',label:'工艺编码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

30
Web/src/views/productionQuality/supplierProProcessEquipment/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','create','import','export']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProProcessEquipment' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'supplierproprocessequipmentdt',
searchFilter: {
deviceCode: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'deviceCode',label:'工艺装备编码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate,apiDelete',
})
</script>

26
Web/src/views/productionQuality/supplierProScheduling/index.vue

@ -0,0 +1,26 @@
<template>
<tablePage
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'supplierProScheduling' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierproscheduling',
searchFilter: {
plantId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'plantId',label:'工厂代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
})
</script>

29
Web/src/views/productionQuality/upplierProMaterialData/index.vue

@ -0,0 +1,29 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'upplierProMaterialData' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierpromaterialdata',
searchFilter: {
cheryProductNo: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'cheryProductNo',label:'奇瑞零件号'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

30
Web/src/views/productionQuality/upplierProStationFirstPassyield/index.vue

@ -0,0 +1,30 @@
<template>
<tablePage
:columnWidth="150"
:apiName="state.apiName"
:searchOptions="state.searchOptions"
:searchFilter="state.searchFilter"
:rightOperation="state.rightOperation"
:searchButtons="['search','export','custominvoke']"
></tablePage>
</template>
<script setup>
//
defineOptions({ name: 'upplierProStationFirstPassyield' })
import { reactive, ref, onMounted } from 'vue'
import tablePage from '@/components/tablePage/index.vue'
const state = reactive({
apiName:'cherysupplierprostationfirstpassyield',
searchFilter: {
stationId: null,
creationTime:null
},
searchOptions:[
{type:'input',prop:'stationId',label:'工位代码'},
{type:'datetimerange',prop:'creationTime',label:'创建时间'},
],
rightOperation:'apiUpdate',
})
</script>

2
Web/src/views/system/autoJob/components/deferredJobDialog.vue

@ -28,7 +28,7 @@
</el-dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref,defineExpose } from 'vue'
import { deferredJob } from '@/api/system/autoJobApi'
import { ElMessage } from 'element-plus'

2
Web/src/views/system/autoJob/index.vue

@ -63,7 +63,7 @@
</template>
</el-table-column>
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/components/orgCascader.vue

@ -13,7 +13,7 @@
</template>
<script setup>
//
import { ref, onMounted, nextTick } from 'vue'
import { ref, onMounted, nextTick,defineExpose } from 'vue'
import { getTreeList } from '@/api/system/orgApi'
import { waiting } from '@/utils/index'

2
Web/src/views/system/components/orgTree.vue

@ -9,7 +9,7 @@
</template>
<script setup>
//
import { ref, onMounted } from 'vue'
import { ref, onMounted,defineExpose } from 'vue'
import { getElTreeList } from '@/api/system/orgApi'
const orgTreeList = ref([])

2
Web/src/views/system/components/userSelect.vue

@ -16,7 +16,7 @@
</template>
<script setup>
//
import { ref } from 'vue'
import { ref,defineExpose } from 'vue'
import { getSelectList } from '@/api/system/userApi'
const model = defineModel()

2
Web/src/views/system/components/userSelectDialog.vue

@ -68,7 +68,7 @@
</el-dialog>
</template>
<script setup>
import { reactive } from 'vue'
import { reactive,defineExpose } from 'vue'
import { getPaged } from '@/api/system/userApi'
import { ElMessageBox, ElMessage } from 'element-plus'
import OrgCascader from '@/views/system/components/orgCascader.vue'

2
Web/src/views/system/dataDict/components/dictDetailDialog.vue

@ -71,7 +71,7 @@
</el-dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref,defineExpose } from 'vue'
import { getPaged, deleteDataDictDetail } from '@/api/system/dataDictDetailApi'
import { ElMessageBox, ElMessage } from 'element-plus'
import EditDictDetailDialog from './editDictDetailDialog.vue'

2
Web/src/views/system/dataDict/components/editDialog.vue

@ -55,7 +55,7 @@
</el-dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref,defineExpose } from 'vue'
import { getMaxSort, addDataDict, updateDataDict, getDataDict } from '@/api/system/dataDictApi'
import { ElMessage } from 'element-plus'

2
Web/src/views/system/dataDict/components/editDictDetailDialog.vue

@ -55,7 +55,7 @@
</el-dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref,defineExpose } from 'vue'
import { getMaxSort, addDataDictDetail, updateDataDictDetail, getDataDictDetail } from '@/api/system/dataDictDetailApi'
import { ElMessage } from 'element-plus'

2
Web/src/views/system/dataDict/index.vue

@ -55,7 +55,7 @@
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 10px"
style="margin-top: 15px;float:right"
v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize"
:total="state.pageParams.Total"

2
Web/src/views/system/log/logDiffIndex.vue

@ -31,7 +31,7 @@
<el-table-column prop="elapsed" label="耗时" />
<el-table-column prop="createTime" label="记录时间" />
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/log/logEventIndex.vue

@ -32,7 +32,7 @@
<el-table-column prop="remark" label="备注" />
<el-table-column prop="createTime" label="记录时间" />
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/log/logExceptionIndex.vue

@ -47,7 +47,7 @@
<el-table-column prop="userName" label="userName" width="210"/>
<el-table-column prop="createTime" label="记录时间" width="210"/>
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/log/logJobIndex.vue

@ -32,7 +32,7 @@
<el-table-column prop="remark" label="备注" />
<el-table-column prop="createTime" label="记录时间" />
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/log/logLoginIndex.vue

@ -31,7 +31,7 @@
<el-table-column prop="logStatusText" label="状态" width="120"/>
<el-table-column prop="createTime" label="记录时间" />
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/log/logOperateIndex.vue

@ -44,7 +44,7 @@
<el-table-column prop="userName" label="userName" width="210"/>
<el-table-column prop="createTime" label="记录时间" width="210"/>
</el-table>
<el-pagination style="margin-top: 10px" v-model:currentPage="state.pageParams.Page"
<el-pagination style="margin-top: 15px;float:right" v-model:currentPage="state.pageParams.Page"
v-model:page-size="state.pageParams.PageSize" :total="state.pageParams.Total" background
layout="total, sizes,prev, pager, next" @size-change="handleQuery" @current-change="handleQuery"
:page-sizes="[10, 20, 50, 100]" />

2
Web/src/views/system/login/components/tenantDialog.vue

@ -33,7 +33,7 @@
</template>
<script setup>
import { reactive } from 'vue'
import { reactive,defineExpose } from 'vue'
import store from '@/stores'
import { useRouter } from 'vue-router'
const router = useRouter()

4
Web/src/views/system/login/index.vue

@ -9,7 +9,8 @@
label-position="left"
>
<div class="title-container">
<h3 class="title">XXX 系统登录</h3>
<h3 class="title" style="margin-bottom:10px">常熟安通林汽车饰件有限公司</h3>
<h3 class="title">{{defaultSettings.title}} 系统登录</h3>
</div>
<el-form-item prop="userName">
@ -106,6 +107,7 @@ const router = useRouter()
import store from '@/stores'
const userStore = store.userStore()
import tenantDialog from './components/tenantDialog.vue'
import defaultSettings from '@/settings'
const route = useRoute()

27
Web/src/views/system/menu/components/editDialog.vue

@ -24,7 +24,7 @@
<el-row>
<el-col :span="12">
<el-form-item label="父级" prop="parentId">
<el-cascader v-model="state.parentIds"
<el-cascader v-model="state.form.parentId"
:options=" state.menuTreeList"
:props="{ label: 'menuName', value: 'id' ,checkStrictly:true}" :clearable="state.form.menuType === 1" />
@ -152,7 +152,7 @@
</template>
<script setup >
import { reactive, ref, onMounted } from 'vue'
import { reactive, ref, onMounted,defineExpose } from 'vue'
import { getTreeList, getMaxSort, addMenu,updateMenu, getMenu } from '@/api/system/menuApi'
import ElIconList from './elIconList.vue'
import FaIconList from './faIconList.vue'
@ -168,7 +168,6 @@ const state = reactive({
iconTabActiveName: 'ele',
menuTreeList: [],
form: {},
parentIds: [],
loading:false,
})
@ -233,19 +232,21 @@ function openDialog(id) {
if (id) {
getMenu(id).then(res => {
state.form = res.data
if (res.data.parentId && res.data.parentId !== '0') {
state.parentIds = [res.data.parentId]
}
setFormRules()
})
.finally(() => (state.loading = false))
.finally(() => {
state.loading = false
state.isShowDialog = true
})
} else {
getMaxSort().then(res => {
state.form.sort = res.data
})
.finally(() => (state.loading = false))
.finally(() => {
state.loading = false
state.isShowDialog = true
})
}
state.isShowDialog = true
}
function iconChange(iconName) {
@ -272,7 +273,6 @@ function resetForm() {
status: 1,
openNewWindow: false,
}
state.parentIds=[]
setFormRules()
setTimeout(() => {
elFormRef.value?.resetFields()
@ -296,12 +296,13 @@ function setFormRules(){
function submit() {
state.form.parentId = (state.parentIds && state.parentIds.length > 0) ? state.parentIds[state.parentIds.length - 1] : null
elFormRef.value.validate((valid) => {
if (valid) {
let _data = JSON.parse(JSON.stringify(state.form))
_data.parentId = (_data.parentId && typeof _data.parentId == 'string') ? _data.parentId : _data.parentId[_data.parentId.length - 1]
state.loading=true
if (state.form.id) {
updateMenu(state.form)
updateMenu(_data)
.then(()=>{
emits('onClose')
ElMessage({
@ -313,7 +314,7 @@ function submit() {
})
.finally(() => (state.loading = false))
} else {
addMenu(state.form)
addMenu(_data)
.then(() => {
emits('onClose')
ElMessage({

1
Web/src/views/system/menu/index.vue

@ -56,6 +56,7 @@
</template>
<script setup>
// menuManage
defineOptions({ name: 'menuIndex' })
import { reactive, onMounted, ref } from 'vue'
import { getTreeList, deleteMenu } from '@/api/system/menuApi'

2
Web/src/views/system/message/components/editDialog.vue

@ -57,7 +57,7 @@
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css' // css
import { reactive, ref, shallowRef, onBeforeUnmount } from 'vue'
import { reactive, ref, shallowRef, onBeforeUnmount,defineExpose } from 'vue'
import { addMessage, updateMessage, getMessage } from '@/api/system/messageApi'
import { uploadFile } from '@/api/system/fileApi'
import { ElMessage } from 'element-plus'

3
Web/src/views/system/message/components/publishDialog.vue

@ -101,7 +101,7 @@
</el-dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref,defineExpose } from 'vue'
import { ElMessage } from 'element-plus'
import { publishMessage } from '@/api/system/messageApi'
import EnumSelect from '@/views/system/components/enumSelect.vue'
@ -188,6 +188,7 @@ function handleQuery() {
function handleDelete(id) {
state.tableData = state.tableData.filter((item) => item.id !== id)
state.tableDataBak = state.tableDataBak.filter((item) => item.id !== id)
}
defineExpose({

2
Web/src/views/system/message/components/viewDialog.vue

@ -37,7 +37,7 @@
</el-dialog>
</template>
<script setup>
import { reactive } from 'vue'
import { reactive,defineExpose } from 'vue'
import { getMessage, setRead } from '@/api/system/messageApi'
const emits = defineEmits(['refresh'])

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save