Compare commits
No commits in common. "345b51130fcdfa75e04d3560744a43c7af60b198" and "119cf4d5608b57174a25d1ad0a95f0e04154cbb3" have entirely different histories.
345b51130f
...
119cf4d560
|
@ -2,7 +2,7 @@
|
||||||
VITE_USE_MOCK = true
|
VITE_USE_MOCK = true
|
||||||
|
|
||||||
# 发布路径
|
# 发布路径
|
||||||
VITE_PUBLIC_PATH = /nu
|
VITE_PUBLIC_PATH = /
|
||||||
|
|
||||||
|
|
||||||
# 跨域代理,您可以配置多个 ,请注意,没有换行符
|
# 跨域代理,您可以配置多个 ,请注意,没有换行符
|
||||||
|
|
|
@ -1,789 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="p-2 base-class">
|
|
||||||
<a-card @click="toggleSearchStatus = true" :class="{ 'base-con-class': toggleSearchStatus == false }">
|
|
||||||
<a-row v-show="!toggleSearchStatus && !orgSelectedCon">
|
|
||||||
<a-col :span="10">
|
|
||||||
<span style="font-size: 15px;font-weight: bold;color: #333;">机构信息:</span>
|
|
||||||
<span v-if="!orgData" class="base-info-dn" style="color: red;"> 请先选择机构</span>
|
|
||||||
<template v-else>
|
|
||||||
<span class="base-info-dn"
|
|
||||||
style="margin-left: 10px;font-size: 15px;font-weight: 400;color: #333;"> {{
|
|
||||||
orgData?.departName }}</span>
|
|
||||||
<a-button type="primary" size="small" @click.stop="handleResetOrg" style="margin-left: 10px;">
|
|
||||||
<span class="base-info-dn">重新选择</span>
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="5">
|
|
||||||
<span v-if="hasSearchConditions" style="font-size: 16px;font-weight: bold;color:#E86A6A">
|
|
||||||
有筛选条件未重置
|
|
||||||
</span>
|
|
||||||
<span style="font-size: 16px;font-weight: bold;color:#ABACAD">点击展开更多操作区域</span>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
<div class="org-info-card" v-show="(!toggleSearchStatus && orgSelectedCon) || toggleSearchStatus">
|
|
||||||
<div class="org-info-header">
|
|
||||||
<div class="org-title">
|
|
||||||
<span class="base-info-label">机构信息:</span>
|
|
||||||
<span v-if="!orgData" class="base-info-dn" style="color: #ff4d4f;"> 请先选择机构</span>
|
|
||||||
<span v-else class="org-name">{{ orgData?.departName }}</span>
|
|
||||||
</div>
|
|
||||||
<a-button v-if="!orgSelectedCon" class="reset-btn" type="primary" @click.stop="handleResetOrg">
|
|
||||||
<span>重新选择</span>
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="org-info-content">
|
|
||||||
<div class="info-row">
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">机构编码:</span>
|
|
||||||
<span class="value">{{ orgData?.orgCode || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">运营时间:</span>
|
|
||||||
<span class="value">
|
|
||||||
{{ orgData?.operationStartTime?.substring(0, 10) || '-' }} 至
|
|
||||||
{{ orgData?.operationEndTime?.substring(0, 10) || '-' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">合同时间:</span>
|
|
||||||
<span class="value">
|
|
||||||
{{ orgData?.contractStartTime?.substring(0, 10) || '-' }} 至
|
|
||||||
{{ orgData?.contractEndTime?.substring(0, 10) || '-' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-row">
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">电话:</span>
|
|
||||||
<span class="value">{{ orgData?.mobile || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">传真:</span>
|
|
||||||
<span class="value">{{ orgData?.fax || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">地址:</span>
|
|
||||||
<span class="value">{{ orgData?.address || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a-divider v-show="toggleSearchStatus && orgData && !orgSelectedCon" style="margin: 0px;margin-top: 8px;" />
|
|
||||||
<a-col :span="24" v-show="toggleSearchStatus && orgData && !orgSelectedCon">
|
|
||||||
<div class="jeecg-basic-table-form-container">
|
|
||||||
<slot name="searchFormSlot"></slot>
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
<div class="p-2 con-class" style="margin-top: -10px;">
|
|
||||||
<a-card>
|
|
||||||
<a-card v-show="orgSelectedCon" :bordered="false" class="org-container">
|
|
||||||
<a-row :gutter="[16, 16]">
|
|
||||||
<a-col :span="8" v-for="org in orgTable" :key="org.id">
|
|
||||||
<div class="org-card" :class="{ 'active': org.id == orgData?.id }"
|
|
||||||
@click="handleOrgSelected(org)">
|
|
||||||
<div class="org-header">
|
|
||||||
<a-tag color="blue" v-if="org.id == orgData?.id">当前选择</a-tag>
|
|
||||||
<h3 class="org-title">{{ org.departName }}</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a-descriptions size="default" :column="2" bordered>
|
|
||||||
<a-descriptions-item label="机构编码">{{ org.orgCode || '-' }}</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="运营时间">
|
|
||||||
{{ org.operationStartTime?.substring(0, 10) || '-' }} 至
|
|
||||||
{{ org.operationEndTime?.substring(0, 10) || '-' }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="电话">
|
|
||||||
<div class="contact-line">
|
|
||||||
<span><phone-outlined /> {{ org.mobile || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="传真">
|
|
||||||
<div class="contact-line">
|
|
||||||
<span><printer-outlined /> {{ org.fax || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="地址">
|
|
||||||
<ellipsis :length="26" tooltip>{{ org.address || '-' }}</ellipsis>
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-card>
|
|
||||||
<a-card v-show="orgSelectedCon && (!orgTable || orgTable?.length == 0)">
|
|
||||||
<a-empty description="暂无数据" :image="simpleImage" />
|
|
||||||
</a-card>
|
|
||||||
<div class="tab-header-container" v-show="!orgSelectedCon">
|
|
||||||
<a-tabs v-model:activeKey="tabActiveKey" class="tabs-container">
|
|
||||||
<a-tab-pane key="dataAsync" tab="数据同步">
|
|
||||||
<a-card>
|
|
||||||
<a-row>
|
|
||||||
<a-col :span="sourceScreenSpan">
|
|
||||||
<div style="height: 16px;margin-left: 15px;">
|
|
||||||
<a-tag color="#87d068">源数据</a-tag>
|
|
||||||
<a-radio-group v-model:value="viewType" size="small" style="margin-left: 10px;"
|
|
||||||
@change="emit('viewTypeChanged', viewType)">
|
|
||||||
<a-radio-button value="all">全部</a-radio-button>
|
|
||||||
<a-radio-button value="selected">已选择</a-radio-button>
|
|
||||||
<a-radio-button value="unselected">未选择</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
<slot name="sourceTableSlot"></slot>
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="selectedScreenSpan">
|
|
||||||
<div style="height: 31px;margin-left: 4px;">
|
|
||||||
<a-tag color="#2db7f5">
|
|
||||||
已选择
|
|
||||||
<span style="font-size: 13px;font-weight: bold;">
|
|
||||||
{{ ' ' + selectedSize + ' ' }}
|
|
||||||
</span>条
|
|
||||||
</a-tag>
|
|
||||||
</div>
|
|
||||||
<a-card size="small" :bordered="false" class="selected-list-container">
|
|
||||||
<slot name="businessTableSlot">111</slot>
|
|
||||||
</a-card>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-card>
|
|
||||||
</a-tab-pane>
|
|
||||||
<a-tab-pane key="asyncHistory" tab="同步历史">
|
|
||||||
<AsyncListComponent ref="asyncHistoryRef"></AsyncListComponent>
|
|
||||||
</a-tab-pane>
|
|
||||||
</a-tabs>
|
|
||||||
<div class="toggle-button-container">
|
|
||||||
<a-button type="primary" size="small" @click.stop="refreshHistory()" style="margin-right: 10px;"
|
|
||||||
v-show="tabActiveKey == 'asyncHistory'">
|
|
||||||
<span>刷新</span>
|
|
||||||
</a-button>
|
|
||||||
<a-button type="warning" size="small" @click.stop="handleAsync()"
|
|
||||||
style="margin-left: 5px;margin-right: 5px;" v-show="tabActiveKey == 'dataAsync'">
|
|
||||||
<span>同步数据</span>
|
|
||||||
</a-button>
|
|
||||||
<a-divider type="vertical" style="background-color: #CDCDCF" />
|
|
||||||
<a-button type="primary" size="small" @click="handleSelectAll" v-show="tabActiveKey == 'dataAsync'"
|
|
||||||
style="margin-left: 8px">全部添加</a-button>
|
|
||||||
<a-divider type="vertical" style="background-color: #CDCDCF" v-show="tabActiveKey == 'dataAsync'" />
|
|
||||||
<a-button type="error" size="small" @click="handleRemoveAll" v-show="tabActiveKey == 'dataAsync'"
|
|
||||||
style="margin-left: 8px">全部移除</a-button>
|
|
||||||
<a-divider type="vertical" style="background-color: #CDCDCF" v-show="tabActiveKey == 'dataAsync'" />
|
|
||||||
<a-button type="primary" size="small" @click.stop="handleRestore"
|
|
||||||
v-show="tabActiveKey == 'dataAsync'" style="margin-left: 8px">
|
|
||||||
<span>还原数据</span>
|
|
||||||
</a-button>
|
|
||||||
<a-divider type="vertical" style="background-color: #CDCDCF" v-show="tabActiveKey == 'dataAsync'" />
|
|
||||||
<a-radio-group v-model:value="splitVal" button-style="solid" size="small"
|
|
||||||
@change="splitScreenChanged" style="margin-left: 5px;margin-right: 5px;"
|
|
||||||
v-show="tabActiveKey == 'dataAsync'">
|
|
||||||
<a-radio-button value="sc">源数据</a-radio-button>
|
|
||||||
<a-radio-button value="sc2sed1">分屏1</a-radio-button>
|
|
||||||
<a-radio-button value="sc1sed1">分屏2</a-radio-button>
|
|
||||||
<a-radio-button value="sc1sed2">分屏3</a-radio-button>
|
|
||||||
<a-radio-button value="sed">已选择</a-radio-button>
|
|
||||||
</a-radio-group>
|
|
||||||
<a-divider type="vertical" style="background-color: #CDCDCF" v-show="tabActiveKey == 'dataAsync'" />
|
|
||||||
<a @click="toggleSearchStatus = !toggleSearchStatus" class="toggle-button"
|
|
||||||
style="margin-left: 5px;margin-right: 5px;">
|
|
||||||
{{ toggleSearchStatus ? '拉伸' : '压缩' }}
|
|
||||||
<Icon
|
|
||||||
:icon="toggleSearchStatus ? 'humbleicons:align-objects-top' : 'humbleicons:align-objects-bottom'" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a-modal v-model:visible="showVideoModal" title="视频播放" :footer="null" @cancel="closeVideoModal"
|
|
||||||
:bodyStyle="{ padding: '0', maxHeight: '80vh', overflow: 'auto' }">
|
|
||||||
<video controls style="width: 100%; max-height: '70vh'; display: block; margin: 0 auto;">
|
|
||||||
<source :src="videoUrl">
|
|
||||||
您的浏览器不支持视频播放。
|
|
||||||
</video>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" name="synchronization-directive" setup>
|
|
||||||
import { ref, onMounted, computed, onBeforeMount, reactive } from 'vue';
|
|
||||||
import { initDictOptions } from '/@/utils/dict';
|
|
||||||
|
|
||||||
import { queryDepartTreeSync } from '/@/api/common/api';
|
|
||||||
import { Empty } from 'ant-design-vue';
|
|
||||||
import { Modal } from 'ant-design-vue';
|
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
|
||||||
import AsyncListComponent from '@/components/dataAsync/AsyncMainList.vue'
|
|
||||||
import { number } from 'vue-types';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
selectedSize: 0
|
|
||||||
});
|
|
||||||
const emit = defineEmits(['changeShowJMCom', 'viewTypeChanged', 'sourceOrgCodeChanged', 'orgChanged']);
|
|
||||||
|
|
||||||
interface OrganizationData {
|
|
||||||
id?: string;
|
|
||||||
departName: string;
|
|
||||||
orgCode: string;
|
|
||||||
operationStartTime?: string;
|
|
||||||
operationEndTime?: string;
|
|
||||||
contractStartTime?: string;
|
|
||||||
contractEndTime?: string;
|
|
||||||
mobile?: string;
|
|
||||||
fax?: string;
|
|
||||||
address?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
const dictData = await initDictOptions('org_code')
|
|
||||||
emit('sourceOrgCodeChanged', dictData.filter(d => d.text == 'shi_yan_tian')[0].value)
|
|
||||||
emit('changeShowJMCom', true)
|
|
||||||
})
|
|
||||||
const initialDataIds = ref<Array<string | number>>([]);
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
|
|
||||||
const toggleSearchStatus = ref<boolean>(true);
|
|
||||||
const splitVal = ref<string>('sc1sed1');
|
|
||||||
const sourceScreenSpan = ref(12);
|
|
||||||
const selectedScreenSpan = ref(12);
|
|
||||||
const orgTable = ref<OrganizationData[]>([]);
|
|
||||||
const orgData = ref<OrganizationData | null>(null);
|
|
||||||
const showVideoModal = ref(false);
|
|
||||||
const videoUrl = ref('');
|
|
||||||
const selectedItems = ref(new Map<string | number, any>());
|
|
||||||
const listComRef = ref();
|
|
||||||
const orgSelectedCon = ref(true)
|
|
||||||
const tabActiveKey = ref('dataAsync')
|
|
||||||
const asyncHistoryRef = ref(null)
|
|
||||||
|
|
||||||
const splitScreenChanged = (val) => {
|
|
||||||
let v_ = val.target.value;
|
|
||||||
if (v_ == 'sc') {
|
|
||||||
sourceScreenSpan.value = 24;
|
|
||||||
selectedScreenSpan.value = 0;
|
|
||||||
}
|
|
||||||
if (v_ == 'sc2sed1') {
|
|
||||||
sourceScreenSpan.value = 16;
|
|
||||||
selectedScreenSpan.value = 8;
|
|
||||||
}
|
|
||||||
if (v_ == 'sc1sed1') {
|
|
||||||
sourceScreenSpan.value = 12;
|
|
||||||
selectedScreenSpan.value = 12;
|
|
||||||
}
|
|
||||||
if (v_ == 'sc1sed2') {
|
|
||||||
sourceScreenSpan.value = 8;
|
|
||||||
selectedScreenSpan.value = 16;
|
|
||||||
}
|
|
||||||
if (v_ == 'sed') {
|
|
||||||
sourceScreenSpan.value = 0;
|
|
||||||
selectedScreenSpan.value = 24;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeVideoModal = () => {
|
|
||||||
showVideoModal.value = false;
|
|
||||||
videoUrl.value = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOrgSelected = async (org) => {
|
|
||||||
if (!!orgData.value && orgData.value.id != org.id) {
|
|
||||||
Modal.confirm({
|
|
||||||
title: '变更机构提醒',
|
|
||||||
content: '是否变更机构!',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: async () => {
|
|
||||||
await loadOrgData(org);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
await loadOrgData(org);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadOrgData = async (org) => {
|
|
||||||
// 更新机构数据
|
|
||||||
orgData.value = org;
|
|
||||||
|
|
||||||
emit('orgChanged', org)
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const handleResetOrg = () => {
|
|
||||||
orgSelectedCon.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetOrgSelectedCon = (v_) => {
|
|
||||||
orgSelectedCon.value = v_
|
|
||||||
}
|
|
||||||
|
|
||||||
//数据同步
|
|
||||||
const handleAsync = () => {
|
|
||||||
Modal.confirm({
|
|
||||||
title: '数据同步',
|
|
||||||
content: '是否确认同步',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: async () => {
|
|
||||||
let idStr = Array.from(selectedItems.value.keys()).join(',')
|
|
||||||
if (!idStr) {
|
|
||||||
createMessage.warning("未选择数据!");
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let izInc = true
|
|
||||||
if (!!orgData.value?.operationStartTime) izInc = new Date() >= new Date(orgData.value?.operationStartTime)
|
|
||||||
let params = {
|
|
||||||
orgCode: orgData.value?.orgCode,
|
|
||||||
izInc,
|
|
||||||
idStr
|
|
||||||
}
|
|
||||||
await asyncFunc(params)
|
|
||||||
|
|
||||||
//处理右侧列表数据移除是否可用 如果已到运营时间则禁用
|
|
||||||
if (!orgData.value?.operationStartTime || new Date() >= new Date(orgData.value?.operationStartTime)) {
|
|
||||||
// 获取当前同步的ID数组
|
|
||||||
const syncedIds = Array.from(selectedItems.value.keys());
|
|
||||||
// 只添加initialDataIds中不存在的ID
|
|
||||||
syncedIds.forEach(id => {
|
|
||||||
if (!initialDataIds.value.includes(id)) {
|
|
||||||
initialDataIds.value.push(id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//刷新历史数据
|
|
||||||
refreshHistory()
|
|
||||||
createMessage.success("同步结果请在同步历史中查看!");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//刷新同步历史数据
|
|
||||||
const refreshHistory = () => {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//源数据查询参数
|
|
||||||
const viewType = ref('all')
|
|
||||||
|
|
||||||
// 全部选择功能
|
|
||||||
const handleSelectAll = async () => {
|
|
||||||
// if (!orgData.value) {
|
|
||||||
// createMessage.warning("请先选择机构");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// // 调用子组件的方法获取所有数据(不分页)
|
|
||||||
// const allData = await listComRef.value?.getAllData?.(queryParam.value);
|
|
||||||
|
|
||||||
// if (allData && allData.length > 0) {
|
|
||||||
// // 过滤掉已经存在的项
|
|
||||||
// const newItems = allData.filter(item => !selectedItems.value.has(item.id));
|
|
||||||
|
|
||||||
// if (newItems.length === 0) {
|
|
||||||
// createMessage.info("没有新的数据可以添加");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 添加新项到已选择列表
|
|
||||||
// newItems.forEach(item => {
|
|
||||||
// selectedItems.value.set(item.id, item);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // 更新子组件的选中状态
|
|
||||||
// listComRef.value?.updateSelection?.(Array.from(selectedItems.value.values()));
|
|
||||||
|
|
||||||
// createMessage.success(`已添加 ${newItems.length} 条数据`);
|
|
||||||
// } else {
|
|
||||||
// createMessage.info("没有查询到数据");
|
|
||||||
// }
|
|
||||||
// } catch (error) {
|
|
||||||
// createMessage.error("获取全部数据失败");
|
|
||||||
// console.error("获取全部数据失败:", error);
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
// 全部移除功能
|
|
||||||
const handleRemoveAll = () => {
|
|
||||||
if (selectedItems.value.size === 0) {
|
|
||||||
createMessage.info("当前没有已选数据");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Modal.confirm({
|
|
||||||
title: '确认移除',
|
|
||||||
content: '确定要移除所有已选数据吗?',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: () => {
|
|
||||||
// 清空已选择的数据
|
|
||||||
if (!orgData.value?.operationStartTime || new Date() >= new Date(orgData.value?.operationStartTime)) {
|
|
||||||
// 创建新的Map只保留初始数据
|
|
||||||
const newSelectedItems = new Map();
|
|
||||||
// 遍历当前选择项,只保留初始数据
|
|
||||||
selectedItems.value.forEach((value, key) => {
|
|
||||||
if (initialDataIds.value.includes(key)) {
|
|
||||||
newSelectedItems.set(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
selectedItems.value = newSelectedItems;
|
|
||||||
listComRef.value?.updateSelection?.(Array.from(newSelectedItems.values()));
|
|
||||||
} else {
|
|
||||||
selectedItems.value.clear();
|
|
||||||
listComRef.value?.updateSelection?.([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
createMessage.success("已移除所有已选数据");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 还原功能
|
|
||||||
const handleRestore = async () => {
|
|
||||||
if (!orgData.value) {
|
|
||||||
createMessage.warning("请先选择机构");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Modal.confirm({
|
|
||||||
title: '确认还原',
|
|
||||||
content: '确定要将已选数据还原为机构初始状态吗?',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: async () => {
|
|
||||||
try {
|
|
||||||
// 调用子组件方法重新加载数据
|
|
||||||
await loadOrgData(orgData.value);
|
|
||||||
createMessage.success("已成功还原数据");
|
|
||||||
} catch (error) {
|
|
||||||
console.error("还原数据失败:", error);
|
|
||||||
createMessage.error("还原数据失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 计算当前搜索条件的函数
|
|
||||||
const hasSearchConditions = computed(() => {
|
|
||||||
return true
|
|
||||||
// return Object.keys(queryParam.value).some(key =>
|
|
||||||
// key !== 'viewType' && queryParam.value[key] !== undefined && queryParam.value[key] !== ''
|
|
||||||
// );
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
queryDepartTreeSync({ platType: 'ywjg' }).then(res => {
|
|
||||||
orgTable.value = res;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
orgData,
|
|
||||||
resetOrgSelectedCon
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.base-con-class {
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-list-container {
|
|
||||||
height: calc(100vh - 350px);
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
:deep(.ant-table) {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 新增的机构卡片样式 */
|
|
||||||
.org-cards-container {
|
|
||||||
max-height: 75vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-card {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: translateY(-4px);
|
|
||||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
|
|
||||||
background: radial-gradient(circle at center, #c7e6ff 0%, #d4eeff 70%, #e4f0ff 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-card-head) {
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
padding: 0 16px;
|
|
||||||
min-height: 48px;
|
|
||||||
|
|
||||||
.ant-card-head-title {
|
|
||||||
padding: 12px 0;
|
|
||||||
font-weight: 500;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-info-item {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.4;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #666;
|
|
||||||
min-width: 70px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
color: #333;
|
|
||||||
word-break: break-word;
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
&.address-text {
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
position: relative;
|
|
||||||
border: 1px solid #1890ff;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: 8px;
|
|
||||||
bottom: 8px;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
background: url("@/assets/icons/success.svg") no-repeat center;
|
|
||||||
background-size: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-header-container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs-container {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
:deep(.ant-tabs-content) {
|
|
||||||
height: calc(100% - 40px); // 减去tab标题高度
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-button-container {
|
|
||||||
position: absolute;
|
|
||||||
right: 16px;
|
|
||||||
top: 8px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-button {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
color: rgba(0, 0, 0, 0.65);
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.con-class {
|
|
||||||
:deep(.ant-card .ant-card-body) {
|
|
||||||
// padding-left: 10px !important;
|
|
||||||
// padding-right: 10px !important;
|
|
||||||
// padding-bottom: 0px !important;
|
|
||||||
// padding-bottom: 0px !important;
|
|
||||||
padding: 3px 10px 3px 10px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.base-class {
|
|
||||||
:deep(.ant-card .ant-card-body) {
|
|
||||||
padding-top: 10px !important;
|
|
||||||
padding-bottom: 10px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.con-class {
|
|
||||||
:deep(.css-dev-only-do-not-override-9m98ij .ant-table-wrapper .ant-table-pagination.ant-pagination) {
|
|
||||||
margin: 10px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-info-card {
|
|
||||||
background: linear-gradient(135deg, #f8f9fa 0%, #d0eaff 100%);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
|
|
||||||
border: 1px solid #e8e8e8;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
// &:hover {
|
|
||||||
// box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
||||||
// transform: translateY(-1px);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-info-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.base-info-label {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #595959;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-name {
|
|
||||||
margin-left: 10px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #262626;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.reset-btn {
|
|
||||||
background-color: #1890ff;
|
|
||||||
border-color: #1890ff;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
// &:hover {
|
|
||||||
// background-color: #40a9ff;
|
|
||||||
// border-color: #40a9ff;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-info-content {
|
|
||||||
.info-row {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-item {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 8px;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: #8c8c8c;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
color: #262626;
|
|
||||||
font-size: 13px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-container {
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
.org-card {
|
|
||||||
padding: 16px;
|
|
||||||
border: 1px solid #f0f0f0;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
background: white;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-color: #1890ff;
|
|
||||||
box-shadow: 0 2px 12px rgba(24, 144, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
border: 1px solid #1890ff;
|
|
||||||
background: #f0f8ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.org-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
|
|
||||||
.org-title {
|
|
||||||
margin: 0 0 0 8px;
|
|
||||||
font-size: 16px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.contact-line {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
>span {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.anticon {
|
|
||||||
margin-right: 4px;
|
|
||||||
color: #8c8c8c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-descriptions) {
|
|
||||||
.ant-descriptions-item-label {
|
|
||||||
width: 80px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,37 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="media-detail">
|
|
||||||
<a-descriptions bordered :column="1">
|
|
||||||
<a-descriptions-item label="资源名称">{{ record.name }}</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="文件类型">{{ record.fileType }}</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="备注">{{ record.descr || '无' }}</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="预览">
|
|
||||||
<PreviewComponent
|
|
||||||
:file-type="record.fileType"
|
|
||||||
:file-path="record.filePath"
|
|
||||||
/>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="创建时间">{{ record.createTime }}</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="更新时间">{{ record.updateTime }}</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { defineProps } from 'vue';
|
|
||||||
import PreviewComponent from './PreviewPickerComponent.vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
record: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const { record } = props;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.media-detail {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,72 +0,0 @@
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
|
||||||
|
|
||||||
const { createConfirm } = useMessage();
|
|
||||||
|
|
||||||
enum Api {
|
|
||||||
list = '/mediamanage/mediaManage/list',
|
|
||||||
save='/mediamanage/mediaManage/add',
|
|
||||||
edit='/mediamanage/mediaManage/edit',
|
|
||||||
deleteOne = '/mediamanage/mediaManage/delete',
|
|
||||||
deleteBatch = '/mediamanage/mediaManage/deleteBatch',
|
|
||||||
importExcel = '/mediamanage/mediaManage/importExcel',
|
|
||||||
exportXls = '/mediamanage/mediaManage/exportXls',
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出api
|
|
||||||
* @param params
|
|
||||||
*/
|
|
||||||
export const getExportUrl = Api.exportXls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入api
|
|
||||||
*/
|
|
||||||
export const getImportUrl = Api.importExcel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列表接口
|
|
||||||
* @param params
|
|
||||||
*/
|
|
||||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除单个
|
|
||||||
* @param params
|
|
||||||
* @param handleSuccess
|
|
||||||
*/
|
|
||||||
export const deleteOne = (params,handleSuccess) => {
|
|
||||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
|
||||||
handleSuccess();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除
|
|
||||||
* @param params
|
|
||||||
* @param handleSuccess
|
|
||||||
*/
|
|
||||||
export const batchDelete = (params, handleSuccess) => {
|
|
||||||
createConfirm({
|
|
||||||
iconType: 'warning',
|
|
||||||
title: '确认删除',
|
|
||||||
content: '是否删除选中数据',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: () => {
|
|
||||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
|
||||||
handleSuccess();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存或者更新
|
|
||||||
* @param params
|
|
||||||
* @param isUpdate
|
|
||||||
*/
|
|
||||||
export const saveOrUpdate = (params, isUpdate) => {
|
|
||||||
let url = isUpdate ? Api.edit : Api.save;
|
|
||||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
|
||||||
}
|
|
|
@ -1,234 +0,0 @@
|
||||||
<template>
|
|
||||||
<a-modal
|
|
||||||
:visible="visible"
|
|
||||||
:width="1000"
|
|
||||||
:title="title"
|
|
||||||
:footer="null"
|
|
||||||
@cancel="handleCancel"
|
|
||||||
>
|
|
||||||
<div class="resource-picker-container">
|
|
||||||
<!-- 搜索区域 -->
|
|
||||||
<div class="search-area">
|
|
||||||
<a-form layout="inline" :model="searchParams">
|
|
||||||
<a-form-item label="资源名称">
|
|
||||||
<a-input v-model:value="searchParams.name" placeholder="请输入资源名称" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="文件类型">
|
|
||||||
<j-dict-select-tag
|
|
||||||
v-model:value="searchParams.fileType"
|
|
||||||
dictCode="file_type"
|
|
||||||
placeholder="请选择文件类型"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
|
||||||
<a-button style="margin-left: 8px" @click="resetSearch">重置</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 表格区域 -->
|
|
||||||
<div class="table-area">
|
|
||||||
<a-table
|
|
||||||
:columns="columns"
|
|
||||||
:data-source="dataSource"
|
|
||||||
:pagination="pagination"
|
|
||||||
:loading="loading"
|
|
||||||
rowKey="id"
|
|
||||||
@change="handleTableChange"
|
|
||||||
:row-selection="{ selectedRowKeys, onChange: onSelectChange }"
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.key === 'filePath'">
|
|
||||||
<PreviewComponent
|
|
||||||
:file-type="record.fileType"
|
|
||||||
:file-path="record.filePath"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.key === 'action'">
|
|
||||||
<a-button type="link" @click="handleViewDetail(record)">详情</a-button>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
|
||||||
<div class="footer-area">
|
|
||||||
<a-button @click="handleCancel">取消</a-button>
|
|
||||||
<a-button type="primary" @click="handleConfirm" :disabled="!selectedRowKeys.length" style="margin-left: 8px">
|
|
||||||
确定
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 详情弹窗 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:visible="detailVisible"
|
|
||||||
:title="detailTitle"
|
|
||||||
:width="800"
|
|
||||||
:footer="null"
|
|
||||||
>
|
|
||||||
<MediaDetail :record="currentRecord" />
|
|
||||||
</a-modal>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, reactive, defineProps, defineEmits, watch } from 'vue';
|
|
||||||
import { list } from './MediaManagePicker.api';
|
|
||||||
import PreviewComponent from './PreviewComponent.vue';
|
|
||||||
import MediaDetail from './MediaDetail.vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: '选择媒体资源'
|
|
||||||
},
|
|
||||||
multiple: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:visible', 'confirm']);
|
|
||||||
|
|
||||||
const visible = ref(props.visible);
|
|
||||||
const loading = ref(false);
|
|
||||||
const dataSource = ref([]);
|
|
||||||
const selectedRowKeys = ref([]);
|
|
||||||
const selectedRows = ref([]);
|
|
||||||
const detailVisible = ref(false);
|
|
||||||
const currentRecord = ref({});
|
|
||||||
const detailTitle = ref('资源详情');
|
|
||||||
|
|
||||||
const searchParams = reactive({
|
|
||||||
name: '',
|
|
||||||
fileType: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const pagination = reactive({
|
|
||||||
current: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
showSizeChanger: true,
|
|
||||||
showQuickJumper: true,
|
|
||||||
pageSizeOptions: ['10', '20', '30', '50'],
|
|
||||||
showTotal: total => `共 ${total} 条`
|
|
||||||
});
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: '资源名称',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '文件类型',
|
|
||||||
dataIndex: 'fileType',
|
|
||||||
key: 'fileType'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '预览',
|
|
||||||
key: 'filePath'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// 监听visible变化
|
|
||||||
watch(() => props.visible, (val) => {
|
|
||||||
visible.value = val;
|
|
||||||
if (val) {
|
|
||||||
fetchData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取数据
|
|
||||||
const fetchData = async () => {
|
|
||||||
try {
|
|
||||||
loading.value = true;
|
|
||||||
const params = {
|
|
||||||
...searchParams,
|
|
||||||
pageNo: pagination.current,
|
|
||||||
pageSize: pagination.pageSize
|
|
||||||
};
|
|
||||||
const res = await list(params);
|
|
||||||
dataSource.value = res.records || [];
|
|
||||||
pagination.total = res.total || 0;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取数据失败:', error);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表格变化
|
|
||||||
const handleTableChange = (pag, filters, sorter) => {
|
|
||||||
pagination.current = pag.current;
|
|
||||||
pagination.pageSize = pag.pageSize;
|
|
||||||
fetchData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 搜索
|
|
||||||
const handleSearch = () => {
|
|
||||||
pagination.current = 1;
|
|
||||||
fetchData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置搜索
|
|
||||||
const resetSearch = () => {
|
|
||||||
searchParams.name = '';
|
|
||||||
searchParams.fileType = '';
|
|
||||||
handleSearch();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 选择变化
|
|
||||||
const onSelectChange = (selectedKeys, selectedRows) => {
|
|
||||||
selectedRowKeys.value = selectedKeys;
|
|
||||||
selectedRows.value = selectedRows;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查看详情
|
|
||||||
const handleViewDetail = (record) => {
|
|
||||||
currentRecord.value = record;
|
|
||||||
detailTitle.value = `资源详情 - ${record.name}`;
|
|
||||||
detailVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 确认选择
|
|
||||||
const handleConfirm = () => {
|
|
||||||
emit('confirm', props.multiple ? selectedRows.value : selectedRows.value[0]);
|
|
||||||
handleCancel();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消
|
|
||||||
const handleCancel = () => {
|
|
||||||
selectedRowKeys.value = [];
|
|
||||||
selectedRows.value = [];
|
|
||||||
emit('update:visible', false);
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
fetchData
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.resource-picker-container {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
.search-area {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
.footer-area {
|
|
||||||
margin-top: 16px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="preview-container">
|
|
||||||
<!-- 图片预览 -->
|
|
||||||
<div v-if="fileType === 'image' && filePath" class="preview-item">
|
|
||||||
<a-image :width="200" :src="getFullPath(filePath)" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 视频预览 -->
|
|
||||||
<div v-if="fileType === 'video' && filePath" class="preview-item">
|
|
||||||
<video controls :src="getFullPath(filePath)" style="width: 200px; height: auto;"></video>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 音频预览 -->
|
|
||||||
<div v-if="fileType === 'audio' && filePath" class="preview-item">
|
|
||||||
<audio controls :src="getFullPath(filePath)"></audio>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 文档预览 -->
|
|
||||||
<div v-if="fileType === 'document' && filePath" class="preview-item">
|
|
||||||
<a-button @click="handlePreviewDocument">预览文档</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, watch } from 'vue';
|
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
fileType: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
filePath: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const getFullPath = (path) => {
|
|
||||||
return getFileAccessHttpUrl(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePreviewDocument = () => {
|
|
||||||
window.open(getFullPath(props.filePath), '_blank');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.preview-container {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,72 +0,0 @@
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
|
||||||
|
|
||||||
const { createConfirm } = useMessage();
|
|
||||||
|
|
||||||
enum Api {
|
|
||||||
list = '/mediamanage/mediaManage/list',
|
|
||||||
save='/mediamanage/mediaManage/add',
|
|
||||||
edit='/mediamanage/mediaManage/edit',
|
|
||||||
deleteOne = '/mediamanage/mediaManage/delete',
|
|
||||||
deleteBatch = '/mediamanage/mediaManage/deleteBatch',
|
|
||||||
importExcel = '/mediamanage/mediaManage/importExcel',
|
|
||||||
exportXls = '/mediamanage/mediaManage/exportXls',
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出api
|
|
||||||
* @param params
|
|
||||||
*/
|
|
||||||
export const getExportUrl = Api.exportXls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导入api
|
|
||||||
*/
|
|
||||||
export const getImportUrl = Api.importExcel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列表接口
|
|
||||||
* @param params
|
|
||||||
*/
|
|
||||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除单个
|
|
||||||
* @param params
|
|
||||||
* @param handleSuccess
|
|
||||||
*/
|
|
||||||
export const deleteOne = (params,handleSuccess) => {
|
|
||||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
|
||||||
handleSuccess();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除
|
|
||||||
* @param params
|
|
||||||
* @param handleSuccess
|
|
||||||
*/
|
|
||||||
export const batchDelete = (params, handleSuccess) => {
|
|
||||||
createConfirm({
|
|
||||||
iconType: 'warning',
|
|
||||||
title: '确认删除',
|
|
||||||
content: '是否删除选中数据',
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
onOk: () => {
|
|
||||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
|
||||||
handleSuccess();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存或者更新
|
|
||||||
* @param params
|
|
||||||
* @param isUpdate
|
|
||||||
*/
|
|
||||||
export const saveOrUpdate = (params, isUpdate) => {
|
|
||||||
let url = isUpdate ? Api.edit : Api.save;
|
|
||||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
import {BasicColumn} from '/@/components/Table';
|
|
||||||
import {FormSchema} from '/@/components/Table';
|
|
||||||
import { rules} from '/@/utils/helper/validator';
|
|
||||||
import { render } from '/@/utils/common/renderUtils';
|
|
||||||
import { getWeekMonthQuarterYear } from '/@/utils';
|
|
||||||
//列表数据
|
|
||||||
export const columns: BasicColumn[] = [
|
|
||||||
{
|
|
||||||
title: '名称',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '备注',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'descr'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '文件类型',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'fileType_dictText'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '文件预览',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'filePath'
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 高级查询数据
|
|
||||||
export const superQuerySchema = {
|
|
||||||
name: {title: '名称',order: 0,view: 'text', type: 'string',},
|
|
||||||
descr: {title: '备注',order: 1,view: 'textarea', type: 'string',},
|
|
||||||
fileType: {title: '文件类型',order: 2,view: 'text', type: 'string',},
|
|
||||||
filePath: {title: '文件预览',order: 3,view: 'text', type: 'string',},
|
|
||||||
};
|
|
|
@ -1,264 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="p-2">
|
|
||||||
<!--查询区域-->
|
|
||||||
<div class="jeecg-basic-table-form-container">
|
|
||||||
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol"
|
|
||||||
:wrapper-col="wrapperCol">
|
|
||||||
<a-row :gutter="24">
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="name">
|
|
||||||
<template #label><span title="名称">名称</span></template>
|
|
||||||
<JInput v-model:value="queryParam.name" placeholder="请输入名称"/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="fileType">
|
|
||||||
<template #label><span title="文件类型">文件类型</span></template>
|
|
||||||
<j-dict-select-tag type='list' v-model:value="queryParam.fileType" dictCode="file_type"
|
|
||||||
placeholder="请选择文件类型" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
|
||||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
|
|
||||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset"
|
|
||||||
style="margin-left: 8px">重置</a-button>
|
|
||||||
</a-col>
|
|
||||||
</span>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
<!--引用表格-->
|
|
||||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
|
||||||
<!--插槽:table标题-->
|
|
||||||
<template #tableTitle>
|
|
||||||
<a-button type="primary" v-auth="'mediamanage:nu_media_manage:add'" @click="handleAdd"
|
|
||||||
preIcon="ant-design:plus-outlined"> 新增</a-button>
|
|
||||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu>
|
|
||||||
<a-menu-item key="1" @click="batchHandleDelete">
|
|
||||||
<Icon icon="ant-design:delete-outlined"></Icon>
|
|
||||||
删除
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
<a-button v-auth="'mediamanage:nu_media_manage:deleteBatch'">批量操作
|
|
||||||
<Icon icon="mdi:chevron-down"></Icon>
|
|
||||||
</a-button>
|
|
||||||
</a-dropdown>
|
|
||||||
</template>
|
|
||||||
<!--操作栏-->
|
|
||||||
<template #action="{ record }">
|
|
||||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
|
||||||
</template>
|
|
||||||
<template v-slot:bodyCell="{ column, record, index, text }">
|
|
||||||
</template>
|
|
||||||
</BasicTable>
|
|
||||||
<!-- 表单区域 -->
|
|
||||||
<MediaManageModal ref="registerModal" @success="handleSuccess"></MediaManageModal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" name="mediamanage-mediaManage" setup>
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
|
||||||
import { columns, superQuerySchema } from './MediaManage.data';
|
|
||||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './MediaManage.api';
|
|
||||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
|
||||||
import MediaManageModal from './components/MediaManageModal.vue'
|
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
|
||||||
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
|
||||||
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
|
|
||||||
|
|
||||||
const formRef = ref();
|
|
||||||
const queryParam = reactive<any>({});
|
|
||||||
const toggleSearchStatus = ref<boolean>(false);
|
|
||||||
const registerModal = ref();
|
|
||||||
const userStore = useUserStore();
|
|
||||||
//注册table数据
|
|
||||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
|
||||||
tableProps: {
|
|
||||||
title: '媒体资源管理',
|
|
||||||
api: list,
|
|
||||||
columns,
|
|
||||||
canResize: false,
|
|
||||||
useSearchForm: false,
|
|
||||||
actionColumn: {
|
|
||||||
width: 150,
|
|
||||||
fixed: 'right',
|
|
||||||
},
|
|
||||||
beforeFetch: async (params) => {
|
|
||||||
return Object.assign(params, queryParam);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
exportConfig: {
|
|
||||||
name: "媒体资源管理",
|
|
||||||
url: getExportUrl,
|
|
||||||
params: queryParam,
|
|
||||||
},
|
|
||||||
importConfig: {
|
|
||||||
url: getImportUrl,
|
|
||||||
success: handleSuccess
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
|
||||||
const labelCol = reactive({
|
|
||||||
xs: 24,
|
|
||||||
sm: 4,
|
|
||||||
xl: 6,
|
|
||||||
xxl: 4
|
|
||||||
});
|
|
||||||
const wrapperCol = reactive({
|
|
||||||
xs: 24,
|
|
||||||
sm: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 高级查询配置
|
|
||||||
const superQueryConfig = reactive(superQuerySchema);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 高级查询事件
|
|
||||||
*/
|
|
||||||
function handleSuperQuery(params) {
|
|
||||||
Object.keys(params).map((k) => {
|
|
||||||
queryParam[k] = params[k];
|
|
||||||
});
|
|
||||||
searchQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增事件
|
|
||||||
*/
|
|
||||||
function handleAdd() {
|
|
||||||
registerModal.value.disableSubmit = false;
|
|
||||||
registerModal.value.add();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑事件
|
|
||||||
*/
|
|
||||||
function handleEdit(record: Recordable) {
|
|
||||||
registerModal.value.disableSubmit = false;
|
|
||||||
registerModal.value.edit(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 详情
|
|
||||||
*/
|
|
||||||
function handleDetail(record: Recordable) {
|
|
||||||
registerModal.value.disableSubmit = true;
|
|
||||||
registerModal.value.edit(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除事件
|
|
||||||
*/
|
|
||||||
async function handleDelete(record) {
|
|
||||||
await deleteOne({ id: record.id }, handleSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除事件
|
|
||||||
*/
|
|
||||||
async function batchHandleDelete() {
|
|
||||||
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 成功回调
|
|
||||||
*/
|
|
||||||
function handleSuccess() {
|
|
||||||
(selectedRowKeys.value = []) && reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作栏
|
|
||||||
*/
|
|
||||||
function getTableAction(record) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: '编辑',
|
|
||||||
onClick: handleEdit.bind(null, record),
|
|
||||||
auth: 'mediamanage:nu_media_manage:edit'
|
|
||||||
}, {
|
|
||||||
label: '详情',
|
|
||||||
onClick: handleDetail.bind(null, record),
|
|
||||||
}, {
|
|
||||||
label: '删除',
|
|
||||||
popConfirm: {
|
|
||||||
title: '是否确认删除',
|
|
||||||
confirm: handleDelete.bind(null, record),
|
|
||||||
placement: 'topLeft',
|
|
||||||
},
|
|
||||||
auth: 'mediamanage:nu_media_manage:delete'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下拉操作栏
|
|
||||||
*/
|
|
||||||
function getDropDownAction(record) {
|
|
||||||
return [
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询
|
|
||||||
*/
|
|
||||||
function searchQuery() {
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置
|
|
||||||
*/
|
|
||||||
function searchReset() {
|
|
||||||
formRef.value.resetFields();
|
|
||||||
selectedRowKeys.value = [];
|
|
||||||
//刷新数据
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.jeecg-basic-table-form-container {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.table-page-search-submitButtons {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-group-cust {
|
|
||||||
min-width: 100px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-group-split-cust {
|
|
||||||
width: 30px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-form-item:not(.ant-form-item-with-help) {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-picker),
|
|
||||||
:deep(.ant-input-number) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,237 +0,0 @@
|
||||||
<template>
|
|
||||||
<a-spin :spinning="confirmLoading">
|
|
||||||
<JFormContainer :disabled="disabled">
|
|
||||||
<template #detail>
|
|
||||||
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"
|
|
||||||
name="MediaManageForm">
|
|
||||||
<a-row>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="名称" v-bind="validateInfos.name" id="MediaManageForm-name" name="name">
|
|
||||||
<a-input v-model:value="formData.name" placeholder="请输入名称" allow-clear></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="备注" v-bind="validateInfos.descr" id="MediaManageForm-descr" name="descr">
|
|
||||||
<a-textarea v-model:value="formData.descr" :rows="4" placeholder="请输入备注" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="文件类型" v-bind="validateInfos.fileType" id="MediaManageForm-fileType" name="fileType">
|
|
||||||
<j-dict-select-tag type='list' v-model:value="formData.fileType" dictCode="file_type"
|
|
||||||
placeholder="请选择文件类型" allowClear @change="handleFileTypeChange" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="文件上传" v-bind="validateInfos.filePath" id="MediaManageForm-filePath">
|
|
||||||
<!-- 未选择文件类型时的提示 -->
|
|
||||||
<div v-if="!formData.fileType" class="upload-tip">
|
|
||||||
<span style="color: red; line-height: 32px;">请先选择文件类型</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图片上传组件 -->
|
|
||||||
<j-image-upload v-if="formData.fileType === 'image'" v-model:value="formData.filePath" :number="1"
|
|
||||||
multiple="1" :fileSize="10" accept=".png,.jpg,.jpeg" @change="handleFileChange">
|
|
||||||
</j-image-upload>
|
|
||||||
|
|
||||||
<!-- 视频上传组件 -->
|
|
||||||
<template v-if="formData.fileType === 'video'">
|
|
||||||
<j-upload v-model:value="formData.filePath" :fileSize="100" :multiple="false" :maxCount="1"
|
|
||||||
accept=".mp4" @change="handleFileChange">
|
|
||||||
</j-upload>
|
|
||||||
<!-- 视频预览 -->
|
|
||||||
<div v-if="formData.filePath" class="media-preview">
|
|
||||||
<video controls style="max-width: 100%; max-height: 300px;">
|
|
||||||
<source :src="getFileAccessHttpUrl(formData.filePath)" type="video/mp4">
|
|
||||||
您的浏览器不支持视频播放
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 音频上传组件 -->
|
|
||||||
<template v-if="formData.fileType === 'audio'">
|
|
||||||
<j-upload v-model:value="formData.filePath" :fileSize="50" :multiple="false" :maxCount="1"
|
|
||||||
accept=".mp3" @change="handleFileChange">
|
|
||||||
</j-upload>
|
|
||||||
<!-- 音频预览 -->
|
|
||||||
<div v-if="formData.filePath" class="media-preview">
|
|
||||||
<audio controls style="width: 100%;">
|
|
||||||
<source :src="getFileAccessHttpUrl(formData.filePath)" type="audio/mpeg">
|
|
||||||
您的浏览器不支持音频播放
|
|
||||||
</audio>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 文档上传组件 -->
|
|
||||||
<j-upload v-if="formData.fileType === 'document'" v-model:value="formData.filePath" :fileSize="20"
|
|
||||||
:multiple="false" :maxCount="1" accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt"
|
|
||||||
@change="handleFileChange">
|
|
||||||
</j-upload>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</template>
|
|
||||||
</JFormContainer>
|
|
||||||
</a-spin>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, reactive, defineExpose, nextTick, defineProps, computed } from 'vue';
|
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
|
||||||
import { getValueType } from '/@/utils';
|
|
||||||
import { saveOrUpdate } from '../MediaManage.api';
|
|
||||||
import { Form } from 'ant-design-vue';
|
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
|
||||||
import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue';
|
|
||||||
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
|
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
formDisabled: { type: Boolean, default: false },
|
|
||||||
formData: { type: Object, default: () => ({}) },
|
|
||||||
formBpm: { type: Boolean, default: true }
|
|
||||||
});
|
|
||||||
const formRef = ref();
|
|
||||||
const useForm = Form.useForm;
|
|
||||||
const emit = defineEmits(['register', 'ok']);
|
|
||||||
const formData = reactive<Record<string, any>>({
|
|
||||||
id: '',
|
|
||||||
name: '',
|
|
||||||
descr: '',
|
|
||||||
fileType: '',
|
|
||||||
filePath: '',
|
|
||||||
});
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
|
|
||||||
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } });
|
|
||||||
const confirmLoading = ref<boolean>(false);
|
|
||||||
//表单验证
|
|
||||||
const validatorRules = reactive({
|
|
||||||
fileType: [{ required: true, message: '请输入文件类型!' },],
|
|
||||||
filePath: [{ required: true, message: '请输入文件预览!' },],
|
|
||||||
});
|
|
||||||
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
|
|
||||||
|
|
||||||
// 文件类型变化处理
|
|
||||||
const handleFileTypeChange = () => {
|
|
||||||
// 切换文件类型时清空已上传的文件
|
|
||||||
formData.filePath = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 文件上传变化处理
|
|
||||||
const handleFileChange = (value) => {
|
|
||||||
formData.filePath = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表单禁用
|
|
||||||
const disabled = computed(() => {
|
|
||||||
if (props.formBpm === true) {
|
|
||||||
if (props.formData.disabled === false) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.formDisabled;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
*/
|
|
||||||
function add() {
|
|
||||||
edit({});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑
|
|
||||||
*/
|
|
||||||
function edit(record) {
|
|
||||||
nextTick(() => {
|
|
||||||
resetFields();
|
|
||||||
const tmpData = {};
|
|
||||||
Object.keys(formData).forEach((key) => {
|
|
||||||
if (record.hasOwnProperty(key)) {
|
|
||||||
tmpData[key] = record[key]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
//赋值
|
|
||||||
Object.assign(formData, tmpData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交数据
|
|
||||||
*/
|
|
||||||
async function submitForm() {
|
|
||||||
try {
|
|
||||||
// 触发表单验证
|
|
||||||
await validate();
|
|
||||||
} catch ({ errorFields }) {
|
|
||||||
if (errorFields) {
|
|
||||||
const firstField = errorFields[0];
|
|
||||||
if (firstField) {
|
|
||||||
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Promise.reject(errorFields);
|
|
||||||
}
|
|
||||||
confirmLoading.value = true;
|
|
||||||
const isUpdate = ref<boolean>(false);
|
|
||||||
//时间格式化
|
|
||||||
let model = formData;
|
|
||||||
if (model.id) {
|
|
||||||
isUpdate.value = true;
|
|
||||||
}
|
|
||||||
//循环数据
|
|
||||||
for (let data in model) {
|
|
||||||
//如果该数据是数组并且是字符串类型
|
|
||||||
if (model[data] instanceof Array) {
|
|
||||||
let valueType = getValueType(formRef.value.getProps, data);
|
|
||||||
//如果是字符串类型的需要变成以逗号分割的字符串
|
|
||||||
if (valueType === 'string') {
|
|
||||||
model[data] = model[data].join(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await saveOrUpdate(model, isUpdate.value)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
createMessage.success(res.message);
|
|
||||||
emit('ok');
|
|
||||||
} else {
|
|
||||||
createMessage.warning(res.message);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
confirmLoading.value = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
add,
|
|
||||||
edit,
|
|
||||||
submitForm,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.antd-modal-form {
|
|
||||||
padding: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upload-tip {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-preview {
|
|
||||||
margin-top: 16px;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px dashed #d9d9d9;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,77 +0,0 @@
|
||||||
<template>
|
|
||||||
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
|
||||||
<MediaManageForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></MediaManageForm>
|
|
||||||
</j-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, nextTick, defineExpose } from 'vue';
|
|
||||||
import MediaManageForm from './MediaManageForm.vue'
|
|
||||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
|
||||||
|
|
||||||
const title = ref<string>('');
|
|
||||||
const width = ref<number>(800);
|
|
||||||
const visible = ref<boolean>(false);
|
|
||||||
const disableSubmit = ref<boolean>(false);
|
|
||||||
const registerForm = ref();
|
|
||||||
const emit = defineEmits(['register', 'success']);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增
|
|
||||||
*/
|
|
||||||
function add() {
|
|
||||||
title.value = '新增';
|
|
||||||
visible.value = true;
|
|
||||||
nextTick(() => {
|
|
||||||
registerForm.value.add();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑
|
|
||||||
* @param record
|
|
||||||
*/
|
|
||||||
function edit(record) {
|
|
||||||
title.value = disableSubmit.value ? '详情' : '编辑';
|
|
||||||
visible.value = true;
|
|
||||||
nextTick(() => {
|
|
||||||
registerForm.value.edit(record);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确定按钮点击事件
|
|
||||||
*/
|
|
||||||
function handleOk() {
|
|
||||||
registerForm.value.submitForm();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* form保存回调事件
|
|
||||||
*/
|
|
||||||
function submitCallback() {
|
|
||||||
handleCancel();
|
|
||||||
emit('success');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消按钮回调事件
|
|
||||||
*/
|
|
||||||
function handleCancel() {
|
|
||||||
visible.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
add,
|
|
||||||
edit,
|
|
||||||
disableSubmit,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
/**隐藏样式-modal确定按钮 */
|
|
||||||
.jee-hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="less" scoped></style>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="preview-container">
|
|
||||||
<!-- 图片预览 -->
|
|
||||||
<div v-if="fileType === 'image' && filePath" class="preview-item">
|
|
||||||
<a-image :width="200" :src="getFullPath(filePath)" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 视频预览 -->
|
|
||||||
<div v-if="fileType === 'video' && filePath" class="preview-item">
|
|
||||||
<video controls :src="getFullPath(filePath)" style="width: 200px; height: auto;"></video>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 音频预览 -->
|
|
||||||
<div v-if="fileType === 'audio' && filePath" class="preview-item">
|
|
||||||
<audio controls :src="getFullPath(filePath)"></audio>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 文档预览 -->
|
|
||||||
<div v-if="fileType === 'document' && filePath" class="preview-item">
|
|
||||||
<a-button @click="handlePreviewDocument">预览文档</a-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, watch } from 'vue';
|
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
fileType: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
filePath: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const getFullPath = (path) => {
|
|
||||||
return getFileAccessHttpUrl(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePreviewDocument = () => {
|
|
||||||
window.open(getFullPath(props.filePath), '_blank');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.preview-container {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -12,7 +12,7 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="键名" v-bind="validateInfos.configKey" id="SysConfigForm-configKey" name="configKey">
|
<a-form-item label="键名" v-bind="validateInfos.configKey" id="SysConfigForm-configKey" name="configKey">
|
||||||
<a-input v-model:value="formData.configKey" placeholder="请输入键名" allow-clear :disabled="!!formData.id"></a-input>
|
<a-input v-model:value="formData.configKey" placeholder="请输入键名" allow-clear></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="5">
|
<a-col :span="5">
|
||||||
<span v-if="hasSearchConditions" style="font-size: 16px;font-weight: bold;color:#E86A6A">
|
<span v-if="hasSearchConditions" style="font-size: 16px;font-weight: bold;color:#E86A6A">
|
||||||
有筛选条件未重置
|
有筛选条件未重置,{{ activeSearchConditions }}
|
||||||
</span>
|
</span>
|
||||||
<span style="font-size: 16px;font-weight: bold;color:#ABACAD">点击展开更多操作区域</span>
|
<span style="font-size: 16px;font-weight: bold;color:#ABACAD">点击展开更多操作区域</span>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
|
|
@ -1,327 +0,0 @@
|
||||||
<template>
|
|
||||||
<SyncComponent ref="syncComRef" :selectedSize="Array.from(selectedItems.values()).length"
|
|
||||||
@changeShowJMCom="changeShowJMCom" @sourceOrgCodeChanged="sourceOrgCodeChanged"
|
|
||||||
@viewTypeChanged="viewTypeChanged" @orgChanged="orgChanged">
|
|
||||||
<!-- 表单 -->
|
|
||||||
<template #searchFormSlot>
|
|
||||||
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol"
|
|
||||||
:wrapper-col="wrapperCol">
|
|
||||||
<a-row :gutter="24">
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="categoryId">
|
|
||||||
<template #label><span title="服务类别">服务类别</span></template>
|
|
||||||
<j-dict-select-tag type="list" v-model:value="queryParam.categoryId" v-if="showJMCom"
|
|
||||||
:orgCode="sourceOrgCode"
|
|
||||||
:dictCode="`nu_config_service_category,category_name,id,del_flag = 0 order by sort asc`"
|
|
||||||
:ignoreDisabled="true" placeholder="请选择服务类别" allow-clear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="typeId">
|
|
||||||
<template #label><span title="服务类型">服务类型</span></template>
|
|
||||||
<j-dict-select-tag type="list" v-model:value="queryParam.typeId" v-if="showJMCom"
|
|
||||||
:orgCode="sourceOrgCode"
|
|
||||||
:dictCode="`nu_config_service_type,type_name,id,del_flag = 0 order by sort asc`"
|
|
||||||
placeholder="请选择服务类型" :ignoreDisabled="true" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<!-- <template v-if="toggleSearchStatus"> -->
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="directiveName">
|
|
||||||
<template #label><span title="服务指令">服务指令</span></template>
|
|
||||||
<JInput v-model:value="queryParam.directiveName" placeholder="请输入服务指令名称" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="instructionTagId">
|
|
||||||
<template #label><span title="分类标签">分类标签</span></template>
|
|
||||||
<j-dict-select-tag v-model:value="queryParam.instructionTagId" v-if="showJMCom"
|
|
||||||
:orgCode="sourceOrgCode" dictCode="instruction_tag" :ignoreDisabled="true"
|
|
||||||
placeholder="请选分类标签" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="bodyTags">
|
|
||||||
<template #label><span title="体型标签">体型标签</span></template>
|
|
||||||
<JSelectMultiple type="list" v-model:value="queryParam.bodyTags" v-if="showJMCom"
|
|
||||||
:orgCode="sourceOrgCode"
|
|
||||||
:dictCode="`nu_config_body_tag,tag_name,id,del_flag = '0' order by sort asc`"
|
|
||||||
:ignoreDisabled="true" placeholder="请选择体型标签" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="emotionTags">
|
|
||||||
<template #label><span title="情绪标签">情绪标签</span></template>
|
|
||||||
<JSelectMultiple type="list" v-model:value="queryParam.emotionTags" v-if="showJMCom"
|
|
||||||
:orgCode="sourceOrgCode"
|
|
||||||
:dictCode="`nu_config_emotion_tag,tag_name,id,del_flag = '0' order by sort asc`"
|
|
||||||
:ignoreDisabled="true" placeholder="请选择情绪标签" allowClear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
|
||||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-button type="primary" preIcon="ant-design:search-outlined"
|
|
||||||
@click="searchQuery">查询</a-button>
|
|
||||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset"
|
|
||||||
style="margin-left: 8px">重置</a-button>
|
|
||||||
</a-col>
|
|
||||||
</span>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 试验田数据列表 -->
|
|
||||||
<template #sourceTableSlot>
|
|
||||||
<ConfigServiceDirectiveList @select-change="handleSelectChange" ref="listComRef" :queryParams="queryParam"
|
|
||||||
:initialDataIds="initialDataIds" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 需要同步的机构的数据列表 -->
|
|
||||||
<template #businessTableSlot>
|
|
||||||
<a-table size="small" :columns="selectedColumns" :dataSource="Array.from(selectedItems.values())"
|
|
||||||
:pagination="false" :scroll="{ y: '55vh' }">
|
|
||||||
<template #bodyCell="{ column, record }">
|
|
||||||
<template v-if="column.dataIndex === 'action'">
|
|
||||||
<a-popconfirm placement="left" ok-text="确认" cancel-text="取消"
|
|
||||||
@confirm="handleRemoveFromRight(record.id)">
|
|
||||||
<template #title>
|
|
||||||
<span>是否确认移除</span>
|
|
||||||
</template>
|
|
||||||
<a-button type="link" danger size="small"
|
|
||||||
:disabled="initialDataIds.includes(record.id)">移除</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'mp3File'">
|
|
||||||
<span v-if="!record.mp3File" style="font-size: 12px;font-style: italic;">无文件</span>
|
|
||||||
<audio controls v-else style="width: 100%; max-width: 300px; height: 40px;">
|
|
||||||
<source :src="getFileAccessHttpUrl(record.mp3File)">
|
|
||||||
</audio>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'mp4File'">
|
|
||||||
<span v-if="!record.mp4File" style="font-size: 12px;font-style: italic;">无文件</span>
|
|
||||||
<a-button v-else type="primary" size="small" @click="openVideoModal(record.mp4File)">
|
|
||||||
播放视频
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'bodyTagList'">
|
|
||||||
<span v-if="!record.bodyTagList || record.bodyTagList.length === 0"
|
|
||||||
style="font-size: 12px;font-style: italic;">-</span>
|
|
||||||
<template v-else>
|
|
||||||
{{record.bodyTagList.map(item => item.tagName).join('、')}}
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'emotionTagList'">
|
|
||||||
<span v-if="!record.emotionTagList || record.emotionTagList.length === 0"
|
|
||||||
style="font-size: 12px;font-style: italic;">-</span>
|
|
||||||
<template v-else>
|
|
||||||
{{record.emotionTagList.map(item => item.tagName).join('、')}}
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'previewFile'">
|
|
||||||
<span v-if="!record.previewFile" style="font-size: 12px;font-style: italic;">无图片</span>
|
|
||||||
<img v-else :src="getFileAccessHttpUrl(record.previewFile)"
|
|
||||||
style="max-width: 100px; max-height: 60px;" />
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'immediateFile'">
|
|
||||||
<span v-if="!record.immediateFile" style="font-size: 12px;font-style: italic;">无图片</span>
|
|
||||||
<img v-else :src="getFileAccessHttpUrl(record.immediateFile)"
|
|
||||||
style="max-width: 100px; max-height: 60px;" />
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</template>
|
|
||||||
</SyncComponent>
|
|
||||||
|
|
||||||
<a-modal v-model:visible="showVideoModal" title="视频播放" :footer="null" @cancel="closeVideoModal"
|
|
||||||
:bodyStyle="{ padding: '0', maxHeight: '80vh', overflow: 'auto' }">
|
|
||||||
<video controls style="width: 100%; max-height: '70vh'; display: block; margin: 0 auto;">
|
|
||||||
<source :src="videoUrl">
|
|
||||||
您的浏览器不支持视频播放。
|
|
||||||
</video>
|
|
||||||
</a-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup name="synchronization-directive2" lang="ts">
|
|
||||||
// ↓↓↓↓↓ 组件自带
|
|
||||||
import { ref, reactive } from 'vue'
|
|
||||||
import SyncComponent from '/@/components/Sync/SyncComponent.vue'
|
|
||||||
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
|
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
|
||||||
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
|
||||||
// ↑↑↑↑↑ 组件自带
|
|
||||||
// ↓↓↓↓↓ 服务指令用
|
|
||||||
import { list, asyncFunc } from '@/views/services/serviceDirective/ConfigServiceDirective.api';
|
|
||||||
import ConfigServiceDirectiveList from '@/views/services/serviceDirective/ConfigServiceDirectiveList.vue'
|
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'
|
|
||||||
import { selectedColumns } from './org.data';
|
|
||||||
// ↑↑↑↑↑ 服务指令用
|
|
||||||
|
|
||||||
// >>>>>>>>>>>>>组件:无需处理代码
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
const syncComRef = ref(null)
|
|
||||||
const sourceOrgCode = ref('')
|
|
||||||
const showJMCom = ref(false)
|
|
||||||
const labelCol = reactive({
|
|
||||||
xs: 24,
|
|
||||||
sm: 4,
|
|
||||||
xl: 6,
|
|
||||||
xxl: 4
|
|
||||||
});
|
|
||||||
const wrapperCol = reactive({
|
|
||||||
xs: 24,
|
|
||||||
sm: 20,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取到了试验田的机构编码
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
const sourceOrgCodeChanged = (v_) => {
|
|
||||||
sourceOrgCode.value = v_
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 是否展示设计dict的cj框架封装的组件(因为需要获取的是对应试验田的数据字典,当接口数据请求未返回时如果展示组件会报错)
|
|
||||||
* 跟sourceOrgCodeChanged方法相配合
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
const changeShowJMCom = (v_) => {
|
|
||||||
showJMCom.value = v_
|
|
||||||
}
|
|
||||||
// <<<<<<<<<<<<<组件:无需处理代码
|
|
||||||
/**
|
|
||||||
* 机构变更
|
|
||||||
*/
|
|
||||||
const orgChanged = async (org) => {
|
|
||||||
// 清空当前选择
|
|
||||||
selectedItems.value.clear();
|
|
||||||
// 清空初始化数据
|
|
||||||
initialDataIds.value = [];
|
|
||||||
try {
|
|
||||||
// 加载新机构数据
|
|
||||||
const res = await list({ dataSourceCode: org.orgCode, pageNo: 1, pageSize: -1 });
|
|
||||||
// 如果有数据,更新右侧列表
|
|
||||||
if (res.records && res.records.length > 0) {
|
|
||||||
const newRecords = res.records;
|
|
||||||
newRecords.forEach(record => {
|
|
||||||
selectedItems.value.set(record.id, record);
|
|
||||||
if (!syncComRef.value.orgData.value?.operationStartTime || new Date() >= new Date(syncComRef.value.orgData.value?.operationStartTime)) {
|
|
||||||
initialDataIds.value.push(record.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新左侧列表的选中状态
|
|
||||||
listComRef.value?.updateSelection?.(newRecords);
|
|
||||||
} else {
|
|
||||||
// 没有数据时也确保清空
|
|
||||||
selectedItems.value.clear();
|
|
||||||
listComRef.value?.updateSelection?.([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换视图
|
|
||||||
syncComRef.value.resetOrgSelectedCon(false);
|
|
||||||
|
|
||||||
console.log("🌊 ~ orgChanged ~ selectedItems.value:", selectedItems.value)
|
|
||||||
} catch (err) {
|
|
||||||
console.error('机构数据查询失败:', err);
|
|
||||||
createMessage.error('机构数据查询失败');
|
|
||||||
// 失败时也确保清空状态
|
|
||||||
selectedItems.value.clear();
|
|
||||||
listComRef.value?.updateSelection?.([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// >>>>>>>>>>>>>组件:需要处理代码
|
|
||||||
// <<<<<<<<<<<<<组件:需要处理代码
|
|
||||||
|
|
||||||
// >>>>>>>>>>>>>非组件代码
|
|
||||||
const listComRef = ref();
|
|
||||||
const selectedItems = ref(new Map<string | number, any>());
|
|
||||||
const queryParam = ref({ viewType: 'all' })//源数据查询参数
|
|
||||||
const initialDataIds = ref<string[]>([]);
|
|
||||||
const showVideoModal = ref(false);
|
|
||||||
const videoUrl = ref('');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询
|
|
||||||
*/
|
|
||||||
function searchQuery() {
|
|
||||||
listComRef.value.reload();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 重置
|
|
||||||
*/
|
|
||||||
function searchReset() {
|
|
||||||
let vt = queryParam.value.viewType
|
|
||||||
queryParam.value = { viewType: vt }
|
|
||||||
listComRef.value?.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 源数据的全部、已选择、未选择变更时触发
|
|
||||||
* @param v_ all、selected、unselected
|
|
||||||
*/
|
|
||||||
const viewTypeChanged = (v_) => {
|
|
||||||
queryParam.value.viewType = v_
|
|
||||||
//组件内部监听了queryParam值的变化,自动刷新
|
|
||||||
}
|
|
||||||
const handleSelectChange = (items: Map<string | number, any>) => {
|
|
||||||
selectedItems.value = new Map(items);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRemoveFromRight = (key: string | number) => {
|
|
||||||
selectedItems.value.delete(key);
|
|
||||||
listComRef.value?.removeSelectedItem?.(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
const openVideoModal = (url: string) => {
|
|
||||||
videoUrl.value = getFileAccessHttpUrl(url);
|
|
||||||
showVideoModal.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeVideoModal = () => {
|
|
||||||
showVideoModal.value = false;
|
|
||||||
videoUrl.value = '';
|
|
||||||
};
|
|
||||||
// <<<<<<<<<<<<<非组件代码
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.jeecg-basic-table-form-container {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.table-page-search-submitButtons {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-group-cust {
|
|
||||||
min-width: 100px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.query-group-split-cust {
|
|
||||||
width: 30px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-form-item:not(.ant-form-item-with-help) {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-picker),
|
|
||||||
:deep(.ant-input-number) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-list-container {
|
|
||||||
:deep(.ant-table) {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -65,7 +65,7 @@ export const saveOrUpdateDict = (params, isUpdate) => {
|
||||||
* 查询全部树形节点数据
|
* 查询全部树形节点数据
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export const loadTreeData = (params) => defHttp.get({ url: Api.loadTreeData,timeout:100*1000, params });
|
export const loadTreeData = (params) => defHttp.get({ url: Api.loadTreeData, params });
|
||||||
/**
|
/**
|
||||||
* 查询子节点数据
|
* 查询子节点数据
|
||||||
* @param params
|
* @param params
|
||||||
|
|
|
@ -64,10 +64,4 @@ export const formSchema: FormSchema[] = [
|
||||||
required: true,
|
required: true,
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '编码(非必要无需填写)',
|
|
||||||
field: 'code',
|
|
||||||
required: false,
|
|
||||||
component: 'Input',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose width="50vw" :title="getTitle" @ok="handleSubmit">
|
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose width="550px" :title="getTitle" @ok="handleSubmit">
|
||||||
<BasicForm @register="registerForm" />
|
<BasicForm @register="registerForm" />
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
showActionButtonGroup: false,
|
showActionButtonGroup: false,
|
||||||
labelCol: {
|
labelCol: {
|
||||||
xs: { span: 24 },
|
xs: { span: 24 },
|
||||||
sm: { span: 5 },
|
sm: { span: 4 },
|
||||||
},
|
},
|
||||||
wrapperCol: {
|
wrapperCol: {
|
||||||
xs: { span: 24 },
|
xs: { span: 24 },
|
||||||
sm: { span: 15 },
|
sm: { span: 18 },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//表单赋值
|
//表单赋值
|
||||||
|
|
|
@ -147,9 +147,6 @@
|
||||||
* 成功回调
|
* 成功回调
|
||||||
*/
|
*/
|
||||||
async function handleSuccess({ isUpdate,isSubAdd, values, expandedArr }) {
|
async function handleSuccess({ isUpdate,isSubAdd, values, expandedArr }) {
|
||||||
reload();
|
|
||||||
return
|
|
||||||
//几百条数据:直接重新加载比框架写的代码要加载快得多 框架设计师不知道在寻思鸡毛🤡 新增一条数据几百个请求处理 处理半天处理不完
|
|
||||||
if (isUpdate) {
|
if (isUpdate) {
|
||||||
//编辑回调
|
//编辑回调
|
||||||
updateTableDataRecord(values.id, values);
|
updateTableDataRecord(values.id, values);
|
||||||
|
|
|
@ -1,55 +1,37 @@
|
||||||
<template>
|
<template>
|
||||||
<BasicModal :title="title" :width="800" v-bind="$attrs" @ok="handleOk" @register="registerModal">
|
<BasicModal :title="title" :width="800" v-bind="$attrs" @ok="handleOk" @register="registerModal">
|
||||||
<BasicForm @register="registerForm">
|
<BasicForm @register="registerForm" />
|
||||||
<!-- 省份 -->
|
|
||||||
<template #province="{ model, field }">
|
|
||||||
<j-dict-select-tag @change="provinceChanged(model)" v-model:value="model[field]"
|
|
||||||
:dictCode="getProvinceDictCode()" placeholder="请选择所在省份" :disabled="model.orgCategory != '1'" />
|
|
||||||
</template>
|
|
||||||
<!-- 城市 -->
|
|
||||||
<template #city="{ model, field }">
|
|
||||||
<j-dict-select-tag @change="cityChanged(model)" v-model:value="model[field]" :dictCode="getCityDictCode(model)"
|
|
||||||
placeholder="请选择所在城市" :disabled="model.orgCategory != '1' && !model.province" />
|
|
||||||
</template>
|
|
||||||
<!-- 区县 -->
|
|
||||||
<template #district="{ model, field }">
|
|
||||||
<j-dict-select-tag v-model:value="model[field]" :dictCode="getDistrictDictCode(model)" placeholder="请选择所在区县"
|
|
||||||
:disabled="model.orgCategory != '1' && (!model.province || !model.city)" />
|
|
||||||
</template>
|
|
||||||
</BasicForm>
|
|
||||||
</BasicModal>
|
</BasicModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
||||||
|
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||||
|
|
||||||
import { saveOrUpdateDepart } from '../depart.api';
|
import { saveOrUpdateDepart } from '../depart.api';
|
||||||
import { useBasicFormSchema, orgCategoryOptions } from '../depart.data';
|
import { useBasicFormSchema, orgCategoryOptions } from '../depart.data';
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
|
||||||
|
|
||||||
|
const emit = defineEmits(['success', 'register']);
|
||||||
const emit = defineEmits(['success', 'register']);
|
const props = defineProps({
|
||||||
const props = defineProps({
|
|
||||||
rootTreeData: { type: Array, default: () => [] },
|
rootTreeData: { type: Array, default: () => [] },
|
||||||
});
|
});
|
||||||
const prefixCls = inject('prefixCls');
|
const prefixCls = inject('prefixCls');
|
||||||
// 当前是否是更新模式
|
// 当前是否是更新模式
|
||||||
const isUpdate = ref<boolean>(false);
|
const isUpdate = ref<boolean>(false);
|
||||||
// 当前的弹窗数据
|
// 当前的弹窗数据
|
||||||
const model = ref<object>({});
|
const model = ref<object>({});
|
||||||
const title = computed(() => (isUpdate.value ? '编辑' : '新增'));
|
const title = computed(() => (isUpdate.value ? '编辑' : '新增'));
|
||||||
|
|
||||||
//注册表单
|
//注册表单
|
||||||
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||||
schemas: useBasicFormSchema().basicFormSchema,
|
schemas: useBasicFormSchema().basicFormSchema,
|
||||||
showActionButtonGroup: false,
|
showActionButtonGroup: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 注册弹窗
|
// 注册弹窗
|
||||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||||
await resetFields();
|
await resetFields();
|
||||||
isUpdate.value = unref(data?.isUpdate);
|
isUpdate.value = unref(data?.isUpdate);
|
||||||
// 当前是否为添加子级
|
// 当前是否为添加子级
|
||||||
|
@ -94,10 +76,10 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
|
||||||
);
|
);
|
||||||
model.value = record;
|
model.value = record;
|
||||||
await setFieldsValue({ ...record });
|
await setFieldsValue({ ...record });
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交事件
|
// 提交事件
|
||||||
async function handleOk() {
|
async function handleOk() {
|
||||||
try {
|
try {
|
||||||
setModalProps({ confirmLoading: true });
|
setModalProps({ confirmLoading: true });
|
||||||
let values = await validate();
|
let values = await validate();
|
||||||
|
@ -110,33 +92,5 @@ async function handleOk() {
|
||||||
} finally {
|
} finally {
|
||||||
setModalProps({ confirmLoading: false });
|
setModalProps({ confirmLoading: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 省份字典
|
|
||||||
*/
|
|
||||||
function getProvinceDictCode() {
|
|
||||||
return 'sys_category,name,id,pid = \'xzqhdm\' order by code asc'
|
|
||||||
}
|
|
||||||
function provinceChanged(model) {
|
|
||||||
model.city = null
|
|
||||||
model.district = null
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 城市字典
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
function getCityDictCode(v_) {
|
|
||||||
return 'sys_category,name,id,pid = \'' + v_.province + '\' order by code asc'
|
|
||||||
}
|
|
||||||
function cityChanged(model) {
|
|
||||||
model.district = null
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 区县字典
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
function getDistrictDictCode(v_) {
|
|
||||||
return 'sys_category,name,id,pid = \'' + v_.city + '\' order by code asc'
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,22 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
<BasicForm @register="registerForm">
|
<BasicForm @register="registerForm" />
|
||||||
<!-- 省份 -->
|
|
||||||
<template #province="{ model, field }">
|
|
||||||
<j-dict-select-tag @change="provinceChanged(model)" v-model:value="model[field]"
|
|
||||||
:dictCode="getProvinceDictCode()" placeholder="请选择所在省份" :disabled="model.orgCategory != '1'" />
|
|
||||||
</template>
|
|
||||||
<!-- 城市 -->
|
|
||||||
<template #city="{ model, field }">
|
|
||||||
<j-dict-select-tag @change="cityChanged(model)" v-model:value="model[field]" :dictCode="getCityDictCode(model)"
|
|
||||||
placeholder="请选择所在城市" :disabled="model.orgCategory != '1' && !model.province" />
|
|
||||||
</template>
|
|
||||||
<!-- 区县 -->
|
|
||||||
<template #district="{ model, field }">
|
|
||||||
<j-dict-select-tag v-model:value="model[field]" :dictCode="getDistrictDictCode(model)" placeholder="请选择所在区县"
|
|
||||||
:disabled="model.orgCategory != '1' && (!model.province || !model.city)" />
|
|
||||||
</template>
|
|
||||||
</BasicForm>
|
|
||||||
<div class="j-box-bottom-button offset-20" style="margin-top: 30px">
|
<div class="j-box-bottom-button offset-20" style="margin-top: 30px">
|
||||||
<div class="j-box-bottom-button-float" :class="[`${prefixCls}`]">
|
<div class="j-box-bottom-button-float" :class="[`${prefixCls}`]">
|
||||||
<a-button preIcon="ant-design:sync-outlined" @click="onReset">重置</a-button>
|
<a-button preIcon="ant-design:sync-outlined" @click="onReset">重置</a-button>
|
||||||
|
@ -27,41 +11,40 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
||||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
import { saveOrUpdateDepart } from '../depart.api';
|
import { saveOrUpdateDepart } from '../depart.api';
|
||||||
import { useBasicFormSchema, orgCategoryOptions } from '../depart.data';
|
import { useBasicFormSchema, orgCategoryOptions } from '../depart.data';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
|
||||||
|
|
||||||
const { prefixCls } = useDesign('j-depart-form-content');
|
const { prefixCls } = useDesign('j-depart-form-content');
|
||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, default: () => ({}) },
|
data: { type: Object, default: () => ({}) },
|
||||||
rootTreeData: { type: Array, default: () => [] },
|
rootTreeData: { type: Array, default: () => [] },
|
||||||
});
|
});
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
// 当前是否是更新模式
|
// 当前是否是更新模式
|
||||||
const isUpdate = ref<boolean>(true);
|
const isUpdate = ref<boolean>(true);
|
||||||
// 当前的弹窗数据
|
// 当前的弹窗数据
|
||||||
const model = ref<object>({});
|
const model = ref<object>({});
|
||||||
|
|
||||||
//注册表单
|
//注册表单
|
||||||
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||||
schemas: useBasicFormSchema().basicFormSchema,
|
schemas: useBasicFormSchema().basicFormSchema,
|
||||||
showActionButtonGroup: false,
|
showActionButtonGroup: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const categoryOptions = computed(() => {
|
const categoryOptions = computed(() => {
|
||||||
if (!!props?.data?.parentId) {
|
if (!!props?.data?.parentId) {
|
||||||
return orgCategoryOptions.child;
|
return orgCategoryOptions.child;
|
||||||
} else {
|
} else {
|
||||||
return orgCategoryOptions.root;
|
return orgCategoryOptions.root;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 禁用字段
|
// 禁用字段
|
||||||
updateSchema([
|
updateSchema([
|
||||||
{ field: 'parentId', componentProps: { disabled: true } },
|
{ field: 'parentId', componentProps: { disabled: true } },
|
||||||
|
@ -107,16 +90,16 @@ onMounted(() => {
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
async function onReset() {
|
async function onReset() {
|
||||||
await resetFields();
|
await resetFields();
|
||||||
await setFieldsValue({ ...model.value });
|
await setFieldsValue({ ...model.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交事件
|
// 提交事件
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let values = await validate();
|
let values = await validate();
|
||||||
|
@ -129,46 +112,17 @@ async function onSubmit() {
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 省份字典
|
|
||||||
*/
|
|
||||||
function getProvinceDictCode() {
|
|
||||||
return 'sys_category,name,id,pid = \'xzqhdm\' order by code asc'
|
|
||||||
}
|
|
||||||
function provinceChanged(model) {
|
|
||||||
model.city = null
|
|
||||||
model.district = null
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 城市字典
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
function getCityDictCode(v_) {
|
|
||||||
return 'sys_category,name,id,pid = \'' + v_.province + '\' order by code asc'
|
|
||||||
}
|
|
||||||
function cityChanged(model) {
|
|
||||||
model.district = null
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 区县字典
|
|
||||||
* @param v_
|
|
||||||
*/
|
|
||||||
function getDistrictDictCode(v_) {
|
|
||||||
return 'sys_category,name,id,pid = \'' + v_.city + '\' order by code asc'
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
// update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
|
// update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
|
||||||
|
|
||||||
@prefix-cls: ~'@{namespace}-j-depart-form-content';
|
@prefix-cls: ~'@{namespace}-j-depart-form-content';
|
||||||
|
/*begin 兼容暗夜模式*/
|
||||||
/*begin 兼容暗夜模式*/
|
.@{prefix-cls} {
|
||||||
.@{prefix-cls} {
|
|
||||||
background: @component-background;
|
background: @component-background;
|
||||||
border-top: 1px solid @border-color-base;
|
border-top: 1px solid @border-color-base;
|
||||||
}
|
}
|
||||||
|
/*end 兼容暗夜模式*/
|
||||||
/*end 兼容暗夜模式*/
|
// update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效
|
||||||
// update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效</style>
|
</style>
|
||||||
|
|
|
@ -36,24 +36,6 @@ export function useBasicFormSchema() {
|
||||||
component: 'RadioButtonGroup',
|
component: 'RadioButtonGroup',
|
||||||
componentProps: { options: [] },
|
componentProps: { options: [] },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'province',
|
|
||||||
label: '省份',
|
|
||||||
component: 'Input',
|
|
||||||
slot: 'province',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'city',
|
|
||||||
label: '城市',
|
|
||||||
component: 'Input',
|
|
||||||
slot: 'city',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'district',
|
|
||||||
label: '区县',
|
|
||||||
component: 'Input',
|
|
||||||
slot: 'district',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'platType',
|
field: 'platType',
|
||||||
label: '业务平台类型',
|
label: '业务平台类型',
|
||||||
|
@ -67,6 +49,12 @@ export function useBasicFormSchema() {
|
||||||
message: '请选择平台类型'
|
message: '请选择平台类型'
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'departOrder',
|
||||||
|
label: '排序',
|
||||||
|
component: 'InputNumber',
|
||||||
|
componentProps: {},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'operationStartTime',
|
field: 'operationStartTime',
|
||||||
label: '运营开始时间',
|
label: '运营开始时间',
|
||||||
|
@ -143,12 +131,6 @@ export function useBasicFormSchema() {
|
||||||
placeholder: '请输入备注',
|
placeholder: '请输入备注',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'departOrder',
|
|
||||||
label: '排序',
|
|
||||||
component: 'InputNumber',
|
|
||||||
componentProps: {},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'picUrl',
|
field: 'picUrl',
|
||||||
label: '机构图片',
|
label: '机构图片',
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
<a-modal v-model:open="showAsyncResult" title="同步结果" @ok="showAsyncResult = false" width="70vw">
|
<a-modal v-model:open="showAsyncResult" title="同步结果" @ok="showAsyncResult = false" width="70vw">
|
||||||
<a-tabs v-model:activeKey="activeTabKey" style="margin-left: 20px;margin-right: 20px;margin-bottom: 20px;">
|
<a-tabs v-model:activeKey="activeTabKey" style="margin-left: 20px;margin-right: 20px;margin-bottom: 20px;">
|
||||||
<template #rightExtra>
|
<template #rightExtra>
|
||||||
<span style="color:red;font-weight: bold;margin-right: 10px;">同步为增量同步,不会修改、删除业务系统数据</span>
|
|
||||||
<a-button type="primary" @click="AsyncResultFunc({ id: opeDictId })" size="small"
|
<a-button type="primary" @click="AsyncResultFunc({ id: opeDictId })" size="small"
|
||||||
preIcon="ant-design:sync-outlined" style="margin-right: 10px;">刷新</a-button>
|
preIcon="ant-design:sync-outlined" style="margin-right: 10px;">刷新</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue