Compare commits

1 Commits

Author SHA1 Message Date
chenlin
93ecebcb2e no message 2025-11-25 10:50:52 +08:00
32 changed files with 1911 additions and 5335 deletions

View File

@@ -4,7 +4,7 @@ VITE_NODE_ENV=development
VITE_DEV=true
# 请求路径 注:/api 正常不需要 当前是访问演示环境nginx转发用
VITE_BASE_URL='https://demo.jeelowcode.com/api'
VITE_BASE_URL='http://10.28.117.100'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server

View File

@@ -63,7 +63,7 @@ watch(
</script>
<template>
<ConfigGlobal :size="currentSize">
<div class="h-100% w-100%" style="overflow-y: auto;" :class="greyMode ? `${prefixCls}-grey-mode` : ''">
<div class="h-100% w-100%" :class="greyMode ? `${prefixCls}-grey-mode` : ''">
<RouterView />
</div>
<routerSearch />

View File

@@ -1,6 +1,5 @@
import request from '@/config/axios'
import { encryptAES } from '@/components/LowDesign/src/utils/aes'
import download from '@/utils/download'
//获取表单开发列表
export const getDbList = (data) => {
@@ -159,11 +158,6 @@ export const exportExcelData = (tableId, data) => {
return request.download({ url: `/jeelowcode/excel/exportExcel/${tableId}`, method: 'POST', data })
}
//导出Excel表数据
export const exportExcelDataCustom = (explain,tableId, data) => {
return request.download({ url: `/jeelowcode/excel/exportExcelCustom/${tableId}`, method: 'POST', data }).then((data) => download.excel(data, explain, 'xlsx'))
}
//下载导入模板
export const downloadImportTemplate = (tableId) => {
return request.download({ url: `/jeelowcode/excel/exportExcelTemplate/${tableId}` })

View File

@@ -1,6 +0,0 @@
import request from '@/config/axios'
// 获取外协管理数据
export const getOutsourcingManagementData = (data) => {
return request.post({ url: '/jeelowcode/report-data/list/kb_wx_jt', data })
}

View File

@@ -1,107 +0,0 @@
<template>
<ContentWrap>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<div v-for="taskAssignRule in props?.taskAssignRules" :key="taskAssignRule.taskDefinitionKey">
<el-divider content-position="left">审批节点{{ taskAssignRule?.taskDefinitionName }}</el-divider>
<el-form-item :label="'候选人'"
:prop="taskAssignRule.taskDefinitionKey"
label-width="122">
<UserSelect
v-model="formData[taskAssignRule.taskDefinitionKey]"
:column="userSelectColumn"
:prop="taskAssignRule.taskDefinitionKey"
type="edit"
:func="(value)=>{console.log(JSON.stringify(value))}"
>
</UserSelect>
</el-form-item>
</div>
</el-form>
</ContentWrap>
</template>
<script lang="ts" setup>
// 从 UserSelect 组件导入 Column 类型
import type {Column} from '@/components/LowDesign/src/shareControl/UserSelect.vue'
// 定义组件选项
defineOptions({
name: "BpmTaskSelectAssigneeForm"
})
interface TaskAssignRule {
id: number
modelId: string
processDefinitionId: string
taskDefinitionKey: string
taskDefinitionName: string
type: number
options: number[]
}
const props = defineProps<{
taskAssignRules: TaskAssignRule[]
modelValue: {}
}>()
const formRef = ref()
const formData = ref(props.modelValue)
const formRules = ref({})
const userSelectColumn: Column = {
label: '候选人',
findType: 'all',
multiple: false,
columnKey: ['sex', 'post', 'deptName']
}
const emit = defineEmits(['updateModelValue'])
watch(
() => props.modelValue,
(val: {}) => {
formData.value = val
},
{
deep: true,
immediate: true,
}
)
watch(
() => formData.value,
(val: {}) => {
emit('updateModelValue', val)
},
{
deep: true,
immediate: true,
}
)
const validateAssignee = (successCallBack: () => void, failCallback: () => void) => {
formRef.value.validate((valid: boolean) => {
if (valid) successCallBack()
else failCallback()
})
}
defineExpose({validateAssignee})
// 初始化 formData
onMounted(() => {
if (props.taskAssignRules) {
props.taskAssignRules.forEach(rule => {
formData.value[rule.taskDefinitionKey] = ''
formRules.value[rule.taskDefinitionKey] = [
{
required: true,
message: '请选择候选人',
trigger: 'blur'
}
]
})
}
})
</script>

View File

@@ -18,18 +18,6 @@
v-bind="userVBind"
class="w-100%"
></userSelect>
</span>
<span prop="delegateDictId" style="display:none">
<DicTableSelect
id="costomDictSelect"
:column="distSelectColumn"
size="default"
type="add"
prop="fields_7897245"
:scope="dictSelectScope"
@set-form-data="handleSetFormData"
></DicTableSelect>
</span>
<!-- 顶部统计 -->
<div
@@ -395,108 +383,12 @@ interface Props {
dicRowKey?: string //dicTable模式 行数据的 Key
}
const dictSelectScope = {
"key": 0,
"value": "",
"column": {
"type": "dicTableSelect",
"controlType": "select",
"label": "表格选择框",
// "fixedSearch":{
// "approveStatusName":"已审批"
// },
"separator": " | ",
"multiple": true,
"display": true,
"span": 12,
"disabled": false,
"required": false,
"hideLabel": false,
"i18nCode": "fields_7897245",
"dictTable": "1959187451673116674",
"dictCode": "id",
"dictText": "personName",
"dictTableColumn": [
"personName",
"personAge",
"personSex",
"mobile",
"approveStatusName"
],
"prop": "fields_7897245",
"dataType": "string",
"className": "control-dicTableSelect control-fields_7897245 ",
"props": {
"lable": "personName",
"value": "id"
},
"rules": [
]
},
"size": "default",
"disabled": false
}
const distSelectColumn = {
"type": "dicTableSelect",
"controlType": "select",
"multiple": true,
"label": "表格选择框",
"separator": " | ",
"display": true,
"span": 12,
"disabled": false,
// "fixedSearch":{
// "approveStatusName":"已审批"
// },
"required": false,
"hideLabel": false,
"i18nCode": "fields_7897245",
"dictTable": "1959187451673116674",
"dictCode": "id",
"dictText": "personName",
"dictTableColumn": [
"personName",
"personAge",
"personSex",
"mobile",
"approveStatusName"
]
,
"prop": "fields_7897245",
"dataType": "string",
"className": "control-dicTableSelect control-fields_7897245 ",
"props": {
"lable": "personName",
"value": "id"
},
"rules": [
]
}
const props = withDefaults(defineProps<Props>(), {
model: 'default',
fixedSearch: () => {
return {}
}
})
const handleSetFormData = (key, val) => {
const cleaned = val.split('|').map(s => s.trim()).join(','); // "1975577437793124352 | 1965778349088899074"
console.log(cleaned);
// 在这里添加其他处理逻辑
useFun.requestApi('get', '/jeelowcode/outsidePerson/importOutside?tableId='+props.tableId+'&ids=' + cleaned, {
}).then(res => {
if (res.length > 0) {
message.success('下发成功')
useFun.refreshChange()
} else {
message.error(res.message)
}
})
};
const userVBind = {
prop: 'delegateUserId',
type: 'edit',
@@ -548,17 +440,6 @@ const userVBind = {
}else if(props.tableId=='1968562717683908610'){ // 考试计划
useFun.requestApi('get', '/jeelowcode/examIssus/addRecord?tableId='+props.tableId+'&ids=' + ids+'&userIds='+resultValue, {
}).then(res => {
if (res.length > 0) {
message.success('下发成功')
useFun.refreshChange()
} else {
message.error(res.message)
}
})
}else if(props.tableId=='1983351353033953281'){ // 工作事项
useFun.requestApi('get', '/jeelowcode/itemIssus/addResult?tableId='+props.tableId+'&ids=' + ids+'&userIds='+resultValue, {
}).then(res => {
if (res.length > 0) {
message.success('下发成功')

View File

@@ -1,6 +1,5 @@
<template>
<div class="dic-table-select-box w-100%">
{{ JSON.stringify(props) }}
<div
class="table-input pos-relative"
:class="[{ disabled }, type, size]"
@@ -274,9 +273,9 @@ const getCurrTableSelect = (type?) => {
const dicObj = {}
const textList: string[] = []
const ids = tableRef.value.tableSelect.map((item) => {
if (item[props.column.dictCode]) {
dicObj[item[dicCode.value]] = item[props.column.dictCode]
textList.push(item[props.column.dictCode])
if (item[props.column.dictText]) {
dicObj[item[dicCode.value]] = item[props.column.dictText]
textList.push(item[props.column.dictText])
}
return item[dicCode.value]
})

View File

@@ -217,7 +217,7 @@ defineOptions({ name: 'UserSelect' })
* all_sub 所有下级
*/
export interface Column {
interface Column {
label: string
findType: 'all' | 'now' | 'sub' | 'all_sub' | 'direct_sub' //查询类型
columnKey: Array<'mobile' | 'email' | 'sex' | 'post' | 'deptName'> //扩展显示列

View File

@@ -34,7 +34,7 @@ const dicObj = {
{ label: '邮箱', value: 'email' }, { label: '性别', value: 'sex' }, { label: '岗位', value: 'post' }, { label: '部门', value: 'deptName' }
],
userFindType: [{ label: '全部用户', value: 'all' }, { label: '本级用户', value: 'now' }, { label: '本级及下级用户', value: 'sub' }],
deptFindType: [{ label: '全部部门', value: 'all' }, { label: '本级部门', value: 'now' }, { label: '本级及下级部门', value: 'sub' }, { label: '外协单位', value: 'out' }, { label: '内部单位', value: 'internal' }],
deptFindType: [{ label: '全部部门', value: 'all' }, { label: '本级部门', value: 'now' }, { label: '本级及下级部门', value: 'sub' }],
customControlType: [{ label: '未全局注册', value: false }, { label: '已全局注册', value: true }],
regionType: [{ label: '全球-国家', value: 'gj' }, { label: '中国-省市区', value: 'ssq' }, { label: '中国-省市', value: 'ss' }, { label: '中国-省', value: 's' }],
dictTextFormatter: [

View File

@@ -7,7 +7,6 @@ import { encryptAES, decryptAES } from '@/components/LowDesign/src/utils/aes'
import { useUserStoreWithOut } from '@/store/modules/user'
import { useI18n } from '@/hooks/web/useI18n';
import router from '@/router/index'
import {exportExcelDataCustom} from '@/api/design/table'
const message = useMessage() // 消息弹窗
@@ -19,7 +18,6 @@ export default {
* @param options 请求配置 如:{ params:{ text:'测试' } }
*/
requestApi: (Method, url, options) => callApiFun(Method, url, options),
exportExcelCustom: (tableId, data) => exportExcelDataCustom(tableId, data),
cloneDeep, //深拷贝
listToTree,//列表转树结构
formatDate,//时间格式化

View File

@@ -546,15 +546,13 @@ export const formDataFormatting = (formOption, formData, formType) => {
echoObj[dicKey].push(...data[key].split(','))
}
} else echoObj[type].push(...data[key].split(','))
} else if (column[key]?.controlType == 'date'||key=='create_time') {
} else if (column[key]?.controlType == 'date') {
if (data[key]) {
if (typeof data[key] == 'number' || typeof data[key] == 'string') {
data[key] = data[key] + ''
if (!(/[-|\/]/g.test(data[key]))) {
//如果是时间戳强制转换
const timestamp = parseInt(data[key], 10)
data[key] = formatDate(new Date(timestamp), column[key].valueFormat || 'YYYY-MM-DD HH:mm:ss')
data[key] = formatDate(new Date(data[key]), column[key].valueFormat || 'YYYY-MM-DD HH:mm:ss')
}
}
}

View File

@@ -171,7 +171,7 @@ const canvasClick = (e) => {
token: backToken.value
}
reqCheck(data).then((res) => {
if (res.repCode == '0000') {
if (res?.repCode == '0000') {
barAreaColor.value = '#4cae4c'
barAreaBorderColor.value = '#5cb85c'
text.value = t('captcha.success')
@@ -228,14 +228,14 @@ const getPictrue = async () => {
captchaType: captchaType.value
}
const res = await getCode(data)
if (res.repCode == '0000') {
pointBackImgBase.value = res.repData.originalImageBase64
backToken.value = res.repData.token
secretKey.value = res.repData.secretKey
poinTextList.value = res.repData.wordList
text.value = t('captcha.point') + '【' + poinTextList.value.join(',') + '】'
if (res?.repCode == '0000') {
pointBackImgBase.value = res?.repData?.originalImageBase64
backToken.value = res?.repData?.token
secretKey.value = res?.repData?.secretKey
poinTextList.value = res?.repData?.wordList || []
text.value = t('captcha.point') + '【' + poinTextList.value?.join(',') + '】'
} else {
text.value = res.repMsg
text.value = res?.repMsg
}
}
//坐标转换函数

View File

@@ -287,7 +287,7 @@ const end = () => {
token: backToken.value
}
reqCheck(data).then((res) => {
if (res.repCode == '0000') {
if (res?.repCode == '0000') {
moveBlockBackgroundColor.value = '#5cb85c'
leftBarBorderColor.value = '#5cb85c'
iconColor.value = '#fff'
@@ -364,13 +364,13 @@ const getPictrue = async () => {
captchaType: captchaType.value
}
const res = await getCode(data)
if (res.repCode == '0000') {
backImgBase.value = res.repData.originalImageBase64
blockBackImgBase.value = res.repData.jigsawImageBase64
backToken.value = res.repData.token
secretKey.value = res.repData.secretKey
if (res?.repCode == '0000') {
backImgBase.value = res?.repData?.originalImageBase64
blockBackImgBase.value = res?.repData?.jigsawImageBase64
backToken.value = res?.repData?.token
secretKey.value = res?.repData?.secretKey
} else {
tipWords.value = res.repMsg
tipWords.value = res?.repMsg
}
}
</script>

View File

@@ -57,45 +57,12 @@ const remainingRouter: AppRouteRecordRaw[] = [
name: 'Home',
meta: {},
children: [
// {
// path: 'index',
// component: () => import('@/views/Home/Index10.vue'),
// name: 'Index',
// meta: {
// title: t('router.home'),
// icon: 'ep:home-filled',
// noCache: false,
// affix: true
// }
// },
{
path: 'index',
component: () => import('@/views/Home/Index10.vue'),
name: 'Index',
meta: {
title: '集团视角数据看板',
icon: 'ep:home-filled',
noCache: false,
affix: true
}
},
{
path: 'region', // 区域数据看板
component: () => import('@/views/Home/Index12.vue'),
name: 'RegionIndex',
meta: {
title: '区域视角数据看板',
icon: 'ep:home-filled',
noCache: false,
affix: true
}
},
{
path: 'park', // 园区数据看板
component: () => import('@/views/Home/Index13.vue'),
name: 'ParkIndex',
meta: {
title: '园区视角数据看板',
title: t('router.home'),
icon: 'ep:home-filled',
noCache: false,
affix: true

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -227,11 +227,13 @@ const getCookie = () => {
// 根据域名,获得租户信息
const getTenantByWebsite = async () => {
const website = location.host
const res = await LoginApi.getTenantByWebsite(website)
if (res) {
loginData.loginForm.tenantName = res.name
authUtil.setTenantId(res.id)
}
try {
const res = await LoginApi.getTenantByWebsite(website)
if (res) {
loginData.loginForm.tenantName = res.name
authUtil.setTenantId(res.id)
}
} catch (e) { }
}
const loading = ref() // ElLoading.service 返回的实例
// 登录
@@ -268,12 +270,7 @@ const handleLogin = async (params) => {
} else {
push({ path: redirect.value || permissionStore.addRouters[0].path })
}
}
catch (e) {
loginLoading.value = false
loading.value?.close()
}
finally {
} finally {
loginLoading.value = false
loading.value?.close()
}

View File

@@ -14,7 +14,7 @@
<el-input v-model="formData.processInstanceKey" disabled placeholder="请输入流程标识" />
</el-form-item>
<el-form-item label="规则类型" prop="type">
<el-select v-model="formData.type" clearable style="width: 100%" disabled>
<el-select v-model="formData.type" clearable style="width: 100%">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_ASSIGN_RULE_TYPE)"
:key="dict.value"
@@ -165,7 +165,7 @@ const open = async (row) => {
resetForm()
// 2. 再设置表单
if (row != null) {
formData.value.type = 30
formData.value.type = undefined as unknown as number
formData.value.taskName = row.name
formData.value.taskId = row.id
formData.value.processInstanceName = row.processInstance.name

View File

@@ -41,7 +41,6 @@
<Icon icon="ep:close" />
不通过
</el-button>
<el-button type="primary" @click="openTaskUpdateAssigneeForm(item.id)">
<Icon icon="ep:edit" />
转办
@@ -50,12 +49,10 @@
<Icon icon="ep:position" />
委派
</el-button>
<!--
<el-button type="primary" @click="handleSign(item)">
<Icon icon="ep:plus" />
加签
</el-button>
-->
<el-button type="primary" @click="handleSign(item)">
<Icon icon="ep:plus" />
加签
</el-button>
<el-button type="warning" @click="handleBack(item)">
<Icon icon="ep:back" />
回退
@@ -176,8 +173,6 @@ const handleAudit = async (task, pass) => {
getDetail()
}
const printPage = async () => {
const { href } = router.resolve({ name: 'BpmProcessInstanceInfo',
@@ -236,10 +231,6 @@ const getProcessInstance = async () => {
if (processDefinition.formType === 10) {
detailForm.value.formId = processDefinition.formId
detailForm.value.optionsData = JSON.parse(processDefinition.formConf)
if (data.formVariables.jeelowcode_subtable_data) {
data.formVariables = { ...data.formVariables, ...data.formVariables.jeelowcode_subtable_data }
delete data.formVariables.jeelowcode_subtable_data
}
detailForm.value.defaultData = data.formVariables
// setConfAndFields2(
// detailForm,

View File

@@ -16,7 +16,7 @@
@current-change="currentChange"
>
<template #category="{ row }">
<dict-tag :type="DICT_TYPE.BPM_MODEL_CATEGORY" :value="row.category || ''"/>
<dict-tag :type="DICT_TYPE.BPM_MODEL_CATEGORY" :value="row.category || ''" />
</template>
<template #status="scope">
<dict-tag
@@ -38,9 +38,8 @@
/>
</template>
<template #menu-left>
<el-button type="primary" v-hasPermi="['bpm:process-instance:create']" @click="handleCreate">
<Icon icon="ep:plus" class="mr-5px"/>
发起流程
<el-button type="primary" v-hasPermi="['bpm:process-instance:query']" @click="handleCreate">
<Icon icon="ep:plus" class="mr-5px" /> 发起流程
</el-button>
</template>
<!-- 自定义操作栏 -->
@@ -48,34 +47,34 @@
<el-button
link
type="primary"
v-hasPermi="['bpm:process-instance:query']"
v-hasPermi="['bpm:process-instance:cancel']"
@click="handleDetail(row)"
>
详情
</el-button>
<el-button
<!-- <el-button
link
type="danger"
v-if="row.result === 1|| row.result === 2"
v-hasPermi="['bpm:process-instance:cancel']"
v-if="row.result === 1"
v-hasPermi="['bpm:process-instance:query']"
@click="handleCancel(row)"
>
取消
</el-button>
</el-button> -->
</template>
</avue-crud>
</ContentWrap>
</template>
<script lang="ts" setup>
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import {dateFormatter, getSearchDate} from '@/utils/formatTime'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter, getSearchDate } from '@/utils/formatTime'
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
defineOptions({name: 'BpmCCProcessInstance'})
defineOptions({ name: 'BpmCCProcessInstance' })
const router = useRouter() // 路由
const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化
const {getCurrPermi} = useCrudPermi()
const { t } = useI18n() // 国际化
const { getCurrPermi } = useCrudPermi()
const loading = ref(true) // 列表的加载中
const tableOption = reactive({
@@ -105,7 +104,7 @@ const tableOption = reactive({
type: 'select',
span: 12,
dicData: getIntDictOptions(DICT_TYPE.BPM_MODEL_CATEGORY),
rules: [{required: true, message: '流程分类不能为空', trigger: 'blur'}]
rules: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }]
},
tasks: {
label: '当前审批任务'
@@ -116,7 +115,7 @@ const tableOption = reactive({
type: 'select',
span: 12,
dicData: getIntDictOptions(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS),
rules: [{required: true, message: '状态不能为空', trigger: 'blur'}]
rules: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
},
result: {
label: '结果',
@@ -124,7 +123,7 @@ const tableOption = reactive({
type: 'select',
span: 12,
dicData: getIntDictOptions(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT),
rules: [{required: true, message: '结果不能为空', trigger: 'blur'}]
rules: [{ required: true, message: '结果不能为空', trigger: 'blur' }]
},
createTime: {
label: '提交时间',
@@ -204,8 +203,7 @@ const searchChange = (params, done) => {
/** 清空按钮操作 */
const resetChange = () => {
searchChange({}, () => {
})
searchChange({}, () => {})
}
const sizeChange = (pageSize) => {
@@ -220,7 +218,7 @@ const currentChange = (currentPage) => {
/** 取消按钮操作 */
const handleCancel = async (row) => {
// 二次确认
const {value} = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格

View File

@@ -1,175 +0,0 @@
<!-- 工作流抄送我的流程 -->
<template>
<ContentWrap>
<avue-crud
ref="crudRef"
v-model="tableForm"
v-model:page="tablePage"
v-model:search="tableSearch"
:data="tableData"
:option="tableOption"
:permission="permission"
@search-change="searchChange"
@search-reset="resetChange"
@refresh-change="getTableData"
@size-change="sizeChange"
@current-change="currentChange"
>
<template #menu="{ row }">
<el-button link type="primary" @click="handleAudit(row)">流程</el-button>
</template>
</avue-crud>
</ContentWrap>
</template>
<script lang="ts" setup>
import {dateFormatter} from '@/utils/formatTime'
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
defineOptions({
name: 'BpmCopyTask'
})
// 路由
const {push} = useRouter()
// 列表的加载中
const loading = ref(true)
const {getCurrPermi} = useCrudPermi()
// 表格的配置
const tableOption = reactive({
addBtn: false,
editBtn: false,
delBtn: false,
viewBtn: true,
viewBtnText: '详情',
viewBtnIcon: 'none',
align: 'center',
headerAlign: 'center',
searchMenuSpan: 6,
searchMenuPosition: 'left',
labelSuffix: ' ',
span: 24,
dialogWidth: '50%',
column: {
taskId: {
label: '任务编号'
},
taskName: {
label: '任务名称'
},
processInstanceId: {
label: '流程编号',
search: true,
},
processInstanceName: {
label: '所属流程',
search: true,
},
startUserNickname: {
label: '流程发起人',
},
reason: {
label: '抄送原因'
},
creatorNickname: {
label: '抄送人'
},
createTime: {
label: '抄送时间',
type: 'datetime',
width: 180,
formatter: (row: any, value: any, rowv: any, column: any) => {
return dateFormatter(row, column, value)
}
},
searchCreateTime: {
label: '抄送时间',
display: false,
hide: true,
search: true,
searchType: 'datetimerange',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
searchRange: true,
}
}
})
const tableForm = ref<any>({})
const tableData = ref([])
const tableSearch = ref<any>({})
const tablePage = ref({
currentPage: 1,
pageSize: 10,
total: 0
})
const permission = getCurrPermi(['bpm:task'])
const crudRef = ref()
useCrudHeight(crudRef)
const getTableData = async () => {
// 列表的加载中...
loading.value = true
// 拼接查询参数
let searchObj = {
...tableSearch.value,
pageNo: tablePage.value.currentPage,
pageSize: tablePage.value.pageSize
}
// 处理时间参数,如果为空则去掉这个属性
if (!searchObj.createTime?.length) delete searchObj.createTime
// 去掉空字符串属性
for (let key in searchObj) if (searchObj[key] === '') delete searchObj[key]
// 请求我的待阅数据
try {
const data = await ProcessInstanceApi.getProcessInstanceCCPage(searchObj)
tableData.value = data.list
tablePage.value.total = data.total
} finally {
// 无论请求成功或者失败,这里都需要将加载中关闭
loading.value = false
}
}
const searchChange = (params: any, done: any) => {
tablePage.value.currentPage = 1
// 获取数据
getTableData().finally(() => done())
}
const resetChange = () => {
searchChange({}, () => {
})
}
const sizeChange = (pageSize) => {
tablePage.value.pageSize = pageSize
resetChange()
}
const currentChange = (currentPage) => {
tablePage.value.currentPage = currentPage
getTableData()
}
const handleAudit = (row: any) => {
push({
name: 'BpmProcessInstanceDetail',
query: {
id: row.processInstanceId
}
})
}
/** 初始化 **/
onMounted(async () => {
await getTableData()
})
</script>

View File

@@ -26,7 +26,7 @@
</template>
<template #menu="{ row }">
<el-button link type="primary" @click="handleAudit(row)">审批</el-button>
<el-button link type="primary" @click="handleCC(row)">抄送</el-button>
<!-- <el-button link type="primary" @click="handleCC(row)">抄送</el-button>-->
</template>
</avue-crud>
<TaskCCDialogForm ref="taskCCDialogForm" />

View File

@@ -32,22 +32,22 @@
</ContentWrap>
</template>
<script lang="ts" setup>
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as TaskAssignRuleApi from '@/api/bpm/taskAssignRule'
import * as RoleApi from '@/api/system/role'
import * as PostApi from '@/api/system/post'
import * as UserGroupApi from '@/api/bpm/userGroup'
import {setUserAndDeptName} from '@/components/LowDesign/src/utils/getName'
import {useLowStoreWithOut} from '@/store/modules/low'
import { setUserAndDeptName } from '@/components/LowDesign/src/utils/getName'
import { useLowStoreWithOut } from '@/store/modules/low'
const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化
const {getCurrPermi} = useCrudPermi()
const { t } = useI18n() // 国际化
const { getCurrPermi } = useCrudPermi()
const lowStore = useLowStoreWithOut()
defineOptions({name: 'BpmTaskAssignRule'})
defineOptions({ name: 'BpmTaskAssignRule' })
const {query} = useRoute() // 查询参数
const { query } = useRoute() // 查询参数
const loading = ref(true)
const getRules = (label) => {
@@ -65,7 +65,6 @@ const getUserKey = (val) => {
else if ([20, 21].includes(val)) key = 'deptIds'
else if (val == 22) key = 'postIds'
else if ([30, 31, 32].includes(val)) key = 'userIds'
else if (val == 35) key = 'userSelects'
else if (val == 40) key = 'userGroupIds'
else if (val == 50) key = 'scripts'
return key
@@ -82,8 +81,8 @@ const tableOption = reactive({
delBtn: false,
calcHeight: 20,
column: {
taskDefinitionName: {label: '任务名', disabled: true},
taskDefinitionKey: {label: '任务标识', disabled: true},
taskDefinitionName: { label: '任务名', disabled: true },
taskDefinitionKey: { label: '任务标识', disabled: true },
type: {
label: '规则类型',
type: 'select',
@@ -91,13 +90,12 @@ const tableOption = reactive({
rules: getRules('规则类型'),
control: (val) => {
const columnObj = {
roleIds: {display: false},
deptIds: {display: false},
postIds: {display: false},
userIds: {display: false},
userGroupIds: {display: false},
scripts: {display: false},
userSelects: {display: false},
roleIds: { display: false },
deptIds: { display: false },
postIds: { display: false },
userIds: { display: false },
userGroupIds: { display: false },
scripts: { display: false }
}
const key = getUserKey(val)
if (key) columnObj[key].display = true
@@ -114,7 +112,6 @@ const tableOption = reactive({
let arr = row.options.map((id) => {
if (key == 'deptIds') return lowStore.dicObj.deptSelect?.[id] || id
else if (key == 'userIds') return lowStore.dicObj.userSelect?.[id] || id
else if (key == 'userSelects') return ''
else return dicObj.value[key][id]
})
@@ -201,7 +198,7 @@ const rowUpdate = async (form, index, done, loading) => {
const delKey = ['roleIds', 'deptIds', 'postIds', 'userIds', 'userGroupIds', 'scripts']
if (key) {
if (typeof form[key] == 'number') form[key] = form[key] + ''
const value = key === 'userSelects' ? '' : form[key]
const value = form[key]
form.options = typeof value == 'string' ? value.split(',') : value
}
delKey.forEach((prop) => delete form[prop])
@@ -231,14 +228,14 @@ const getDicData = () => {
const id = item.id + ''
const name = item.name
dicObj.value[key][id] = name
return {label: name, value: id}
return { label: name, value: id }
})
})
dicObj.value.scripts = {}
tableOption.column.scripts.dicData = getIntDictOptions(DICT_TYPE.BPM_TASK_ASSIGN_SCRIPT).map(
(item) => {
dicObj.value.scripts[item.value] = item.label
return {value: item.value + '', label: item.label}
return { value: item.value + '', label: item.label }
}
) as never[]
dicObj.value.type = {}
@@ -265,7 +262,7 @@ const formattingTableData = (data): Promise<any[]> => {
}
return item
})
await setUserAndDeptName({userIdList, deptIdList})
await setUserAndDeptName({ userIdList, deptIdList })
resolve(data)
})
}

View File

@@ -61,13 +61,6 @@ const tabsPaneList = ref([
calcHeight: 200,
fixedSearch: {file_main_type: 4}
},
{
label: '工作档案',
name: 'workArchive',
formId: '1966386366515343361',
calcHeight: 200,
fixedSearch: {file_main_type: 5}
},
])
// 定义点击tab的事件动作

View File

@@ -41,7 +41,7 @@
>
<template #menu-left="{ size }">
<el-button type="primary" :size="size" @click="menuLeftHandle('aiCreated')">
<Icon :size="14" icon="jam:magic-f"/>
<Icon :size="14" icon="jam:magic-f" />
<span class="ml-3px!">AI建表</span>
</el-button>
<el-button
@@ -51,12 +51,12 @@
@click="menuLeftHandle('btn')"
class="mr-10px"
>
<Icon :size="14" icon="teenyicons:button-outline"/>
<Icon :size="14" icon="teenyicons:button-outline" />
<span class="ml-3px!">自定义按钮</span>
</el-button>
<el-dropdown @command="menuLeftHandle" v-hasPermi="['jeelowcode:web']">
<el-button type="primary" :size="size">
<Icon :size="14" icon="teenyicons:webpack-outline"/>
<Icon :size="14" icon="teenyicons:webpack-outline" />
<span class="ml-3px!">前端增强</span>
</el-button>
<template #dropdown>
@@ -74,7 +74,7 @@
@click="menuLeftHandle('sql')"
v-hasPermi="['jeelowcode:sql']"
>
<Icon :size="14" icon="devicon-plain:sqldeveloper"/>
<Icon :size="14" icon="devicon-plain:sqldeveloper" />
<span class="ml-3px!">SQL增强</span>
</el-button>
<el-button
@@ -83,20 +83,9 @@
@click="menuLeftHandle('java')"
v-hasPermi="['jeelowcode:java']"
>
<Icon :size="14" icon="hugeicons:java"/>
<Icon :size="14" icon="hugeicons:java" />
<span class="ml-3px!">JAVA增强</span>
</el-button>
<!-- 批量同步 -->
<el-button
type="primary"
:size="size"
@click="handleBatchSync"
v-hasPermi="['jeelowcode:dbform:sync']"
>
<Icon :size="14" icon="simple-icons:oracle"/>
<span class="ml-3px!">批量同步</span>
</el-button>
</template>
<template #menu="{ size, row }">
<div class="flex justify-center flex-items-center">
@@ -118,7 +107,7 @@
<div class="mt--2px cursor-pointer">
<el-text :size="size" type="primary">
更多
<Icon :size="16" icon="iconamoon:arrow-down-2-light"/>
<Icon :size="16" icon="iconamoon:arrow-down-2-light" />
</el-text>
</div>
<template #dropdown>
@@ -201,8 +190,7 @@
@click="openDataOrigin"
:disabled="!tableForm.dataOrigin"
>
<Icon :size="14" icon="lucide:text-search"></Icon>
<span>数据源SQL配置</span>
<Icon :size="14" icon="lucide:text-search"></Icon> <span>数据源SQL配置</span>
</el-button>
<el-button
type="primary"
@@ -223,12 +211,10 @@
<span>表格扩展配置</span>
</el-button>
<el-button @click="sortPopup = true">
<Icon :size="14" icon="mdi:sort"></Icon>
<span>默认排序</span>
<Icon :size="14" icon="mdi:sort"></Icon> <span>默认排序</span>
</el-button>
<el-button @click="searchPopup = true">
<Icon :size="14" icon="lucide:text-search"></Icon>
<span>默认搜索</span>
<Icon :size="14" icon="lucide:text-search"></Icon> <span>默认搜索</span>
</el-button>
</div>
</template>
@@ -314,7 +300,7 @@
</template>
<template #optionCondition="{ row }">
<template v-for="item in row.optionCondition" :key="item.key">
<el-tag v-if="item.value !== 0" size="small"> {{ item.label }}{{ item.value }}</el-tag>
<el-tag v-if="item.value !== 0" size="small"> {{ item.label }}{{ item.value }} </el-tag>
</template>
</template>
</avue-crud>
@@ -431,8 +417,7 @@
size="small"
type="primary"
@click="copySampleStr(key)"
>点击复制
</el-button
>点击复制</el-button
>
</div>
</div>
@@ -477,32 +462,32 @@ import {
DataOriginOption,
AuthConfig
} from './components'
import {TipView} from '../general/components/index'
import { TipView } from '../general/components/index'
import * as TableApi from '@/api/design/table'
import * as JsApi from '@/api/design/table/jsEnhance'
import {dicObj, pageOption, tableInfoOption} from './designData'
import {scssEnhanceExample, controlInitExample} from '@/components/LowDesign/src/utils/example'
import {formattingLengStr} from '@/utils/lowDesign'
import { dicObj, pageOption, tableInfoOption } from './designData'
import { scssEnhanceExample, controlInitExample } from '@/components/LowDesign/src/utils/example'
import { formattingLengStr } from '@/utils/lowDesign'
import controlPath from '@/components/LowDesign/src/controlPath'
import useMEDialog from '@/hooks/design/useMEDialog'
import useCopyText from '@/hooks/design/useCopyText'
import {ElButton, ElLoading} from 'element-plus'
import {cloneDeep} from 'lodash-es'
import {useRenderVxeColumn} from '../general/components/useRenderVxeColumn'
import {useGroup} from '@/hooks/design/useGroup'
import {checkPermi} from '@/utils/permission'
import {ElMessage} from 'element-plus'
import { ElButton, ElLoading } from 'element-plus'
import { cloneDeep } from 'lodash-es'
import { useRenderVxeColumn } from '../general/components/useRenderVxeColumn'
import { useGroup } from '@/hooks/design/useGroup'
import { checkPermi } from '@/utils/permission'
import { ElMessage } from 'element-plus'
defineOptions({name: 'TableDesign'})
defineOptions({ name: 'TableDesign' })
const {MEDialog, MEData, openMEDialog} = useMEDialog()
const {copyText} = useCopyText()
const { MEDialog, MEData, openMEDialog } = useMEDialog()
const { copyText } = useCopyText()
useRenderVxeColumn()
const message = useMessage() // 消息弹窗
const router = useRouter() // 路由
const {t} = useI18n() // 国际化
const {getCurrPermi} = useCrudPermi()
const { t } = useI18n() // 国际化
const { getCurrPermi } = useCrudPermi()
const loading = ref(true) // 列表的加载中
const saveLoading = ref(false)
@@ -570,7 +555,7 @@ const authPopup = ref({
show: false,
vBind: {}
})
const aiCreatedObj = ref({popup: false, loading: false, describe: '', timer: null as any})
const aiCreatedObj = ref({ popup: false, loading: false, describe: '', timer: null as any })
const basicPopup = ref({
show: false,
@@ -595,9 +580,9 @@ const samplePopup = ref(false)
const permission = getCurrPermi(['jeelowcode:dbform'])
const tableConfigList = [
{label: '表格选择', prop: 'tableSelect', valClass: 'w-75px!'},
{label: '搜索样式', prop: 'searchStyle', valClass: 'w-100px!'},
{label: '操作栏样式', prop: 'operateMenuStyle', labelWidth: '90px', valClass: 'w-100px!'},
{ label: '表格选择', prop: 'tableSelect', valClass: 'w-75px!' },
{ label: '搜索样式', prop: 'searchStyle', valClass: 'w-100px!' },
{ label: '操作栏样式', prop: 'operateMenuStyle', labelWidth: '90px', valClass: 'w-100px!' },
{
label: '操作栏最大横排数',
prop: 'maxMenuNum',
@@ -613,7 +598,7 @@ const tableConfigList = [
showKey: 'tableType',
showVal: 1,
valClass: 'w-114px!',
changeFun: ({value}) => {
changeFun: ({ value }) => {
let dicData = cloneDeep(dicObj.tableConfig)
if (value == 'card') {
dicData = dicData.filter(
@@ -647,8 +632,8 @@ const tableConfigList = [
showVal: 'expand',
valClass: 'w-90px!'
},
{label: '树表样式', prop: 'treeStyle', showKey: 'tableType', showVal: 2},
{label: '树表模式', prop: 'treeMode', showKey: 'tableType', showVal: 2}
{ label: '树表样式', prop: 'treeStyle', showKey: 'tableType', showVal: 2 },
{ label: '树表模式', prop: 'treeMode', showKey: 'tableType', showVal: 2 }
]
const menuMoreList = [
@@ -657,14 +642,14 @@ const menuMoreList = [
type: 'sync',
isShow: (row) => row.isDbSync == 'N' && checkPermi(['jeelowcode:dbform:sync'])
},
{label: '功能测试', type: 'test'},
{label: '路由地址', type: 'address'},
{label: '接口地址', type: 'apiUrl'},
{label: '租户权限配置', type: 'auth'},
{label: '复制表', type: 'copy', isShow: () => checkPermi(['jeelowcode:dbform:create'])},
{label: 'js增强解锁', type: 'jsUnlock', isShow: () => checkPermi(['jeelowcode:web'])},
{label: 'scss增强解锁', type: 'scssUnlock', isShow: () => checkPermi(['jeelowcode:web'])},
{label: '删除', type: 'del', isShow: () => checkPermi(['jeelowcode:dbform:delete'])}
{ label: '功能测试', type: 'test' },
{ label: '路由地址', type: 'address' },
{ label: '接口地址', type: 'apiUrl' },
{ label: '租户权限配置', type: 'auth' },
{ label: '复制表', type: 'copy', isShow: () => checkPermi(['jeelowcode:dbform:create']) },
{ label: 'js增强解锁', type: 'jsUnlock', isShow: () => checkPermi(['jeelowcode:web']) },
{ label: 'scss增强解锁', type: 'scssUnlock', isShow: () => checkPermi(['jeelowcode:web']) },
{ label: '删除', type: 'del', isShow: () => checkPermi(['jeelowcode:dbform:delete']) }
]
useCrudHeight(crudRef)
@@ -762,8 +747,8 @@ const tableFormVerify = (type) => {
customFormRef.value.validate((bool, done, msg) => {
done()
if (!bool) return reject(msg)
const {tableName, tableType, tableClassify} = tableForm.value
const subTable = {bool: true, len: 0}
const { tableName, tableType, tableClassify } = tableForm.value
const subTable = { bool: true, len: 0 }
if (tableClassify == 2 && tableName && tableName.indexOf('view_') != 0) {
message.warning('视图表的表名请以 view_ 开头')
return reject('message')
@@ -828,7 +813,7 @@ const tableFormVerify = (type) => {
if (messageText) {
handleVerifyError(tabKey, item._X_ROW_KEY, index)
ElMessage({dangerouslyUseHTMLString: true, message: messageText})
ElMessage({ dangerouslyUseHTMLString: true, message: messageText })
errText = 'message'
break
}
@@ -861,7 +846,7 @@ const tableFormVerify = (type) => {
: ''
}
if (key == 'summaryList') {
const {sqlType, sqlValue} = item.summaryJson
const { sqlType, sqlValue } = item.summaryJson
itemObj.summaryType = 'bottom'
itemObj.summarySql = sqlType == 'custom' ? sqlValue : sqlType
itemObj.summaryJson = JSON.stringify(item.summaryJson)
@@ -942,7 +927,7 @@ const contrastEditData = (infoData) => {
for (const k in item) {
if (item[k] != contrastObj[k]) {
item.isModify = 'Y'
break
break
}
}
}
@@ -953,7 +938,7 @@ const contrastEditData = (infoData) => {
}
const setApiDetailData = (data) => {
apiDetailData.value = {delIdVo: {}}
apiDetailData.value = { delIdVo: {} }
for (const key in data) {
let listKey = key
if (['summaryBottomList', 'summaryTopList'].includes(listKey)) listKey = 'summaryList'
@@ -1005,9 +990,9 @@ const menuLeftHandle = (type) => {
if (aiCreatedObj.value.timer) clearInterval(aiCreatedObj.value.timer)
}
}
const menuHandle = async ({type, row, index}) => {
const menuHandle = async ({ type, row, index }) => {
if (type == 'edit') crudRef.value.rowEdit(row, index)
else if (type == 'test') router.push({path: '/low/table/test/' + row.id})
else if (type == 'test') router.push({ path: '/low/table/test/' + row.id })
else if (type == 'sync') syncDbTable(row)
else if (type == 'address') showAddress(row)
else if (type == 'apiUrl') showApiUrl(row)
@@ -1017,7 +1002,7 @@ const menuHandle = async ({type, row, index}) => {
else if (type == 'auth') {
authPopup.value = {
show: true,
vBind: {dbformId: row.id, tableName: row.tableName, tableDescribe: row.tableDescribe}
vBind: { dbformId: row.id, tableName: row.tableName, tableDescribe: row.tableDescribe }
}
}
}
@@ -1029,7 +1014,7 @@ const syncDbTable = (row) => {
title: '同步数据库',
width: '400px',
isCenter: true,
dialogParams: {alignCenter: true},
dialogParams: { alignCenter: true },
footerBtn: [
{
name: '取 消',
@@ -1038,7 +1023,7 @@ const syncDbTable = (row) => {
{
name: '确 定',
loading: true,
params: {type: 'primary'},
params: { type: 'primary' },
clickFun: async (done) => {
if (syncData.value.value == 'force') {
await message.prompt(
@@ -1101,7 +1086,7 @@ const showApiUrl = async (row) => {
value: `/jeelowcode/${isOpen ? 'open' : 'dbform-data'}/save/batch/${row.id}`,
tipText: '接口参数格式data:[ { 新增的数据... },{ ... } ]'
},
{label: '编辑数据[put]', value: `/jeelowcode/dbform-data/edit/${row.id}`},
{ label: '编辑数据[put]', value: `/jeelowcode/dbform-data/edit/${row.id}` },
{
label: '批量编辑数据[put]',
value: `/jeelowcode/dbform-data/edit/batch/${row.id}`,
@@ -1122,19 +1107,19 @@ const showApiUrl = async (row) => {
let list: VNode[] = []
apiList.forEach((item) => {
list.push(
h('div', {style: {marginBottom: '10px', border: ' 1px solid #eee', padding: '10px'}}, [
h('div', { style: { marginBottom: '10px', border: ' 1px solid #eee', padding: '10px' } }, [
h('div', [
h('span', {style: {fontWeight: 600, fontSize: '14px'}}, item.label + ''),
h('span', { style: { fontWeight: 600, fontSize: '14px' } }, item.label + ''),
h(
ElButton,
{size: 'small', type: 'primary', onClick: () => copyText(item.value)},
{ size: 'small', type: 'primary', onClick: () => copyText(item.value) },
() => '复制'
)
]),
h('div', {style: {fontSize: '12px'}}, item.value),
h('div', { style: { fontSize: '12px' } }, item.value),
h(
'div',
{style: {display: !!item.tipText, fontSize: '12px', color: '#E6A23C'}},
{ style: { display: !!item.tipText, fontSize: '12px', color: '#E6A23C' } },
item.tipText
)
])
@@ -1142,11 +1127,11 @@ const showApiUrl = async (row) => {
})
message.alert('', '接口地址', {
message: () => {
return h('div', {width: '360px'}, list)
return h('div', { width: '360px' }, list)
},
confirmButtonText: '关闭',
dangerouslyUseHTMLString: true,
customStyle: {width: '384px'}
customStyle: { width: '384px' }
})
}
const copyDbTable = (row) => {
@@ -1161,7 +1146,7 @@ const copyDbTable = (row) => {
if (!RExp.test(value)) return '表名只能使用小写字母、数字、下划线,并以字母开头'
}
})
.then(async ({value}) => {
.then(async ({ value }) => {
loading.value = true
const bool = await TableApi.verifyDbName(value)
if (bool) {
@@ -1184,7 +1169,7 @@ const unlockEnhance = (type, row) => {
const openWebEnhance = async (enhanceType) => {
loading.value = true
jsEnhanceData.value = {jsJson: ''}
jsEnhanceData.value = { jsJson: '' }
const dbformId = tableSelect.value[0].id
const detailData = await JsApi.getJsDetail({
dbformId,
@@ -1232,7 +1217,7 @@ const openWebEnhance = async (enhanceType) => {
},
footerBtn: [
{
params: {type: 'primary'},
params: { type: 'primary' },
name: '保 存',
icon: 'mingcute:save-line',
loading: true,
@@ -1243,7 +1228,7 @@ const openWebEnhance = async (enhanceType) => {
}
},
{
params: {type: 'success'},
params: { type: 'success' },
name: '保存并关闭',
icon: 'mingcute:save-line',
loading: true,
@@ -1272,11 +1257,11 @@ const openWebEnhance = async (enhanceType) => {
}
if (enhanceType == 'js') {
params['providerType'] = 'tableJsEnhance'
params['otherParams'] = {type: 'simple', width: '300px', tipKeyList: ['TableJsEnhance']}
params['otherParams'] = { type: 'simple', width: '300px', tipKeyList: ['TableJsEnhance'] }
params['language'] = 'javascript'
params['headerBtn'] = [
{
params: {type: 'success'},
params: { type: 'success' },
name: '控件使用示例',
icon: 'jam:code-sample',
clickFun: async () => (samplePopup.value = true)
@@ -1294,7 +1279,7 @@ const openWebEnhance = async (enhanceType) => {
}
}
openMEDialog({params, prop: 'jsJson'}, jsEnhanceData.value)
openMEDialog({ params, prop: 'jsJson' }, jsEnhanceData.value)
isUnload.value = true
}
const handleWebEnhance = (dbformId, enhanceType) => {
@@ -1316,16 +1301,16 @@ const handleWebEnhance = (dbformId, enhanceType) => {
})
}
const cellStyle = ({row, columnIndex}) => {
const cellStyle = ({ row, columnIndex }) => {
if (columnIndex == 6) {
return {color: row.isDbSync == 'Y' ? '#67C23A' : '#F56C6C'}
return { color: row.isDbSync == 'Y' ? '#67C23A' : '#F56C6C' }
}
if (columnIndex == 5) {
let color = ''
if (row.tableClassify == 1) color = '#409EFF'
else if (row.tableClassify == 2) color = '#909399'
else if (row.tableClassify == 3) color = '#E6A23C'
return {color}
return { color }
}
}
@@ -1342,7 +1327,7 @@ const radioClick = (row) => {
const setTreeLabelDicData = (dicData) => {
if (dicData.length == 0) {
dicData = [{label: '请先添加字段', value: 'low', disabled: true}]
dicData = [{ label: '请先添加字段', value: 'low', disabled: true }]
}
customFormRef.value.updateDic('treeLabelField', dicData)
}
@@ -1369,7 +1354,7 @@ const openDataOrigin = () => {
})
const filedData = [...tableInfoRef.value.infoData.basics, ...tableInfoRef.value.tableInfoDefault]
dataOriginPopup.value.viewField = filedData.map((item) => {
return {label: item.fieldName, value: item.fieldCode}
return { label: item.fieldName, value: item.fieldCode }
})
dataOriginPopup.value.show = true
}
@@ -1406,14 +1391,14 @@ const analysisDataOrigin = async () => {
return item
})
}
let {infoData} = tableInfoOption.formattingInitData(analysisData)
let { infoData } = tableInfoOption.formattingInitData(analysisData)
infoData = infoData.map((item) => {
for (const key in item) {
if (item[key] === null || item[key] === undefined || key == 'fieldList_id') {
delete item[key]
}
}
return {...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item}
return { ...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item }
})
setInfoBasics(infoData)
message.success('解析成功')
@@ -1437,11 +1422,11 @@ const getSqlFormConfig = async () => {
(item) => !tableInfoOption.disabledArr.includes(item.fieldCode) || item.fieldCode == 'pid'
)
fieldList = fieldList.map((item) => {
return {...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item}
return { ...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item }
})
setInfoBasics(fieldList)
message.success('生成成功')
let {tableName} = customFormOption.value.column
let { tableName } = customFormOption.value.column
tableName['disabled'] = true
})
.finally(() => (sqlFormLoading.value = false))
@@ -1472,7 +1457,7 @@ const handleAiCreatedTable = async () => {
(item) => !tableInfoOption.disabledArr.includes(item.fieldCode) || item.fieldCode == 'pid'
)
data.fieldModelList = data.fieldModelList.map((item) => {
return {...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item}
return { ...cloneDeep(tableInfoOption.infoDefaultData.basics), ...item }
})
aiCreatedObj.value.popup = false
crudRef.value.rowAdd()
@@ -1514,7 +1499,7 @@ const getTableData = async () => {
if (typeof item[key] == 'number') {
let val: number | string = item[key]
if (['jsCou', 'scssCou'].includes(key)) val = val > 0 ? '√' : val
item.optionCondition.push({label: couKey[key], value: val, key})
item.optionCondition.push({ label: couKey[key], value: val, key })
}
}
return item
@@ -1539,8 +1524,7 @@ const searchChange = (params, done) => {
/** 清空按钮操作 */
const resetChange = () => {
searchChange({}, () => {
})
searchChange({}, () => {})
}
const sizeChange = (pageSize) => {
@@ -1558,7 +1542,7 @@ const beforeOpen = async (done, type) => {
isTableInfo.value = false
const groupData = cloneDeep(treeData.value)
customFormOption.value.column.groupDbformId.dicData = groupData[0].children
const {tableName, subTableListStr} = customFormOption.value.column
const { tableName, subTableListStr } = customFormOption.value.column
if (['edit', 'view'].includes(type) && tableForm.value.id) {
loading.value = true
const data = await TableApi.getDbDetail(tableForm.value.id, ['all'])
@@ -1566,7 +1550,7 @@ const beforeOpen = async (done, type) => {
data.dbForm.tableConfig = data.dbForm.tableConfig?.split(',') || []
data.dbForm.dataConfig = data.dbForm.dataConfig?.split(',') || []
editInfoData.value = data
tableForm.value = {...data.dbForm}
tableForm.value = { ...data.dbForm }
tableName['disabled'] = true
tableName['rules'] = []
subTableListStr['display'] = tableForm.value.tableType == 3 && tableForm.value.subTableListStr
@@ -1601,7 +1585,7 @@ const beforeOpen = async (done, type) => {
searchStyle: 'default'
}
tableName['disabled'] = false
tableName['rules'] = [{validator: pageOption.tableName_required, trigger: 'blur'}] as any
tableName['rules'] = [{ validator: pageOption.tableName_required, trigger: 'blur' }] as any
subTableListStr['display'] = false
if (groupValue.value) tableForm.value.groupDbformId = groupValue.value
authValue.value = ''
@@ -1664,8 +1648,8 @@ const rowSave = async (formData, done, loading) => {
const form = handleApiFormData(formData)
tableFormVerify('add')
.then(async (infoData: object) => {
const elLoading = ElLoading.service({fullscreen: true})
let bool = await TableApi.saveDbData({dbForm: {...form}, ...infoData}).catch(() => false)
const elLoading = ElLoading.service({ fullscreen: true })
let bool = await TableApi.saveDbData({ dbForm: { ...form }, ...infoData }).catch(() => false)
if (bool) {
message.success(t('common.createSuccess'))
resetChange()
@@ -1678,7 +1662,7 @@ const rowSave = async (formData, done, loading) => {
let key = Object.keys(error)[0]
message.info(error[key][0].message)
} else if (error !== 'message') {
message.alert(error, '请修改', {dangerouslyUseHTMLString: true})
message.alert(error, '请修改', { dangerouslyUseHTMLString: true })
}
loading()
})
@@ -1696,7 +1680,7 @@ const rowUpdate = async (formData, index?, done?, loading?) => {
const form = handleApiFormData(formData)
tableFormVerify('edit')
.then(async (infoData: object) => {
let bool = await TableApi.updateDbData({dbForm: {...form}, ...infoData}).catch(
let bool = await TableApi.updateDbData({ dbForm: { ...form }, ...infoData }).catch(
() => false
)
if (bool) {
@@ -1718,7 +1702,7 @@ const rowUpdate = async (formData, index?, done?, loading?) => {
let key = Object.keys(error)[0]
message.info(error[key][0].message)
} else if (error !== 'message') {
message.alert(error, '请修改', {dangerouslyUseHTMLString: true})
message.alert(error, '请修改', { dangerouslyUseHTMLString: true })
}
loading()
})
@@ -1754,35 +1738,13 @@ const rowDel = async (form) => {
message.success(t('common.delSuccess'))
// 刷新列表
await getTableData()
} catch {
}
} catch {}
}
const beforeUnload = (event) => {
if (isUnload.value) return (event.returnValue = '您确定要关闭页面吗?')
}
/** 批量同步 **/
const handleBatchSync = async () => {
// 首先需要查询有没有需要同步的表单,如果没有则提示消息并结束,如果有则打开弹窗
let searchObj = {
isDbSync: 'N',
pageNo: tablePage.value.currentPage,
pageSize: -1
}
const data = await TableApi.getDbList(searchObj)
if (data?.records?.length > 0) {
// 将data.records取出来每个记录的id作为row.id并且发起普通同步
const promises = data.records.map((row) => TableApi.asyncDbData(row.id, 'default'))
await Promise.all(promises).catch(() => message.alert('同步失败'))
// 刷新列表
getTableData()
} else {
// 没有需要同步的表单,提示信息并结束方法
message.info('没有需要同步的表单')
}
}
/** 初始化 **/
onMounted(async () => {
window.addEventListener('beforeunload', beforeUnload)

View File

@@ -70,8 +70,7 @@
</div>
<div class="bottom-card">
<div class="bottom-card-title">
<!-- 隐患排查治理 标题需要隐藏 2025-10-31 -->
<span></span>
<span>隐患排查治理</span>
<img width="50%" style="margin: 8px 0" src="@/assets/images/line_1.png" />
</div>
<div class="type-wrapper">

View File

@@ -1,10 +1,9 @@
<template>
<div class="center-container">
<div class="center-content">
<!-- 隐患排查治理 这个标题需要隐藏 2025-10-31 -->
<span class="title"></span>
<span class="title">隐患排查治理</span>
<img class="bottom-border-line" src="@/assets/images/title_border_line_1.png" />
<span class="sub-title">隐患等级</span>
<span class="sub-title">分类风险</span>
<img width="50%" src="@/assets/images/line_1.png" />
<div class="type-wrapper">

View File

@@ -60,7 +60,6 @@ import RiskStatisticsPanel from './components/RiskStatisticsPanel.vue'
import HighRiskAlertPanel from './components/HighRiskAlertPanel.vue'
import TimeoutWorkOrderPanel from './components/TimeoutWorkOrderPanel.vue'
import HiddenDangerPanel from './components/HiddenDangerPanel.vue'
import {error} from "echarts/types/src/util/log";
// 类型定义
interface AlertItem {
@@ -485,16 +484,7 @@ const handleHiddenDangerPannelData = (query) => {
_data2.general = Number(res.records[0].general)
_data2.major = Number(res.records[0].major)
// 安全指数另算,再起一个报表
// dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
// 在这里添加获取安全指数的逻辑
getTableList('hidden_danger_safety_index', query).then(res => {
if (res.records && res.records.length > 0) {
dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
}
}).catch(error => {
console.error('获取隐患排查治理数据失败:', error)
})
dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
// 获取隐患排查治理处理进度数据
getTableList('hidden_danger_process_progress', query).then(res => {

View File

@@ -33,10 +33,9 @@
<div class="center-container">
<div class="center-content">
<!-- 隐患排查治理 -->
<span class="title"></span>
<span class="title">隐患排查治理</span>
<img class="bottom-border-line" src="@/assets/images/title_border_line_1.png" />
<span class="sub-title">隐患等级</span>
<span class="sub-title">分类风险</span>
<img width="50%" src="@/assets/images/line_1.png" />
<div class="type-wrapper">
<div class="type-item">

View File

@@ -60,8 +60,7 @@
</div>
<div class="bottom-card">
<div class="bottom-card-title">
<!--隐患排查治理-->
<span></span>
<span>隐患排查治理</span>
<img width="50%" style="margin: 8px 0" src="@/assets/images/line_1.png" />
</div>
<div class="type-wrapper">

View File

@@ -3,8 +3,7 @@
<!-- 顶部标题栏 -->
<div class="header-container">
<div class="header-left">
<img class="back-img" @click="returnToHeadquarters"
src="@/assets/images/screen/back_image.png"/>
<img class="back-img" @click="returnToHeadquarters" src="@/assets/images/screen/back_image.png" />
<div class="back-button" @click="openRegionSelector"> {{ selectedRegion }}
<span>···</span>
</div>
@@ -17,44 +16,39 @@
</div>
</div>
<!-- 天气预报 -->
<WeatherWarning/>
<WeatherWarning />
<!-- 主内容区 -->
<div class="content-container">
<div class="left-wrapper">
<OverviewPanel :totalCount="dashboardData?.totalCount || 0"
:formalEmployeeCount="dashboardData?.formalEmployeeCount || 0"
:externalStaffCount="dashboardData?.externalStaffCount || 0"
:visitorCount="dashboardData?.visitorCount || 0"
:parkStatistics="dashboardData?.parkStatistics"/>
<RiskStatisticsPanel :riskStatistics="riskStatistics" :dangerDetail="dangerDetail"
:park="parkValue"
@tab-change="handleRiskTabChange" :campus_id="query.campus_id"/>
:formalEmployeeCount="dashboardData?.formalEmployeeCount || 0"
:externalStaffCount="dashboardData?.externalStaffCount || 0" :visitorCount="dashboardData?.visitorCount || 0"
:parkStatistics="dashboardData?.parkStatistics" />
<RiskStatisticsPanel :riskStatistics="riskStatistics" :dangerDetail="dangerDetail" :park="parkValue"
@tab-change="handleRiskTabChange" :campus_id="query.campus_id" />
</div>
<div class="right-wrapper">
<HighRiskAlertPanel :alertData="dashboardData?.alertData"
:alertDetails="dashboardData?.alertData.details"
:sourceIndex="sourceIndex"/>
<HighRiskAlertPanel :alertData="dashboardData?.alertData" :alertDetails="dashboardData?.alertData.details"
:sourceIndex="sourceIndex" />
<TimeoutWorkOrderPanel :timeoutWorkOrders="dashboardData?.timeoutWorkOrders"
:alertDetails="dashboardData?.timeoutWorkOrders.details"
:sourceIndex="sourceIndex"/>
:alertDetails="dashboardData?.timeoutWorkOrders.details" :sourceIndex="sourceIndex" />
</div>
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData"/>
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData" />
</div>
</div>
<!-- 区域选择弹窗 -->
<RegionSelector v-model="regionSelectorVisible" :modelSelected="selectedPark"
:regions="regionOption"
@change="onRegionChange"/>
<RegionSelector v-model="regionSelectorVisible" :modelSelected="selectedPark" :regions="regionOption"
@change="onRegionChange" />
</template>
<script setup lang="ts">
import {getTableList, getTableData} from './report'
import {ref, onMounted, watch, onUnmounted} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import { getTableList, getTableData } from './report'
import { ref, onMounted, watch, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import RegionSelector from './components/RegionSelector.vue'
import WeatherWarning from './components/WeatherWarning.vue'
import {getDashboardData, getAlertDetails, type DashboardData} from '@/api/dashboard'
import { getDashboardData, getAlertDetails, type DashboardData } from '@/api/dashboard'
import OverviewPanel from './components/OverviewPanel.vue'
import RiskStatisticsPanel from './components/RiskStatisticsPanel.vue'
@@ -231,7 +225,7 @@ onMounted(async () => {
}
try {
let {records} = await getTableList(
let { records } = await getTableList(
'park_info_list'
)
// records = [
@@ -258,9 +252,7 @@ onMounted(async () => {
// 去重region字段使用Map来确保唯一性
const regionMap = new Map()
records.filter((el) => el.region_id == query.regionCode)
.map(el => {
return el
})
.map(el => { return el })
.forEach(el => {
if (!regionMap.has(el.park_name)) {
regionMap.set(el.park_name, {
@@ -488,16 +480,7 @@ const handleHiddenDangerPannelData = (query) => {
_data2.general = Number(res.records[0].general)
_data2.major = Number(res.records[0].major)
// 安全指数另算,再起一个报表
// dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
// 在这里添加获取安全指数的逻辑
getTableList('hidden_danger_safety_index', query).then(res => {
if (res.records && res.records.length > 0) {
dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
}
}).catch(error => {
console.error('获取隐患排查治理数据失败:', error)
})
dashboardData.value.hiddenDangerData.safetyIndex = res.records[0].safetyIndex
// 获取隐患排查治理处理进度数据
getTableList('hidden_danger_process_progress', query).then(res => {
@@ -588,7 +571,7 @@ const handleRiskTabChange = async (tab: TabType) => {
// 根据不同的tab请求不同的接口
getTableList(
code,
{...query, activeTab: tab}
{ ...query, activeTab: tab }
).then(response => {
// 更新风险统计数据 - 传递完整的数组数据用于饼图显示
if (response.records && response.records.length > 0) {
@@ -637,7 +620,7 @@ const handleRiskTabChange = async (tab: TabType) => {
// 根据不同的tab请求不同的接口
getTableList(
code,
{...query, activeTab: tab}
{ ...query, activeTab: tab }
).then(response => {
// 更新风险统计数据 - 传递完整的数组数据用于饼图显示
if (response.records && response.records.length > 0) {
@@ -667,7 +650,7 @@ const onRegionChange = (item: RegionItem): void => {
parkValue.value = item.code
router.push({
path: '/screen/company',
query: {parkName: item.name, parkCode: item.code}
query: { parkName: item.name, parkCode: item.code }
})
}
@@ -1236,20 +1219,23 @@ const timeOut1 = (): void => {
.left-top {
padding: 0 5px;
background-image: url('@/assets/images/screen/left_top_img.png'),
url('@/assets/images/screen/left_center_img.png'),
url('@/assets/images/screen/left_bottom_img.png');
background-position: top center,
left center,
bottom center;
background-image:
url('@/assets/images/screen/left_top_img.png'),
url('@/assets/images/screen/left_center_img.png'),
url('@/assets/images/screen/left_bottom_img.png');
background-position:
top center,
left center,
bottom center;
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
background-repeat: no-repeat, no-repeat, no-repeat;
/* 设置位置 */
background-size: 100% 90px,
cover,
100% 68px;
background-size:
100% 90px,
cover,
100% 68px;
flex: 1;
/* 设置重复方式 */
@@ -1410,20 +1396,23 @@ const timeOut1 = (): void => {
}
.left-bottom {
background-image: url('@/assets/images/screen/left_top_2_img.png'),
url('@/assets/images/screen/left_center_img.png'),
url('@/assets/images/screen/left_bottom_img.png');
background-position: top center,
left center,
bottom center;
background-image:
url('@/assets/images/screen/left_top_2_img.png'),
url('@/assets/images/screen/left_center_img.png'),
url('@/assets/images/screen/left_bottom_img.png');
background-position:
top center,
left center,
bottom center;
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
background-repeat: no-repeat, no-repeat, no-repeat;
/* 设置位置 */
background-size: 100% 90px,
cover,
100% 68px;
background-size:
100% 90px,
cover,
100% 68px;
flex: 1;
/* 设置重复方式 */
@@ -1473,6 +1462,8 @@ const timeOut1 = (): void => {
row-gap: 1rem;
}
.center-container {