公文流转
This commit is contained in:
parent
9e2d89e911
commit
7f3c9705cc
@ -3,166 +3,115 @@ import { get, post } from "@/utils/request";
|
|||||||
// 公文相关API接口
|
// 公文相关API接口
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取公文列表
|
* 分页查询公文列表
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
*/
|
||||||
export function getGwListApi(params: {
|
export function gwFindPageApi(params: any) {
|
||||||
page: number;
|
return get('/api/gw/findPage', params);
|
||||||
pageSize: number;
|
|
||||||
status?: string;
|
|
||||||
keyword?: string;
|
|
||||||
gwType?: string;
|
|
||||||
urgencyLevel?: string;
|
|
||||||
startTime?: string;
|
|
||||||
endTime?: string;
|
|
||||||
}) {
|
|
||||||
return get('/api/gw/list', params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取公文详情
|
* 根据ID查询公文详情
|
||||||
* @param id 公文ID
|
|
||||||
*/
|
*/
|
||||||
export function getGwDetailApi(id: string) {
|
export function gwFindByIdApi(params: any) {
|
||||||
return get(`/api/gw/detail/${id}`);
|
return get('/api/gw/findById', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建公文
|
* 新增/修改公文
|
||||||
* @param data 公文数据
|
|
||||||
*/
|
*/
|
||||||
export function createGwApi(data: {
|
export function gwSaveApi(params: any) {
|
||||||
title: string;
|
return post('/api/gw/save', params);
|
||||||
gwType: string;
|
|
||||||
urgencyLevel: string;
|
|
||||||
remark?: string;
|
|
||||||
files: any[];
|
|
||||||
approvers: any[];
|
|
||||||
ccUsers: any[];
|
|
||||||
}) {
|
|
||||||
return post('/api/gw/create', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新公文
|
* 软删除公文
|
||||||
* @param id 公文ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
*/
|
||||||
export function updateGwApi(id: string, data: any) {
|
export function gwLogicDeleteApi(params: any) {
|
||||||
return post(`/api/gw/update/${id}`, data);
|
// 将参数拼接到URL中,确保后端能正确接收
|
||||||
}
|
const queryString = Object.keys(params)
|
||||||
|
.map(key => `${key}=${encodeURIComponent(params[key])}`)
|
||||||
|
.join('&');
|
||||||
|
|
||||||
/**
|
// 尝试POST请求,如果不行可以改为GET请求
|
||||||
* 删除公文
|
return post(`/api/gw/logicDelete?${queryString}`, params);
|
||||||
* @param id 公文ID
|
|
||||||
*/
|
// 如果POST请求有问题,可以尝试GET请求:
|
||||||
export function deleteGwApi(id: string) {
|
// return get(`/api/gw/logicDelete?${queryString}`);
|
||||||
return post(`/api/gw/delete/${id}`, { id });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存草稿
|
* 保存草稿
|
||||||
* @param data 草稿数据
|
|
||||||
*/
|
*/
|
||||||
export function saveDraftApi(data: any) {
|
export function gwDraftApi(params: any) {
|
||||||
return post('/api/gw/draft', data);
|
return post('/api/gw/draft', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交公文
|
* 提交公文
|
||||||
* @param data 提交数据
|
|
||||||
*/
|
*/
|
||||||
export function submitGwApi(data: any) {
|
export function gwSubmitApi(params: any) {
|
||||||
return post('/api/gw/submit', data);
|
return post('/api/gw/submit', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存变更
|
* 审批公文
|
||||||
* @param data 变更数据
|
|
||||||
*/
|
*/
|
||||||
export function saveChangesApi(data: {
|
export function gwApproveApi(params: any) {
|
||||||
gwId: string;
|
return post('/api/gw/approve', params);
|
||||||
approvers: any[];
|
|
||||||
ccUsers: any[];
|
|
||||||
operationLogs: any[];
|
|
||||||
}) {
|
|
||||||
return post('/api/gw/changes', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索用户
|
* 抄送确认
|
||||||
* @param keyword 搜索关键词
|
|
||||||
*/
|
*/
|
||||||
export function searchUsersApi(keyword: string) {
|
export function gwCcConfirmApi(params: any) {
|
||||||
return get('/api/user/search', { keyword });
|
return post('/api/gw/cc-confirm', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取审批人列表
|
* 获取审批人列表
|
||||||
* @param gwId 公文ID
|
|
||||||
*/
|
*/
|
||||||
export function getApproversApi(gwId: string) {
|
export function gwApproversApi(params: any) {
|
||||||
return get(`/api/gw/approvers/${gwId}`);
|
return get('/api/gw/approvers', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取抄送人列表
|
* 获取抄送人列表
|
||||||
* @param gwId 公文ID
|
|
||||||
*/
|
*/
|
||||||
export function getCCUsersApi(gwId: string) {
|
export function gwCcUsersApi(params: any) {
|
||||||
return get(`/api/gw/cc-users/${gwId}`);
|
return get('/api/gw/cc-users', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取操作记录
|
* 获取操作记录
|
||||||
* @param gwId 公文ID
|
|
||||||
*/
|
*/
|
||||||
export function getOperationLogsApi(gwId: string) {
|
export function gwLogsApi(params: any) {
|
||||||
return get(`/api/gw/logs/${gwId}`);
|
return get('/api/gw/logs', params);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
* @param file 文件对象
|
|
||||||
*/
|
|
||||||
export function uploadFileApi(file: File) {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("file", file);
|
|
||||||
|
|
||||||
return post('/api/file/upload', formData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件删除
|
|
||||||
* @param fileId 文件ID
|
|
||||||
*/
|
|
||||||
export function deleteFileApi(fileId: string) {
|
|
||||||
return post(`/api/file/delete/${fileId}`, { fileId });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取公文统计信息
|
* 获取公文统计信息
|
||||||
*/
|
*/
|
||||||
export function getGwStatsApi() {
|
export function gwStatsApi(params: any) {
|
||||||
return get('/api/gw/stats');
|
return get('/api/gw/stats', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批公文
|
* 文件上传
|
||||||
* @param data 审批数据
|
|
||||||
*/
|
*/
|
||||||
export function approveGwApi(data: {
|
export function fileUploadApi(params: any) {
|
||||||
gwId: string;
|
return post('/api/file/upload', params);
|
||||||
action: "approve" | "reject";
|
|
||||||
remark?: string;
|
|
||||||
}) {
|
|
||||||
return post('/api/gw/approve', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 抄送确认
|
* 文件删除
|
||||||
* @param gwId 公文ID
|
|
||||||
*/
|
*/
|
||||||
export function confirmCCApi(gwId: string) {
|
export function fileDeleteApi(params: any) {
|
||||||
return post(`/api/gw/cc-confirm/${gwId}`);
|
return post('/api/file/delete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索用户
|
||||||
|
*/
|
||||||
|
export function userSearchApi(params: any) {
|
||||||
|
return get('/api/user/search', params);
|
||||||
}
|
}
|
||||||
|
|||||||
112
src/api/routine/lcglSetApi.ts
Normal file
112
src/api/routine/lcglSetApi.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { get, post } from "@/utils/request";
|
||||||
|
|
||||||
|
// 流程管理设置相关API接口
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询流程设置
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export function lcglSetFindPageApi(params: {
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
ruleId?: string;
|
||||||
|
ruleName?: string;
|
||||||
|
status?: string;
|
||||||
|
startTime?: string;
|
||||||
|
endTime?: string;
|
||||||
|
}) {
|
||||||
|
return get('/api/lcglSet/findPage', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增/修改流程设置
|
||||||
|
* @param params 流程设置数据
|
||||||
|
*/
|
||||||
|
export function lcglSetSaveApi(params: {
|
||||||
|
id?: string;
|
||||||
|
ruleId: string;
|
||||||
|
ruleName: string;
|
||||||
|
spId?: string;
|
||||||
|
ccId?: string;
|
||||||
|
status?: string;
|
||||||
|
remark?: string;
|
||||||
|
}) {
|
||||||
|
return post('/api/lcglSet/save', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逻辑删除流程设置
|
||||||
|
* @param params 删除参数
|
||||||
|
*/
|
||||||
|
export function lcglSetLogicDeleteApi(params: { id: string }) {
|
||||||
|
return post('/api/lcglSet/logicDelete', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询流程设置详情
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export function lcglSetFindByIdApi(params: { id: string }) {
|
||||||
|
return get('/api/lcglSet/findById', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有流程设置
|
||||||
|
*/
|
||||||
|
export function lcglSetFindAllApi() {
|
||||||
|
return get('/api/lcglSet/findAll');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据规则ID查询流程设置
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export function lcglSetFindByRuleIdApi(params: { ruleId: string }) {
|
||||||
|
return get('/api/lcglSet/findByRuleId', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新流程设置状态
|
||||||
|
* @param params 更新参数
|
||||||
|
*/
|
||||||
|
export function lcglSetUpdateStatusApi(params: {
|
||||||
|
id: string;
|
||||||
|
status: string;
|
||||||
|
}) {
|
||||||
|
return post('/api/lcglSet/updateStatus', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制流程设置
|
||||||
|
* @param params 复制参数
|
||||||
|
*/
|
||||||
|
export function lcglSetCopyApi(params: {
|
||||||
|
id: string;
|
||||||
|
newRuleId: string;
|
||||||
|
newRuleName: string;
|
||||||
|
}) {
|
||||||
|
return post('/api/lcglSet/copy', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出流程设置
|
||||||
|
* @param params 导出参数
|
||||||
|
*/
|
||||||
|
export function lcglSetExportApi(params: {
|
||||||
|
ids?: string[];
|
||||||
|
ruleId?: string;
|
||||||
|
status?: string;
|
||||||
|
}) {
|
||||||
|
return post('/api/lcglSet/export', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入流程设置
|
||||||
|
* @param params 导入参数
|
||||||
|
*/
|
||||||
|
export function lcglSetImportApi(params: {
|
||||||
|
file: File;
|
||||||
|
overwrite?: boolean;
|
||||||
|
}) {
|
||||||
|
return post('/api/lcglSet/import', params);
|
||||||
|
}
|
||||||
91
src/components/BasicForm/components/BasicJsPicker.vue
Normal file
91
src/components/BasicForm/components/BasicJsPicker.vue
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<view class="py-7">
|
||||||
|
<BasicJsPicker
|
||||||
|
ref="pickerRef"
|
||||||
|
v-model="pickerValue"
|
||||||
|
v-bind="attrs.componentProps"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
/**
|
||||||
|
* FormBasicJsPicker 教师选择器表单组件
|
||||||
|
* 用于在 BasicForm 中使用 BasicJsPicker 组件
|
||||||
|
*/
|
||||||
|
import BasicJsPicker from "@/components/BasicJsPicker/Picker.vue";
|
||||||
|
|
||||||
|
const pickerRef = ref<any>(null);
|
||||||
|
|
||||||
|
const props = defineProps(["modelValue"]);
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
const attrs: any = useAttrs();
|
||||||
|
|
||||||
|
// 计算显示值
|
||||||
|
const pickerValue = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
emit("update:modelValue", value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 注意:displayValue 和 open 函数已移除,因为 BasicJsPicker 组件本身已经处理了显示和交互
|
||||||
|
|
||||||
|
// 处理选择变化
|
||||||
|
const handleChange = (value: any) => {
|
||||||
|
// 根据 multiple 属性处理返回值
|
||||||
|
if (attrs.componentProps.multiple) {
|
||||||
|
// 多选模式:返回数组
|
||||||
|
pickerValue.value = value;
|
||||||
|
} else {
|
||||||
|
// 单选模式:返回单个值或 null
|
||||||
|
pickerValue.value = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
open: () => pickerRef.value?.open(),
|
||||||
|
close: () => pickerRef.value?.close()
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.py-7 {
|
||||||
|
padding: 7rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.justify-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-13 {
|
||||||
|
font-size: 13rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-ellipsis-1 {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-9 {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -8,6 +8,7 @@
|
|||||||
<FormBasicCode v-bind="attrs" v-if="isShow('BasicCode')" v-model="newValue"/>
|
<FormBasicCode v-bind="attrs" v-if="isShow('BasicCode')" v-model="newValue"/>
|
||||||
<FormBasicSwitch v-bind="attrs" v-if="isShow('BasicSwitch')" v-model="newValue"/>
|
<FormBasicSwitch v-bind="attrs" v-if="isShow('BasicSwitch')" v-model="newValue"/>
|
||||||
<FormBasicPicker v-bind="attrs" v-if="isShow('BasicPicker')" v-model="newValue"/>
|
<FormBasicPicker v-bind="attrs" v-if="isShow('BasicPicker')" v-model="newValue"/>
|
||||||
|
<FormBasicJsPicker v-bind="attrs" v-if="isShow('BasicJsPicker')" v-model="newValue"/>
|
||||||
<FormBasicNumberBox v-bind="attrs" v-if="isShow('BasicNumberBox')" v-model="newValue"/>
|
<FormBasicNumberBox v-bind="attrs" v-if="isShow('BasicNumberBox')" v-model="newValue"/>
|
||||||
<FormBasicSelectBox v-bind="attrs" v-if="isShow('BasicSelectBox')" v-model="newValue"/>
|
<FormBasicSelectBox v-bind="attrs" v-if="isShow('BasicSelectBox')" v-model="newValue"/>
|
||||||
<FormBasicLocation v-bind="attrs" v-if="isShow('BasicLocation')" v-model="newValue"/>
|
<FormBasicLocation v-bind="attrs" v-if="isShow('BasicLocation')" v-model="newValue"/>
|
||||||
|
|||||||
1
src/components/BasicForm/type/useForm.d.ts
vendored
1
src/components/BasicForm/type/useForm.d.ts
vendored
@ -17,6 +17,7 @@ type Component =
|
|||||||
| 'BasicDateTime'
|
| 'BasicDateTime'
|
||||||
| 'BasicInput'
|
| 'BasicInput'
|
||||||
| 'BasicPicker'
|
| 'BasicPicker'
|
||||||
|
| 'BasicJsPicker'
|
||||||
| 'BasicRate'
|
| 'BasicRate'
|
||||||
| 'BasicSwitch'
|
| 'BasicSwitch'
|
||||||
| 'BasicUpload'
|
| 'BasicUpload'
|
||||||
|
|||||||
387
src/components/BasicJsPicker/Picker.vue
Normal file
387
src/components/BasicJsPicker/Picker.vue
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
<template>
|
||||||
|
<view class="basic-js-picker">
|
||||||
|
<view class="js-selected" @click="showPicker">
|
||||||
|
<view class="js-selected-name">
|
||||||
|
<text class="data" v-if="selectedList && selectedList.length">{{ getShowSelectedName() }}</text>
|
||||||
|
<text class="data" style="color: #999;" v-else>{{ placeholder }}</text>
|
||||||
|
</view>
|
||||||
|
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<u-popup :show="showPopup" @close="showPopup=false">
|
||||||
|
<view class="js-picker-popup">
|
||||||
|
<view class="js-picker-header">
|
||||||
|
<view class="js-cancel-btn" @click="handleCancel">取消</view>
|
||||||
|
<view class="js-picker-title">{{ title }}</view>
|
||||||
|
<view class="js-ok-btn" @click="handleOk">确定</view>
|
||||||
|
</view>
|
||||||
|
<view class="js-picker-search" v-if="showSearch">
|
||||||
|
<BasicSearch @change="handleSearch" :showAction="false" height="36" :placeholder="searchPlaceholder"/>
|
||||||
|
</view>
|
||||||
|
<view class="js-list">
|
||||||
|
<scroll-view scroll-y style="max-height: 60vh" :scroll-top="targetScrollTop">
|
||||||
|
<view class="js-item" v-for="(item, index) in jsList" :key="index"
|
||||||
|
:class="{ selected: item.selected }" @click="handleSelect(item)">
|
||||||
|
<view class="js-name">{{ item.label }}</view>
|
||||||
|
<BasicIcon type="checkmarkempty" v-if="item.selected" color="#333" />
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useCommonStore } from "@/store/modules/common";
|
||||||
|
const { getAllJs } = useCommonStore();
|
||||||
|
|
||||||
|
// 接收外部传入属性
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
modelValue?: any,
|
||||||
|
defaultValue?: any,
|
||||||
|
parentData?: any,
|
||||||
|
multiple?: boolean,
|
||||||
|
// 排除id列表
|
||||||
|
excludeIds?: any,
|
||||||
|
// 自定义配置
|
||||||
|
title?: string,
|
||||||
|
placeholder?: string,
|
||||||
|
searchPlaceholder?: string,
|
||||||
|
showSearch?: boolean
|
||||||
|
}>(), {
|
||||||
|
modelValue: null,
|
||||||
|
defaultValue: null,
|
||||||
|
parentData: null,
|
||||||
|
multiple: false,
|
||||||
|
excludeIds: [],
|
||||||
|
title: '请选择教师',
|
||||||
|
placeholder: '请选择老师',
|
||||||
|
searchPlaceholder: '输入教师名称查询',
|
||||||
|
showSearch: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 定义一个上级传入的emit响应事件用于接收数据变更
|
||||||
|
const emit = defineEmits(['change', 'update:modelValue'])
|
||||||
|
|
||||||
|
const targetScrollTop = ref(0); // 用于绑定 scroll-top
|
||||||
|
const showPopup = ref(false);
|
||||||
|
|
||||||
|
const jsListAll = ref<any>([]);
|
||||||
|
const jsList = ref<any>([]);
|
||||||
|
let searchKey = "";
|
||||||
|
|
||||||
|
const selectedList = ref<any>([]);
|
||||||
|
|
||||||
|
// 计算属性,用于 v-model 双向绑定
|
||||||
|
const currentValue = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加一个内部状态来跟踪当前值
|
||||||
|
const internalValue = ref(props.modelValue || props.defaultValue);
|
||||||
|
|
||||||
|
const getShowSelectedName = () => {
|
||||||
|
const names = selectedList.value.map((item: any) => item.label).join(",");
|
||||||
|
return names;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = (value: any) => {
|
||||||
|
searchKey = value;
|
||||||
|
rebuildJsList();
|
||||||
|
return
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (item: any) => {
|
||||||
|
if (props.multiple) {
|
||||||
|
// 多选模式:切换选中状态
|
||||||
|
const index = selectedList.value.findIndex((selected: any) => selected.value === item.value);
|
||||||
|
if (index > -1) {
|
||||||
|
// 取消选择:从选中列表中移除
|
||||||
|
selectedList.value.splice(index, 1);
|
||||||
|
item.selected = false;
|
||||||
|
} else {
|
||||||
|
// 新增选择:添加到选中列表末尾(保持选择顺序)
|
||||||
|
selectedList.value.push(item);
|
||||||
|
item.selected = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 单选模式:清除其他选中状态,设置当前选中
|
||||||
|
jsList.value.forEach((listItem: any) => listItem.selected = false);
|
||||||
|
selectedList.value = [item];
|
||||||
|
item.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
showPopup.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOk = () => {
|
||||||
|
showPopup.value = false;
|
||||||
|
let result;
|
||||||
|
if (props.multiple) {
|
||||||
|
result = selectedList.value;
|
||||||
|
} else {
|
||||||
|
result = selectedList.value[0] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 v-model 值
|
||||||
|
currentValue.value = result;
|
||||||
|
|
||||||
|
// 触发 change 事件
|
||||||
|
emit("change", result, props.parentData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showPicker = () => {
|
||||||
|
showPopup.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const rebuildJsList = () => {
|
||||||
|
jsList.value = [];
|
||||||
|
jsListAll.value.forEach((item: any) => {
|
||||||
|
if (props.excludeIds && props.excludeIds.length && props.excludeIds.includes(item.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 判断教师姓名jsxm包含搜索关键词
|
||||||
|
if (!searchKey || item.jsxm.includes(searchKey)) {
|
||||||
|
jsList.value.push({
|
||||||
|
label: item.jsxm,
|
||||||
|
value: item.id,
|
||||||
|
headPic: item.headPic,
|
||||||
|
selected: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 恢复选中状态
|
||||||
|
restoreSelection();
|
||||||
|
};
|
||||||
|
|
||||||
|
const restoreSelection = () => {
|
||||||
|
if (!selectedList.value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按照selectedList的顺序恢复选中状态,保持选择顺序
|
||||||
|
jsList.value.forEach((item: any) => {
|
||||||
|
const isSelected = selectedList.value.some((selected: any) => selected.value === item.value);
|
||||||
|
item.selected = isSelected;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
showPicker,
|
||||||
|
open: showPicker,
|
||||||
|
close: () => showPopup.value = false
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const res = await getAllJs()
|
||||||
|
jsListAll.value = res.result || [];
|
||||||
|
|
||||||
|
rebuildJsList();
|
||||||
|
|
||||||
|
// 等待下一个tick确保jsList已经构建完成
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
const initialValue = internalValue.value || props.defaultValue;
|
||||||
|
|
||||||
|
if (initialValue) {
|
||||||
|
setInitialValue(initialValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置初始值的函数
|
||||||
|
const setInitialValue = (value: any) => {
|
||||||
|
if (!jsList.value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.multiple) {
|
||||||
|
if (!Array.isArray(value) || !value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedList.value = [];
|
||||||
|
|
||||||
|
// 先清空所有选中状态
|
||||||
|
jsList.value.forEach((item: any) => {
|
||||||
|
item.selected = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理不同类型的输入值
|
||||||
|
let processedValue = value;
|
||||||
|
|
||||||
|
// 如果输入的是对象数组(如{0: {value: '1001', label: '张三'}, 1: {value: '1002', label: '李四'}})
|
||||||
|
if (value[0] && typeof value[0] === 'object' && (value[0].value || value[0].id)) {
|
||||||
|
processedValue = value.map((item: any) => item.value || item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按照传入值的顺序设置选中状态,保持选择顺序
|
||||||
|
selectedList.value = [];
|
||||||
|
|
||||||
|
// 遍历传入的值,按照顺序查找对应的项目
|
||||||
|
processedValue.forEach((id: any) => {
|
||||||
|
const foundItem = jsList.value.find((item: any) => item.value === id || item.id === id);
|
||||||
|
if (foundItem) {
|
||||||
|
foundItem.selected = true;
|
||||||
|
selectedList.value.push(foundItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清空其他未选中的项目
|
||||||
|
jsList.value.forEach((item: any) => {
|
||||||
|
if (!processedValue.includes(item.value) && !processedValue.includes(item.id)) {
|
||||||
|
item.selected = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 单选模式
|
||||||
|
|
||||||
|
// 清空所有选中状态
|
||||||
|
jsList.value.forEach((item: any) => {
|
||||||
|
item.selected = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理不同类型的输入值
|
||||||
|
let processedValue = value;
|
||||||
|
if (value && typeof value === 'object' && (value.value || value.id)) {
|
||||||
|
processedValue = value.value || value.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查value是否匹配当前项的value或id
|
||||||
|
const targetItem = jsList.value.find((item: any) => item.value === processedValue || item.id === processedValue);
|
||||||
|
if (targetItem) {
|
||||||
|
targetItem.selected = true;
|
||||||
|
selectedList.value = [targetItem];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果selectedList仍然为空,尝试从jsListAll中查找
|
||||||
|
if (selectedList.value.length === 0 && value && Array.isArray(value)) {
|
||||||
|
selectedList.value = [];
|
||||||
|
|
||||||
|
// 处理不同类型的输入值
|
||||||
|
let processedValue = value;
|
||||||
|
if (value[0] && typeof value[0] === 'object' && (value[0].value || value[0].id)) {
|
||||||
|
processedValue = value.map((item: any) => item.value || item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
processedValue.forEach((id: any) => {
|
||||||
|
const foundItem = jsListAll.value.find((item: any) => item.id === id);
|
||||||
|
if (foundItem) {
|
||||||
|
const itemForList = {
|
||||||
|
label: foundItem.jsxm,
|
||||||
|
value: foundItem.id,
|
||||||
|
headPic: foundItem.headPic,
|
||||||
|
selected: true
|
||||||
|
};
|
||||||
|
selectedList.value.push(itemForList);
|
||||||
|
|
||||||
|
// 同时更新jsList中对应项的选中状态
|
||||||
|
const jsListItem = jsList.value.find((item: any) => item.value === foundItem.id);
|
||||||
|
if (jsListItem) {
|
||||||
|
jsListItem.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 监听 modelValue 变化,同步到内部状态
|
||||||
|
watch(() => props.modelValue, (newValue) => {
|
||||||
|
if (newValue !== internalValue.value) {
|
||||||
|
internalValue.value = newValue;
|
||||||
|
// 立即尝试设置值,如果jsList还没准备好,会在jsList变化时再次尝试
|
||||||
|
if (jsList.value.length > 0) {
|
||||||
|
setInitialValue(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
|
// 监听 defaultValue 变化
|
||||||
|
watch(() => props.defaultValue, (newValue) => {
|
||||||
|
if (newValue && jsList.value.length > 0) {
|
||||||
|
setInitialValue(newValue);
|
||||||
|
}
|
||||||
|
}, { immediate: false });
|
||||||
|
|
||||||
|
// 监听 jsList 变化,当jsList构建完成后设置初始值
|
||||||
|
watch(() => jsList.value, (newJsList) => {
|
||||||
|
if (newJsList.length > 0) {
|
||||||
|
const initialValue = internalValue.value || props.defaultValue;
|
||||||
|
|
||||||
|
if (initialValue) {
|
||||||
|
setInitialValue(initialValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { immediate: false });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.basic-js-picker {
|
||||||
|
flex: 1;
|
||||||
|
.js-selected {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.js-selected-name {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.js-picker-popup {
|
||||||
|
min-height: 50vh;
|
||||||
|
max-height: 90vh;
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.js-picker-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: bold;
|
||||||
|
.js-cancel-btn {
|
||||||
|
flex: 0 0 50;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
.js-ok-btn {
|
||||||
|
flex: 0 0 50;
|
||||||
|
padding: 5px 10px;
|
||||||
|
color: #3c9cff;
|
||||||
|
}
|
||||||
|
.js-picker-title {
|
||||||
|
flex: 1 0 1px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.js-picker-search {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.js-list {
|
||||||
|
flex: 1 0 1px;
|
||||||
|
.js-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
&.selected {
|
||||||
|
background-color: beige;
|
||||||
|
}
|
||||||
|
.js-name {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -35,7 +35,14 @@ function deletePic(event: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps(['modelValue'])
|
// 添加 beforeUpload prop
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: String,
|
||||||
|
beforeUpload: {
|
||||||
|
type: Function,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (props.modelValue) {
|
if (props.modelValue) {
|
||||||
@ -67,6 +74,12 @@ async function afterRead(event: any) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
for (let i = 0; i < lists.length; i++) {
|
for (let i = 0; i < lists.length; i++) {
|
||||||
|
if (props.beforeUpload && !props.beforeUpload(lists[i])) {
|
||||||
|
// 如果 beforeUpload 返回 false,移除该文件并跳过上传
|
||||||
|
data.fileList.splice(fileListLen + i, 1)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
showLoading({title: '上传中'})
|
showLoading({title: '上传中'})
|
||||||
const res:any = await attachmentUpload(lists[i].url)
|
const res:any = await attachmentUpload(lists[i].url)
|
||||||
const result = res.result
|
const result = res.result
|
||||||
|
|||||||
@ -179,14 +179,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/routine/GongWenLiuZhuan/index",
|
"path": "pages/view/routine/gwlz/gwDetail",
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "公文流转",
|
|
||||||
"enablePullDownRefresh": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/view/routine/GongWenLiuZhuan/detail",
|
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "公文详情",
|
"navigationBarTitleText": "公文详情",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
@ -195,21 +188,21 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/view/routine/gwlz/gwAdd",
|
"path": "pages/view/routine/gwlz/gwAdd",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "公文列表",
|
"navigationBarTitleText": "公文调整",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/routine/gwlz/index",
|
"path": "pages/view/routine/gwlz/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "公文接收",
|
"navigationBarTitleText": "公文列表",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/view/routine/gwlz/gwFlow",
|
"path": "pages/view/routine/gwlz/gwFlow",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "公文流转",
|
"navigationBarTitleText": "公文审批",
|
||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -344,6 +344,7 @@ const sections = reactive<Section[]>([
|
|||||||
permissionKey: "routine-gwlz", // 公文流转权限编码
|
permissionKey: "routine-gwlz", // 公文流转权限编码
|
||||||
path: "/pages/view/routine/gwlz/index",
|
path: "/pages/view/routine/gwlz/index",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: "hr3",
|
id: "hr3",
|
||||||
icon: "gz",
|
icon: "gz",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
210
src/pages/view/routine/gwlz/gwDetail.vue
Normal file
210
src/pages/view/routine/gwlz/gwDetail.vue
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
<template>
|
||||||
|
<BasicLayout>
|
||||||
|
<view class="px-15 pb-15">
|
||||||
|
<BasicForm @register="register" :readonly="true"> </BasicForm>
|
||||||
|
</view>
|
||||||
|
</BasicLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { navigateTo } from "@/utils/uniapp";
|
||||||
|
import { useForm } from "@/components/BasicForm/hooks/useForm";
|
||||||
|
import { findDicTreeByPidApi } from "@/api/system/dic";
|
||||||
|
import { gwFindByIdApi } from "@/api/routine/gw";
|
||||||
|
import { useDicStore } from "@/store/modules/dic";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
const { findByPid } = useDicStore();
|
||||||
|
|
||||||
|
// 公文ID
|
||||||
|
const gwId = ref<string>('');
|
||||||
|
|
||||||
|
// 表单配置
|
||||||
|
const [register, { setValue, setSchema }] = useForm({
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
title: "公文信息",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "title",
|
||||||
|
label: "公文标题",
|
||||||
|
component: "BasicInput",
|
||||||
|
componentProps: {
|
||||||
|
placeholder: "公文标题",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "docType",
|
||||||
|
label: "公文类型",
|
||||||
|
component: "BasicPicker",
|
||||||
|
componentProps: {
|
||||||
|
api: findByPid,
|
||||||
|
param: { pid: "2146632731" }, // 公文类型字典
|
||||||
|
rangeKey: "dictionaryValue",
|
||||||
|
savaKey: "dictionaryCode",
|
||||||
|
placeholder: "公文类型",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "urgencyLevel",
|
||||||
|
label: "紧急程度",
|
||||||
|
component: "BasicPicker",
|
||||||
|
componentProps: {
|
||||||
|
api: findByPid,
|
||||||
|
param: { pid: "2146632735" }, // 紧急程度字典
|
||||||
|
rangeKey: "dictionaryValue",
|
||||||
|
savaKey: "dictionaryCode",
|
||||||
|
placeholder: "紧急程度",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "fileUrl",
|
||||||
|
label: "附件",
|
||||||
|
component: "BasicUpload",
|
||||||
|
componentProps: {
|
||||||
|
multiple: false,
|
||||||
|
accept: "*/*",
|
||||||
|
maxCount: 1,
|
||||||
|
disabled: true,
|
||||||
|
limit: 1,
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "remark",
|
||||||
|
label: "备注",
|
||||||
|
component: "BasicInput",
|
||||||
|
componentProps: {
|
||||||
|
placeholder: "备注信息",
|
||||||
|
type: "textarea",
|
||||||
|
rows: 3,
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "审批设置",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "spId",
|
||||||
|
label: "审批人",
|
||||||
|
component: "BasicJsPicker",
|
||||||
|
componentProps: {
|
||||||
|
multiple: true,
|
||||||
|
placeholder: "审批人",
|
||||||
|
title: "审批人",
|
||||||
|
searchPlaceholder: "输入教师姓名搜索",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "ccId",
|
||||||
|
label: "抄送人",
|
||||||
|
component: "BasicJsPicker",
|
||||||
|
componentProps: {
|
||||||
|
multiple: true,
|
||||||
|
placeholder: "抄送人",
|
||||||
|
title: "抄送人",
|
||||||
|
searchPlaceholder: "输入教师姓名搜索",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "tjrName",
|
||||||
|
label: "提交人",
|
||||||
|
component: "BasicInput",
|
||||||
|
componentProps: {
|
||||||
|
placeholder: "提交人",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "tjrtime",
|
||||||
|
label: "提交时间",
|
||||||
|
component: "BasicInput",
|
||||||
|
componentProps: {
|
||||||
|
placeholder: "提交时间",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "gwStatus",
|
||||||
|
label: "公文状态",
|
||||||
|
component: "BasicInput",
|
||||||
|
componentProps: {
|
||||||
|
placeholder: "公文状态",
|
||||||
|
readonly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面加载完成 - 使用onLoad获取路由参数
|
||||||
|
onLoad((options: any) => {
|
||||||
|
console.log('页面加载,路由参数:', options);
|
||||||
|
|
||||||
|
if (options && options.id) {
|
||||||
|
gwId.value = options.id;
|
||||||
|
getGwDetail();
|
||||||
|
} else {
|
||||||
|
console.error('未获取到公文ID参数');
|
||||||
|
uni.showToast({
|
||||||
|
title: "参数错误",
|
||||||
|
icon: "error",
|
||||||
|
});
|
||||||
|
// 返回上一页
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取公文详情
|
||||||
|
const getGwDetail = async () => {
|
||||||
|
try {
|
||||||
|
const response = await gwFindByIdApi({ id: gwId.value });
|
||||||
|
|
||||||
|
if (response && response.result) {
|
||||||
|
const gwData = response.result;
|
||||||
|
|
||||||
|
// 设置表单值
|
||||||
|
await setValue({
|
||||||
|
title: gwData.title || '',
|
||||||
|
docType: gwData.docType || '',
|
||||||
|
urgencyLevel: gwData.urgencyLevel || '',
|
||||||
|
fileUrl: gwData.fileUrl || '',
|
||||||
|
fileName: gwData.fileName || '',
|
||||||
|
fileFormat: gwData.fileFormat || '',
|
||||||
|
remark: gwData.remark || '',
|
||||||
|
spId: gwData.spId ? gwData.spId.split(',').filter((id: string) => id.trim()) : [],
|
||||||
|
ccId: gwData.ccId ? gwData.ccId.split(',').filter((id: string) => id.trim()) : [],
|
||||||
|
tjrName: gwData.tjrxm || gwData.tjrName || '',
|
||||||
|
tjrtime: gwData.tjrtime || '',
|
||||||
|
gwStatus: getStatusText(gwData.gwStatus || ''),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取公文详情失败:", error);
|
||||||
|
uni.showToast({
|
||||||
|
title: "获取详情失败",
|
||||||
|
icon: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
const statusMap: Record<string, string> = {
|
||||||
|
'A': "暂存",
|
||||||
|
'B': "提交",
|
||||||
|
};
|
||||||
|
return statusMap[status] || "未知";
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// 详情页面样式
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user