rcs5.0 commit
This commit is contained in:
Vendored
+570
@@ -0,0 +1,570 @@
|
||||
import request from '@/http/request.js';
|
||||
import {
|
||||
callGetFile,
|
||||
} from '@/http/api.call';
|
||||
// 使用示例: const res = await this.$apis.pubQueryComboxData(data)
|
||||
|
||||
// 交易簿记/ 现金流预览
|
||||
export const getdcsPreviewCashflows = (data) => {
|
||||
return request({
|
||||
url: 'dcs/flow/previewCashflows.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 新增获取id
|
||||
export const getdcsDealNo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getDealNo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 操作风险
|
||||
export const getdcsdealActionFlow = (data) => {
|
||||
return request({
|
||||
url: 'dcs/flow/dealActionFlow.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 快速查询列表
|
||||
export const getdealQueryqueryPage = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/dealQuery/queryPage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 现金流 现金流
|
||||
export const getdcsQueryCashFlowList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryCashFlow.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 现金流 定盘
|
||||
export const getdcsQueryObserveList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/dealQuery/queryObserveList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 提交
|
||||
export const handledcsdealActionFlow = (data) => {
|
||||
return request({
|
||||
url: 'dcs/flow/dealActionFlow.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 是否节假日
|
||||
export const getdcsisHolidayByUnderlying = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/isHolidayByUnderlying.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/ 按钮权限
|
||||
export const getdcsdoGetFolderAuth = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/doGetFolderAuth.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记/账户信息
|
||||
export const getDCSqueryCptyName = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryCptyName.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 交易簿记/交易对手
|
||||
export const getDCSqueryFolderById = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryFolderById.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记
|
||||
export const getDCSdoEvaluation = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/doEvaluation.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记
|
||||
export const getDCSgetSystemDate = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getSystemDate.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易簿记
|
||||
export const querySettle = (data) => {
|
||||
return request({
|
||||
url: 'settle6-web/query_settle.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 交易簿记
|
||||
export const getdealQueryQueryList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/dealQuery/queryList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 交易簿记
|
||||
export const getDcsOptions = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 交易簿记 获取即期汇率
|
||||
export const getdcsPairInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getPairInfo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 交易簿记 获取起息日
|
||||
export const getdcsValueDate = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getValueDate.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 参数审批-统计接口
|
||||
export const getParamsStaList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/doQueryNumber.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-待处理接口
|
||||
export const getParamsList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/doQueryPageWaiting.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-已处理接口
|
||||
export const getFinishList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/doQueryPageFinish.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-已拒绝接口
|
||||
export const getRefuseList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/doQueryPageRefuse.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-我发起接口
|
||||
export const getInitiateList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/doQueryPageMine.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 参数审批-批量审核
|
||||
export const batchCheck = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/approveBatch.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-审批状态字典
|
||||
export const getApproveData = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-获取流程操作按钮
|
||||
export const getUserFlowOperations = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/getUserFlowOperations.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-获取审批流程日志
|
||||
export const getFlowLogBySerialNoRepeat = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/getFlowLogBySerialNoRepeat.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 参数审批-获取变更数据
|
||||
export const getFlowCompareData = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/eflowCompareData.action', // ?dealNo=174194761864137
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-退回发起下拉获取
|
||||
export const getBackList = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 参数审批-退回发起提交
|
||||
export const backSubmit = (data) => {
|
||||
return request({
|
||||
url: 'eflow/flow/approve.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 存续期事件管理 列表查询
|
||||
export const getEventList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryPage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 存续期事件管理 撤销
|
||||
export const batchRevoke = (data) => {
|
||||
return request({
|
||||
url: '',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 发送异常管理 补发
|
||||
export const batchSendAgain = (data) => {
|
||||
return request({
|
||||
url: 'dcs/pub/sendExceptionReissue.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 发送异常管理 报文内容保存
|
||||
export const messageSave = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/doUpdate.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// queryParam.moduleName:"pubSendExceptionManager","queryParam.domain":"{"id":"20250327_1df210eb-a865-4a6b-accf-8db487d2508c","messageContent":{}}
|
||||
// 获取数据源-通用
|
||||
export const queryComboxData = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 获取数据源-债券检索
|
||||
export const queryBondList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryBondList.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 获取数据源-交易对手
|
||||
export const queryCptyPage = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryCptyPage.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 获取数据源-账户/账户组
|
||||
export const queryFolderQueryAuthList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryFolderQueryAuthList.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 自定义交易查询接口
|
||||
export const dcsQueryPage = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryPage.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询结果-产品表头
|
||||
export const queryFieldByProduct = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryFieldByProduct.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询-获取自定义查询组合
|
||||
export const queryList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryList.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
//
|
||||
export const pubqueryList = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/queryList.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询-保存自定义查询组合
|
||||
export const doSave = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/doSave.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询-删除自定义查询组合
|
||||
export const doDelete = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/doDelete.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询结果-账户详情
|
||||
export const getFolderInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getFolderInfo.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 导出
|
||||
export const exportData = (data) => {
|
||||
return request({
|
||||
url: 'dcs/baseQuery/exportAll.action',
|
||||
method: 'post',
|
||||
// headers: { 'Content-Type': 'multipart/form-data' },
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 下载模板
|
||||
export const downLoadTemplate = callGetFile('pub/baseData/downloadTemplate.action');
|
||||
// export const downLoadTemplate = (data) => {
|
||||
// return axios.request({
|
||||
// url: 'pub/baseData/downloadTemplate.action',
|
||||
// method: 'get',
|
||||
// data,
|
||||
// });
|
||||
// };
|
||||
|
||||
// 导入校验
|
||||
export const importCheck = (data) => {
|
||||
return request({
|
||||
url: 'pub/baseData/importCheck.action',
|
||||
method: 'post',
|
||||
// headers: { 'Content-Type': 'multipart/form-data' },
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 确认导入
|
||||
export const importData = (data) => {
|
||||
return request({
|
||||
url: 'pub/baseData/importData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 查询导入结果
|
||||
export const getProcess = (data) => {
|
||||
return request({
|
||||
url: 'pub/baseData/queryResult.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const getPosOptions = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 外汇账户明细字典
|
||||
export const getForList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryComboxData.action?codifierGrpCodes=static_currencies,FolderStatus,AccountingSection,HomeType',
|
||||
method: 'get',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 自定义交易查询结果-账户详情
|
||||
export const queryDealOperateLog = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryDealOperateLog.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易模块查询历史版本
|
||||
export const getCompareVersionLog = (data) => {
|
||||
return request({
|
||||
url: 'dcs/getCompareVersionLog.action',
|
||||
method: 'get',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 公共模块查询历史版本详细信息
|
||||
export const compareVersionLog = (data) => {
|
||||
return request({
|
||||
url: 'dcs/compareVersionLog.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取历史版本版本号列表
|
||||
export const versionsLogCombox = (data) => {
|
||||
return request({
|
||||
url: 'dcs/versionsLogCombox.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取历史头寸配置
|
||||
export const getOneQueryComponent = (data) => {
|
||||
return request({
|
||||
url: 'pos/pub/getOneQueryComponent.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取登录账户
|
||||
export const getUserInfo = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/getUserInfo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取登录用户信息
|
||||
export const findPreferenceDtoByUserIdAndType = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/findPreferenceDtoByUserIdAndType.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 历史头寸获取时间
|
||||
export const getPosSystemDate = (data) => {
|
||||
return request({
|
||||
url: 'pos/baseRcs/getSystemDate.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易主要信息
|
||||
export const getQueryMainInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryMainInfo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易派生信息
|
||||
export const getQueryDeriveInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryDeriveInfo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易审批信息
|
||||
export const getQueryAuditInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryAuditInfo.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易收据模板
|
||||
export const queryDealReceipt = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryDealReceipt.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易跟踪记录
|
||||
export const queryDealTrace = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryDealTrace.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 交易收据数据
|
||||
export const queryDealQueryList = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/dealQuery/queryList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// 导入所有模块api
|
||||
const modules = require.context('./', true, /.js/);
|
||||
|
||||
const apis = {};
|
||||
modules.keys().forEach(item => {
|
||||
if (item !== './index.js') {
|
||||
let api = modules(item);
|
||||
if (api.default) {
|
||||
api = { ...api, ...api.default };
|
||||
delete api.default;
|
||||
}
|
||||
for (const key in api) {
|
||||
if (apis[key]) { // 请求方法名不能重复
|
||||
throw new Error(`error: api method repeat!!! method---->${key}`);
|
||||
} else {
|
||||
apis[key] = api[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
export default apis;
|
||||
Vendored
+118
@@ -0,0 +1,118 @@
|
||||
import request from '@/http/request.js';
|
||||
|
||||
/**
|
||||
* 评级信息列表获取
|
||||
* @returns
|
||||
*/
|
||||
export const msdQueryPage = (data) => {
|
||||
return request({
|
||||
url: 'mds/baseData/queryPage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 评级目标 */
|
||||
|
||||
export const msdQueryComboxData = (data) => {
|
||||
return request({
|
||||
url: 'mds/baseRcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
/** 交易对手评级 */
|
||||
export const mdsFindAllCptysi18n = () => {
|
||||
return request({
|
||||
url: 'mds/sdscounterparty/findAllCptysi18n.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
|
||||
/** 发行人评级 */
|
||||
export const mdsFindAllIssuerCptysi18n = () => {
|
||||
return request({
|
||||
url: 'mds/sdscounterparty/findAllIssuerCptysi18n.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
/** 债券评级 */
|
||||
export const mdsFindAllbonds = () => {
|
||||
return request({
|
||||
url: 'mds/sdsbonds/findAllbonds.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
/** 国家评级 */
|
||||
export const mdsFindAllCountries = () => {
|
||||
return request({
|
||||
url: 'mds/sdsthirdparty/findAllCountries.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
/** 担保人评级 */
|
||||
export const mdsFindAllGuarantees = () => {
|
||||
return request({
|
||||
url: 'mds/sdscounterparty/findAllGuarantees.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
|
||||
/** 评级机构 */
|
||||
|
||||
export const msdFindRatingAgenciesByContainsTermRating = () => {
|
||||
return request({
|
||||
url: 'mds/sdsrating/findRatingAgenciesByContainsTermRating.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
|
||||
export const msdFindRatingByAgencyIdAndTerm = (data) => {
|
||||
return request({
|
||||
url: 'mds/sdsrating/findRatingByAgencyIdAndTerm.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
export const msdHistoryQueryPage = (data) => {
|
||||
return request({
|
||||
url: 'mds/baseData/queryPage.action?queryParam.moduleName=mdsTargetRatingsHistory',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 数据集查询
|
||||
export const msdFindAllDataSet = () => {
|
||||
return request({
|
||||
url: 'mds/mds/findAllDataSet.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
|
||||
// 数据类型
|
||||
export const msdQueryComboxDataAction = (data) => {
|
||||
return request({
|
||||
url: `mds/baseRcs/queryComboxData.action?codifierGrpCodes=${data}`,
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
|
||||
// 数据集管理列表
|
||||
export const msdBaseQueryPage = (data) => {
|
||||
return request({
|
||||
url: 'mds/baseData/queryPage.action?queryParam.moduleName=mdsDataRicSetService',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 数据源
|
||||
export const mdsFindAllDataSource = () => {
|
||||
return request({
|
||||
url: 'mds/mds/findAllDataSource.action',
|
||||
method: 'post',
|
||||
});
|
||||
};
|
||||
Vendored
+220
@@ -0,0 +1,220 @@
|
||||
import request from '@/http/request.js';
|
||||
|
||||
// 获取数据源-通用
|
||||
export const pmsQueryComboxData = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询数据源PMS服务
|
||||
export const queryComboxDataPMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/baseRcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取系统日期
|
||||
export const getSystemDate = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getSystemDate.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// pms服务获取系统日期
|
||||
export const getSystemDatePMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/getSystemDate.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 期权计算器-获取日期
|
||||
export const getValueDate = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getValueDate.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// pms服务获取日期
|
||||
export const getValueDatePMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/getValueDate.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 期权计算器-获取日期间隔
|
||||
export const getbetweenDays = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getbetweenDays.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// pms服务查询日期间隔
|
||||
export const getbetweenDaysPMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/getbetweenDays.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 期权计算器-获取金额
|
||||
export const getPairInfo = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getPairInfo.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// pms服务查询金额
|
||||
export const getPairInfoPMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/getPairInfo.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 期权计算器-获取QuantoPairs
|
||||
export const getQuantoPairs = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getQuantoPairs.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-获取Model
|
||||
export const getModelByParam = (data) => {
|
||||
return request({
|
||||
url: 'pms/getModelByParam.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-获取市场数据
|
||||
export const findMarketInfoForAnalysis = (data) => {
|
||||
return request({
|
||||
url: 'mds/mds/findMarketInfoForAnalysis.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-获取市场价格
|
||||
export const findMarketPriceForValAnalysis = (data) => {
|
||||
return request({
|
||||
url: 'mds/findMarketPriceForValAnalysis.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-保存市场价格
|
||||
export const saveMarketPriceForValAnalysis = (data) => {
|
||||
return request({
|
||||
url: 'mds/saveMarketPriceForValAnalysis.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-估值
|
||||
export const simulationValuationAnalysis = (data) => {
|
||||
return request({
|
||||
url: 'mds/simulationValuationAnalysis.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-试算
|
||||
export const simulateDealWithVlParam = (data) => {
|
||||
return request({
|
||||
url: 'mds/simulateDealWithVlParam.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-获取定价列表
|
||||
export const createObs = (data) => {
|
||||
return request({
|
||||
url: 'pms/createObs.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 期权计算器-获取执行价
|
||||
export const getPoints = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/getPoints.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// pms服务查询执行价
|
||||
export const getPointsPMS = (data) => {
|
||||
return request({
|
||||
url: 'pms/getForwardRate.action',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 逐笔估值结果查询-获取数据源
|
||||
export const baseRcsQueryComboxData = (data) => {
|
||||
return request({
|
||||
url: 'pms/baseRcs/queryComboxData.action',
|
||||
method: 'post',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 逐笔估值结果查询-获取列表
|
||||
export const pmsQueryPage = (data) => {
|
||||
return request({
|
||||
url: 'pms/pmsone/queryPage.action',
|
||||
method: 'post',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 逐笔估值结果查询-重估值
|
||||
export const reDoCalcFont = (data) => {
|
||||
return request({
|
||||
url: 'pms/pms/reDoCalcFont.action',
|
||||
method: 'post',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 逐笔估值结果查询-查看估值中间数据
|
||||
export const pmsFindPmsResultDetail = (data) => {
|
||||
return request({
|
||||
url: 'pms/pmsFindPmsResultDetailNew.action',
|
||||
method: 'post',
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
Vendored
+59
@@ -0,0 +1,59 @@
|
||||
|
||||
import request from '@/http/request.js';
|
||||
import { callPostFormFile, callPostAll, callPostFile } from '@/http/api.call';
|
||||
// 外汇即期单货币头寸
|
||||
export const getForeignCurrencyList = (data) => {
|
||||
return request({
|
||||
url: 'pos/equery.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 导出
|
||||
export const exportForData = callPostFormFile('/pos/equery.action');
|
||||
|
||||
// pv01头寸
|
||||
export const getPv01DataList = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/pv01DataQuery.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 外汇现金流查询
|
||||
export const getTtCashFlowList = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/queryTtCashFlow.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 期限列设置
|
||||
export const queryTerm = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/queryTerm.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取现金流期限列设置
|
||||
export const findPreferenceDtoByUserId = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/findPreferenceDtoByUserIdAndType.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 保存期限列设置
|
||||
export const updatePreferenceDto = (data) => {
|
||||
return request({
|
||||
url: 'pos/pos/updatePreferenceDto.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
import request from '@/http/request.js';
|
||||
|
||||
// 使用示例: const res = await this.$apis.pubQueryComboxData(data)
|
||||
// 获取数据源-公共
|
||||
export const pubQueryComboxData = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/queryComboxData.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 货币-查询接口
|
||||
export const queryPage = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/queryPage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 公共模块查询历史版本
|
||||
export const getCompareVersion = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/getCompareVersion.action',
|
||||
method: 'get',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 公共模块查询历史版本详细信息
|
||||
export const compare = (data) => {
|
||||
return request({
|
||||
url: 'pub/compare.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取历史版本版本号列表
|
||||
export const versionsCombox = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/versionsCombox.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 货币查询id
|
||||
export const findStaticDataId = (data) => {
|
||||
return request({
|
||||
url: 'pub/sdsthirdparty/findStaticDataId.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 节假日查询
|
||||
export const queryAll = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/queryAll.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 公共新增接口
|
||||
export const pubDoSave = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/doSave.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 公共编辑接口
|
||||
export const pubDoUpdate = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/doUpdate.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 接入数据管理-左侧树形数据
|
||||
export const getPacketTree = (data) => {
|
||||
return request({
|
||||
url: 'pub/pub/getPacketTree.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取数据源-交易对手
|
||||
export const queryCptyPage1 = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/queryCptyPage.action',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
Vendored
+198
@@ -0,0 +1,198 @@
|
||||
import request from '@/http/request.js';
|
||||
|
||||
// 消息提醒获取数据
|
||||
export const queryNormalMessageList = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/queryNormalMessageList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取异常消息处理
|
||||
export const queryErrorMessageList = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/queryErrorMessageList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取日成交交易table数据
|
||||
export const getDailyTradeQuery = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dailyTradeQuery.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取风险头寸图表数据
|
||||
export const queryRiskPositionByType = (data) => {
|
||||
return request({
|
||||
url: 'rsk-new/rsk/queryRiskPositionByType.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取市场风险图表数据
|
||||
export const getMarketRiskChart = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getMarketRiskChart',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取信用额度图表数据
|
||||
export const getCreditLimitChart = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getCreditLimitChart',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取授权占比图表数据
|
||||
export const getEmpowerChart = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getEmpowerChart',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取市场数据货币对价格
|
||||
export const queryPriceList = (data) => {
|
||||
return request({
|
||||
url: 'mds/desktop/queryPriceList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取货币对对应的历史数据
|
||||
export const queryHistoryPriceList = (data) => {
|
||||
return request({
|
||||
url: 'mds/hisprice/client/desktop/queryHistoryPriceList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取损益变动图表数据
|
||||
export const queryPlByType = (data) => {
|
||||
return request({
|
||||
url: 'rsk-new/rsk/queryPlByType.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取账户列表数据
|
||||
export const queryAllFolderInfo = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getFolderTree.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取损益货币
|
||||
export const getFolderPlCcy = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/getFolderPlCcy.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取资产情况表格数据
|
||||
export const queryPlChartByType = (data) => {
|
||||
return request({
|
||||
url: 'pos/queryPlChartByType.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取资产情况期限数据
|
||||
export const queryTermCash = (data) => {
|
||||
return request({
|
||||
url: 'dcs/queryCashFlowSumAmount.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取超限事件表格数据
|
||||
export const getOverEventChart = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/queryEventList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取交易审批table数据
|
||||
export const queryCommunicationMessage = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/queryCommunicationMessage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取结算发报table数据
|
||||
export const queryPaymentFlowProcessList = (data) => {
|
||||
return request({
|
||||
url: 'settle6-web/desktop/queryPaymentFlowProcessList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取收付审批列表
|
||||
export const queryPaymentFlowAuditList = (data) => {
|
||||
return request({
|
||||
url: 'settle6-web/desktop/queryPaymentFlowAuditList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取接口通讯列表
|
||||
export const getApiStatus = (data) => {
|
||||
return request({
|
||||
url: 'settle6-web/desktop/getApiStatus.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取当日全量数据
|
||||
export const queryDealAuditNum = (data) => {
|
||||
return request({
|
||||
url: 'settle6-web/desktop/queryDealAuditNum.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取机构
|
||||
export const querySiteList = (data) => {
|
||||
return request({
|
||||
url: 'pub/desktop/querySiteList.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
// 日成交交易
|
||||
export const queryDealPage = (data) => {
|
||||
return request({
|
||||
url: 'dcs/dcs/dealQuery/queryPage.action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
};
|
||||
+539
@@ -0,0 +1,539 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
+1617
File diff suppressed because it is too large
Load Diff
+297
@@ -0,0 +1,297 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4894712 */
|
||||
/* Color fonts */
|
||||
src:
|
||||
url('iconfont.woff2?t=1746004916794') format('woff2'),
|
||||
url('iconfont.woff?t=1746004916794') format('woff'),
|
||||
url('iconfont.ttf?t=1746004916794') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-copy:before {
|
||||
content: "\e79e";
|
||||
}
|
||||
|
||||
.icon-email:before {
|
||||
content: "\e78a";
|
||||
}
|
||||
|
||||
.icon-calendar:before {
|
||||
content: "\e7ed";
|
||||
}
|
||||
|
||||
.icon-folder-add:before {
|
||||
content: "\e80d";
|
||||
}
|
||||
|
||||
.icon-folder:before {
|
||||
content: "\e7f9";
|
||||
}
|
||||
|
||||
.icon-layers:before {
|
||||
content: "\e83c";
|
||||
}
|
||||
|
||||
.icon-dollar:before {
|
||||
content: "\e8b6";
|
||||
}
|
||||
|
||||
.icon-monitor:before {
|
||||
content: "\e985";
|
||||
}
|
||||
|
||||
.icon-link1:before {
|
||||
content: "\e789";
|
||||
}
|
||||
|
||||
.icon-information-query:before {
|
||||
content: "\e90b";
|
||||
}
|
||||
|
||||
.icon-batch-search:before {
|
||||
content: "\e977";
|
||||
}
|
||||
|
||||
.icon-a-marketrisk:before {
|
||||
content: "\e72f";
|
||||
}
|
||||
|
||||
.icon-trending-up:before {
|
||||
content: "\e7ae";
|
||||
}
|
||||
|
||||
.icon-trending-down:before {
|
||||
content: "\e7a9";
|
||||
}
|
||||
|
||||
.icon-liedingzhi:before {
|
||||
content: "\e787";
|
||||
}
|
||||
|
||||
.icon-research:before {
|
||||
content: "\e8b2";
|
||||
}
|
||||
|
||||
.icon-bank-card-fill:before {
|
||||
content: "\e9c6";
|
||||
}
|
||||
|
||||
.icon-fund-fill:before {
|
||||
content: "\e9b4";
|
||||
}
|
||||
|
||||
.icon-term-exposure-fill:before {
|
||||
content: "\e994";
|
||||
}
|
||||
|
||||
.icon-bank-card:before {
|
||||
content: "\e7e5";
|
||||
}
|
||||
|
||||
.icon-date-time:before {
|
||||
content: "\e7ef";
|
||||
}
|
||||
|
||||
.icon-doc-edit:before {
|
||||
content: "\e80c";
|
||||
}
|
||||
|
||||
.icon-chart-combo:before {
|
||||
content: "\e886";
|
||||
}
|
||||
|
||||
.icon-account:before {
|
||||
content: "\e8c4";
|
||||
}
|
||||
|
||||
.icon-bank:before {
|
||||
content: "\e8bd";
|
||||
}
|
||||
|
||||
.icon-trend1:before {
|
||||
content: "\e8b9";
|
||||
}
|
||||
|
||||
.icon-credit-risk:before {
|
||||
content: "\e98c";
|
||||
}
|
||||
|
||||
.icon-market-risk:before {
|
||||
content: "\e98a";
|
||||
}
|
||||
|
||||
.icon-operational-risk:before {
|
||||
content: "\e988";
|
||||
}
|
||||
|
||||
.icon-chaxunguanli:before {
|
||||
content: "\e783";
|
||||
}
|
||||
|
||||
.icon-toucunguanli:before {
|
||||
content: "\e784";
|
||||
}
|
||||
|
||||
.icon-jisuangongjv:before {
|
||||
content: "\e786";
|
||||
}
|
||||
|
||||
.icon-home:before {
|
||||
content: "\e731";
|
||||
}
|
||||
|
||||
.icon-refresh1:before {
|
||||
content: "\e72c";
|
||||
}
|
||||
|
||||
.icon-delete:before {
|
||||
content: "\e78c";
|
||||
}
|
||||
|
||||
.icon-filter:before {
|
||||
content: "\e790";
|
||||
}
|
||||
|
||||
.icon-save:before {
|
||||
content: "\e785";
|
||||
}
|
||||
|
||||
.icon-search:before {
|
||||
content: "\e788";
|
||||
}
|
||||
|
||||
.icon-user1:before {
|
||||
content: "\e7d9";
|
||||
}
|
||||
|
||||
.icon-batch-failure:before {
|
||||
content: "\e96f";
|
||||
}
|
||||
|
||||
.icon-components:before {
|
||||
content: "\e965";
|
||||
}
|
||||
|
||||
.icon-application1-fill:before {
|
||||
content: "\e9cd";
|
||||
}
|
||||
|
||||
.icon-edit-fill:before {
|
||||
content: "\e9bd";
|
||||
}
|
||||
|
||||
.icon-home-fill:before {
|
||||
content: "\e9ba";
|
||||
}
|
||||
|
||||
.icon-rmb-fill:before {
|
||||
content: "\e9a5";
|
||||
}
|
||||
|
||||
.icon-parameter-fill:before {
|
||||
content: "\e99f";
|
||||
}
|
||||
|
||||
.icon-yijujue:before {
|
||||
content: "\e781";
|
||||
}
|
||||
|
||||
.icon-yitongguo:before {
|
||||
content: "\e780";
|
||||
}
|
||||
|
||||
.icon-daishenpi:before {
|
||||
content: "\e782";
|
||||
}
|
||||
|
||||
.icon-yituihui:before {
|
||||
content: "\e77f";
|
||||
}
|
||||
|
||||
.icon-more2:before {
|
||||
content: "\e729";
|
||||
}
|
||||
|
||||
.icon-remind:before {
|
||||
content: "\e712";
|
||||
}
|
||||
|
||||
.icon-add:before {
|
||||
content: "\e79f";
|
||||
}
|
||||
|
||||
.icon-double_right:before {
|
||||
content: "\e7d0";
|
||||
}
|
||||
|
||||
.icon-double-left:before {
|
||||
content: "\e7d6";
|
||||
}
|
||||
|
||||
.icon-down:before {
|
||||
content: "\e7cb";
|
||||
}
|
||||
|
||||
.icon-down1:before {
|
||||
content: "\e7bd";
|
||||
}
|
||||
|
||||
.icon-left1:before {
|
||||
content: "\e7c6";
|
||||
}
|
||||
|
||||
.icon-left:before {
|
||||
content: "\e7a8";
|
||||
}
|
||||
|
||||
.icon-right:before {
|
||||
content: "\e7c1";
|
||||
}
|
||||
|
||||
.icon-right1:before {
|
||||
content: "\e7b8";
|
||||
}
|
||||
|
||||
.icon-attention:before {
|
||||
content: "\e867";
|
||||
}
|
||||
|
||||
.icon-fail:before {
|
||||
content: "\e868";
|
||||
}
|
||||
|
||||
.icon-help:before {
|
||||
content: "\e869";
|
||||
}
|
||||
|
||||
.icon-success:before {
|
||||
content: "\e86b";
|
||||
}
|
||||
|
||||
.icon-caution:before {
|
||||
content: "\e86c";
|
||||
}
|
||||
|
||||
.icon-info:before {
|
||||
content: "\e86d";
|
||||
}
|
||||
|
||||
.icon-EUR:before {
|
||||
content: "\e633";
|
||||
}
|
||||
|
||||
.icon-meiguoguoqi:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.icon-zhongguoguoqi:before {
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+499
@@ -0,0 +1,499 @@
|
||||
{
|
||||
"id": "4894712",
|
||||
"name": "RCS-5.0",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "40904218",
|
||||
"name": "copy",
|
||||
"font_class": "copy",
|
||||
"unicode": "e79e",
|
||||
"unicode_decimal": 59294
|
||||
},
|
||||
{
|
||||
"icon_id": "40904240",
|
||||
"name": "email",
|
||||
"font_class": "email",
|
||||
"unicode": "e78a",
|
||||
"unicode_decimal": 59274
|
||||
},
|
||||
{
|
||||
"icon_id": "40904567",
|
||||
"name": "calendar",
|
||||
"font_class": "calendar",
|
||||
"unicode": "e7ed",
|
||||
"unicode_decimal": 59373
|
||||
},
|
||||
{
|
||||
"icon_id": "40904659",
|
||||
"name": "folder-add",
|
||||
"font_class": "folder-add",
|
||||
"unicode": "e80d",
|
||||
"unicode_decimal": 59405
|
||||
},
|
||||
{
|
||||
"icon_id": "40904674",
|
||||
"name": "folder",
|
||||
"font_class": "folder",
|
||||
"unicode": "e7f9",
|
||||
"unicode_decimal": 59385
|
||||
},
|
||||
{
|
||||
"icon_id": "40905078",
|
||||
"name": "layers",
|
||||
"font_class": "layers",
|
||||
"unicode": "e83c",
|
||||
"unicode_decimal": 59452
|
||||
},
|
||||
{
|
||||
"icon_id": "40906322",
|
||||
"name": "dollar",
|
||||
"font_class": "dollar",
|
||||
"unicode": "e8b6",
|
||||
"unicode_decimal": 59574
|
||||
},
|
||||
{
|
||||
"icon_id": "40907675",
|
||||
"name": "monitor",
|
||||
"font_class": "monitor",
|
||||
"unicode": "e985",
|
||||
"unicode_decimal": 59781
|
||||
},
|
||||
{
|
||||
"icon_id": "40904247",
|
||||
"name": "link1",
|
||||
"font_class": "link1",
|
||||
"unicode": "e789",
|
||||
"unicode_decimal": 59273
|
||||
},
|
||||
{
|
||||
"icon_id": "40907403",
|
||||
"name": "information-query",
|
||||
"font_class": "information-query",
|
||||
"unicode": "e90b",
|
||||
"unicode_decimal": 59659
|
||||
},
|
||||
{
|
||||
"icon_id": "40907711",
|
||||
"name": "batch-search",
|
||||
"font_class": "batch-search",
|
||||
"unicode": "e977",
|
||||
"unicode_decimal": 59767
|
||||
},
|
||||
{
|
||||
"icon_id": "32459477",
|
||||
"name": "market-risk",
|
||||
"font_class": "a-marketrisk",
|
||||
"unicode": "e72f",
|
||||
"unicode_decimal": 59183
|
||||
},
|
||||
{
|
||||
"icon_id": "40904404",
|
||||
"name": "trending-up",
|
||||
"font_class": "trending-up",
|
||||
"unicode": "e7ae",
|
||||
"unicode_decimal": 59310
|
||||
},
|
||||
{
|
||||
"icon_id": "40904409",
|
||||
"name": "trending-down",
|
||||
"font_class": "trending-down",
|
||||
"unicode": "e7a9",
|
||||
"unicode_decimal": 59305
|
||||
},
|
||||
{
|
||||
"icon_id": "44054370",
|
||||
"name": "liedingzhi",
|
||||
"font_class": "liedingzhi",
|
||||
"unicode": "e787",
|
||||
"unicode_decimal": 59271
|
||||
},
|
||||
{
|
||||
"icon_id": "40906335",
|
||||
"name": "research",
|
||||
"font_class": "research",
|
||||
"unicode": "e8b2",
|
||||
"unicode_decimal": 59570
|
||||
},
|
||||
{
|
||||
"icon_id": "40907821",
|
||||
"name": "bank-card-fill",
|
||||
"font_class": "bank-card-fill",
|
||||
"unicode": "e9c6",
|
||||
"unicode_decimal": 59846
|
||||
},
|
||||
{
|
||||
"icon_id": "40907834",
|
||||
"name": "fund-fill",
|
||||
"font_class": "fund-fill",
|
||||
"unicode": "e9b4",
|
||||
"unicode_decimal": 59828
|
||||
},
|
||||
{
|
||||
"icon_id": "40907871",
|
||||
"name": "term-exposure-fill",
|
||||
"font_class": "term-exposure-fill",
|
||||
"unicode": "e994",
|
||||
"unicode_decimal": 59796
|
||||
},
|
||||
{
|
||||
"icon_id": "40904437",
|
||||
"name": "bank-card",
|
||||
"font_class": "bank-card",
|
||||
"unicode": "e7e5",
|
||||
"unicode_decimal": 59365
|
||||
},
|
||||
{
|
||||
"icon_id": "40904566",
|
||||
"name": "date-time",
|
||||
"font_class": "date-time",
|
||||
"unicode": "e7ef",
|
||||
"unicode_decimal": 59375
|
||||
},
|
||||
{
|
||||
"icon_id": "40904652",
|
||||
"name": "doc-edit",
|
||||
"font_class": "doc-edit",
|
||||
"unicode": "e80c",
|
||||
"unicode_decimal": 59404
|
||||
},
|
||||
{
|
||||
"icon_id": "40905885",
|
||||
"name": "chart-combo",
|
||||
"font_class": "chart-combo",
|
||||
"unicode": "e886",
|
||||
"unicode_decimal": 59526
|
||||
},
|
||||
{
|
||||
"icon_id": "40906317",
|
||||
"name": "account",
|
||||
"font_class": "account",
|
||||
"unicode": "e8c4",
|
||||
"unicode_decimal": 59588
|
||||
},
|
||||
{
|
||||
"icon_id": "40906320",
|
||||
"name": "bank",
|
||||
"font_class": "bank",
|
||||
"unicode": "e8bd",
|
||||
"unicode_decimal": 59581
|
||||
},
|
||||
{
|
||||
"icon_id": "40906329",
|
||||
"name": "trend1",
|
||||
"font_class": "trend1",
|
||||
"unicode": "e8b9",
|
||||
"unicode_decimal": 59577
|
||||
},
|
||||
{
|
||||
"icon_id": "40907667",
|
||||
"name": "credit-risk",
|
||||
"font_class": "credit-risk",
|
||||
"unicode": "e98c",
|
||||
"unicode_decimal": 59788
|
||||
},
|
||||
{
|
||||
"icon_id": "40907670",
|
||||
"name": "market-risk",
|
||||
"font_class": "market-risk",
|
||||
"unicode": "e98a",
|
||||
"unicode_decimal": 59786
|
||||
},
|
||||
{
|
||||
"icon_id": "40907672",
|
||||
"name": "operational-risk",
|
||||
"font_class": "operational-risk",
|
||||
"unicode": "e988",
|
||||
"unicode_decimal": 59784
|
||||
},
|
||||
{
|
||||
"icon_id": "44024976",
|
||||
"name": "chaxunguanli",
|
||||
"font_class": "chaxunguanli",
|
||||
"unicode": "e783",
|
||||
"unicode_decimal": 59267
|
||||
},
|
||||
{
|
||||
"icon_id": "44024975",
|
||||
"name": "toucunguanli",
|
||||
"font_class": "toucunguanli",
|
||||
"unicode": "e784",
|
||||
"unicode_decimal": 59268
|
||||
},
|
||||
{
|
||||
"icon_id": "44024977",
|
||||
"name": "jisuangongjv",
|
||||
"font_class": "jisuangongjv",
|
||||
"unicode": "e786",
|
||||
"unicode_decimal": 59270
|
||||
},
|
||||
{
|
||||
"icon_id": "40903893",
|
||||
"name": "home",
|
||||
"font_class": "home",
|
||||
"unicode": "e731",
|
||||
"unicode_decimal": 59185
|
||||
},
|
||||
{
|
||||
"icon_id": "40903911",
|
||||
"name": "refresh1",
|
||||
"font_class": "refresh1",
|
||||
"unicode": "e72c",
|
||||
"unicode_decimal": 59180
|
||||
},
|
||||
{
|
||||
"icon_id": "40904228",
|
||||
"name": "delete",
|
||||
"font_class": "delete",
|
||||
"unicode": "e78c",
|
||||
"unicode_decimal": 59276
|
||||
},
|
||||
{
|
||||
"icon_id": "40904232",
|
||||
"name": "filter",
|
||||
"font_class": "filter",
|
||||
"unicode": "e790",
|
||||
"unicode_decimal": 59280
|
||||
},
|
||||
{
|
||||
"icon_id": "40904238",
|
||||
"name": "save",
|
||||
"font_class": "save",
|
||||
"unicode": "e785",
|
||||
"unicode_decimal": 59269
|
||||
},
|
||||
{
|
||||
"icon_id": "40904242",
|
||||
"name": "search",
|
||||
"font_class": "search",
|
||||
"unicode": "e788",
|
||||
"unicode_decimal": 59272
|
||||
},
|
||||
{
|
||||
"icon_id": "40904447",
|
||||
"name": "user1",
|
||||
"font_class": "user1",
|
||||
"unicode": "e7d9",
|
||||
"unicode_decimal": 59353
|
||||
},
|
||||
{
|
||||
"icon_id": "40907708",
|
||||
"name": "batch-failure",
|
||||
"font_class": "batch-failure",
|
||||
"unicode": "e96f",
|
||||
"unicode_decimal": 59759
|
||||
},
|
||||
{
|
||||
"icon_id": "40907732",
|
||||
"name": "components",
|
||||
"font_class": "components",
|
||||
"unicode": "e965",
|
||||
"unicode_decimal": 59749
|
||||
},
|
||||
{
|
||||
"icon_id": "40907812",
|
||||
"name": "application1-fill",
|
||||
"font_class": "application1-fill",
|
||||
"unicode": "e9cd",
|
||||
"unicode_decimal": 59853
|
||||
},
|
||||
{
|
||||
"icon_id": "40907832",
|
||||
"name": "edit-fill",
|
||||
"font_class": "edit-fill",
|
||||
"unicode": "e9bd",
|
||||
"unicode_decimal": 59837
|
||||
},
|
||||
{
|
||||
"icon_id": "40907837",
|
||||
"name": "home-fill",
|
||||
"font_class": "home-fill",
|
||||
"unicode": "e9ba",
|
||||
"unicode_decimal": 59834
|
||||
},
|
||||
{
|
||||
"icon_id": "40907851",
|
||||
"name": "rmb-fill",
|
||||
"font_class": "rmb-fill",
|
||||
"unicode": "e9a5",
|
||||
"unicode_decimal": 59813
|
||||
},
|
||||
{
|
||||
"icon_id": "40907853",
|
||||
"name": "parameter-fill",
|
||||
"font_class": "parameter-fill",
|
||||
"unicode": "e99f",
|
||||
"unicode_decimal": 59807
|
||||
},
|
||||
{
|
||||
"icon_id": "44024793",
|
||||
"name": "yijujue",
|
||||
"font_class": "yijujue",
|
||||
"unicode": "e781",
|
||||
"unicode_decimal": 59265
|
||||
},
|
||||
{
|
||||
"icon_id": "44024789",
|
||||
"name": "yitongguo",
|
||||
"font_class": "yitongguo",
|
||||
"unicode": "e780",
|
||||
"unicode_decimal": 59264
|
||||
},
|
||||
{
|
||||
"icon_id": "44024790",
|
||||
"name": "daishenpi",
|
||||
"font_class": "daishenpi",
|
||||
"unicode": "e782",
|
||||
"unicode_decimal": 59266
|
||||
},
|
||||
{
|
||||
"icon_id": "44024751",
|
||||
"name": "yituihui",
|
||||
"font_class": "yituihui",
|
||||
"unicode": "e77f",
|
||||
"unicode_decimal": 59263
|
||||
},
|
||||
{
|
||||
"icon_id": "40903907",
|
||||
"name": "more2",
|
||||
"font_class": "more2",
|
||||
"unicode": "e729",
|
||||
"unicode_decimal": 59177
|
||||
},
|
||||
{
|
||||
"icon_id": "40903914",
|
||||
"name": "remind",
|
||||
"font_class": "remind",
|
||||
"unicode": "e712",
|
||||
"unicode_decimal": 59154
|
||||
},
|
||||
{
|
||||
"icon_id": "40904214",
|
||||
"name": "add",
|
||||
"font_class": "add",
|
||||
"unicode": "e79f",
|
||||
"unicode_decimal": 59295
|
||||
},
|
||||
{
|
||||
"icon_id": "40904365",
|
||||
"name": "double_right",
|
||||
"font_class": "double_right",
|
||||
"unicode": "e7d0",
|
||||
"unicode_decimal": 59344
|
||||
},
|
||||
{
|
||||
"icon_id": "40904369",
|
||||
"name": "double-left",
|
||||
"font_class": "double-left",
|
||||
"unicode": "e7d6",
|
||||
"unicode_decimal": 59350
|
||||
},
|
||||
{
|
||||
"icon_id": "40904373",
|
||||
"name": "down",
|
||||
"font_class": "down",
|
||||
"unicode": "e7cb",
|
||||
"unicode_decimal": 59339
|
||||
},
|
||||
{
|
||||
"icon_id": "40904376",
|
||||
"name": "down1",
|
||||
"font_class": "down1",
|
||||
"unicode": "e7bd",
|
||||
"unicode_decimal": 59325
|
||||
},
|
||||
{
|
||||
"icon_id": "40904380",
|
||||
"name": "left1",
|
||||
"font_class": "left1",
|
||||
"unicode": "e7c6",
|
||||
"unicode_decimal": 59334
|
||||
},
|
||||
{
|
||||
"icon_id": "40904383",
|
||||
"name": "left",
|
||||
"font_class": "left",
|
||||
"unicode": "e7a8",
|
||||
"unicode_decimal": 59304
|
||||
},
|
||||
{
|
||||
"icon_id": "40904386",
|
||||
"name": "right",
|
||||
"font_class": "right",
|
||||
"unicode": "e7c1",
|
||||
"unicode_decimal": 59329
|
||||
},
|
||||
{
|
||||
"icon_id": "40904392",
|
||||
"name": "right1",
|
||||
"font_class": "right1",
|
||||
"unicode": "e7b8",
|
||||
"unicode_decimal": 59320
|
||||
},
|
||||
{
|
||||
"icon_id": "40905242",
|
||||
"name": "attention",
|
||||
"font_class": "attention",
|
||||
"unicode": "e867",
|
||||
"unicode_decimal": 59495
|
||||
},
|
||||
{
|
||||
"icon_id": "40905243",
|
||||
"name": "fail",
|
||||
"font_class": "fail",
|
||||
"unicode": "e868",
|
||||
"unicode_decimal": 59496
|
||||
},
|
||||
{
|
||||
"icon_id": "40905244",
|
||||
"name": "help",
|
||||
"font_class": "help",
|
||||
"unicode": "e869",
|
||||
"unicode_decimal": 59497
|
||||
},
|
||||
{
|
||||
"icon_id": "40905246",
|
||||
"name": "success",
|
||||
"font_class": "success",
|
||||
"unicode": "e86b",
|
||||
"unicode_decimal": 59499
|
||||
},
|
||||
{
|
||||
"icon_id": "40905247",
|
||||
"name": "caution",
|
||||
"font_class": "caution",
|
||||
"unicode": "e86c",
|
||||
"unicode_decimal": 59500
|
||||
},
|
||||
{
|
||||
"icon_id": "40905248",
|
||||
"name": "info",
|
||||
"font_class": "info",
|
||||
"unicode": "e86d",
|
||||
"unicode_decimal": 59501
|
||||
},
|
||||
{
|
||||
"icon_id": "7524460",
|
||||
"name": "EUR",
|
||||
"font_class": "EUR",
|
||||
"unicode": "e633",
|
||||
"unicode_decimal": 58931
|
||||
},
|
||||
{
|
||||
"icon_id": "10956897",
|
||||
"name": "美国国旗",
|
||||
"font_class": "meiguoguoqi",
|
||||
"unicode": "e610",
|
||||
"unicode_decimal": 58896
|
||||
},
|
||||
{
|
||||
"icon_id": "41751543",
|
||||
"name": "中国国旗",
|
||||
"font_class": "zhongguoguoqi",
|
||||
"unicode": "e632",
|
||||
"unicode_decimal": 58930
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+109
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-bind="$attrs"
|
||||
:class="{'rcs_dialog': true, 'padding_empty': $attrs.paddingempty, 'hidden_title': $attrs.hiddentitle}"
|
||||
>
|
||||
<template
|
||||
v-for="(_, name) in $slots"
|
||||
#[name]
|
||||
>
|
||||
<slot :name="name" />
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="title">
|
||||
<div class="context">{{ $attrs.title }}</div>
|
||||
<div class="right">
|
||||
<slot name="title-right" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'RCSDialog',
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.rcs_dialog {
|
||||
// el-dialog
|
||||
::v-deep .el-dialog {
|
||||
background-color: var(--bg-color-main-2);
|
||||
}
|
||||
::v-deep .el-dialog__header {
|
||||
padding: 0;
|
||||
}
|
||||
::v-deep .el-dialog__headerbtn {
|
||||
right: 16px;
|
||||
}
|
||||
::v-deep .el-dialog__footer {
|
||||
border-top: 1px solid var(--application-color-8);
|
||||
padding: 10px 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
::v-deep .el-dialog__body {
|
||||
// TODO 滚动栏宽度有 10 px。开启 overflow: scroll 之后 增加 UI 兼容处理 padding-right - 10px
|
||||
padding: 12px 2px 12px 12px !important;
|
||||
max-height: 522px;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.padding_empty {
|
||||
::v-deep .el-dialog__body {
|
||||
padding: 0 !important;
|
||||
scrollbar-width: none; /* 隐藏滚动条 */
|
||||
}
|
||||
::v-deep .el-dialog__body::-webkit-scrollbar {
|
||||
display: none; // 隐藏滚动条
|
||||
width: 0; // 置滚动条的宽度为 0 来隐藏
|
||||
}
|
||||
}
|
||||
.hidden_title {
|
||||
::v-deep .el-dialog__header {
|
||||
height: 0px !important;
|
||||
.title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// el-button
|
||||
::v-deep .el-button {
|
||||
width: 51px;
|
||||
height: 24px;
|
||||
font-size: 12px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 8px 16px 8px 16px;
|
||||
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
border-bottom: 1px solid var(--application-color-8);
|
||||
.context {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: var(--application-color-2);
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,530 @@
|
||||
<template>
|
||||
<div class="transfer-container">
|
||||
<div class="transfer-modal">
|
||||
<div class="transfer-header">
|
||||
<span class="transfer-title">{{ title }}</span>
|
||||
<span
|
||||
class="transfer-close"
|
||||
@click="onClose"
|
||||
>×</span>
|
||||
</div>
|
||||
|
||||
<div class="transfer-content">
|
||||
<div class="transfer-panel source-panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-header-inner">
|
||||
<span class="checkbox-wrapper">
|
||||
<input
|
||||
ref="allCheckbox"
|
||||
type="checkbox"
|
||||
:checked="isAllSourceChecked"
|
||||
:indeterminate="isIndeterminate"
|
||||
@change="toggleAllSource"
|
||||
>
|
||||
<span :class="{'checkbox-label': true, 'checkbox-select': sourceCheckedCount }">{{ sourceCheckedCount }}/{{ sourceData.length }} 项</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-search">
|
||||
<input
|
||||
v-model="sourceSearchText"
|
||||
type="text"
|
||||
placeholder="请输入搜索内容"
|
||||
>
|
||||
<span class="search-icon">⌕</span>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div
|
||||
v-for="(item, index) in filteredSourceData"
|
||||
:key="'source-' + item.value"
|
||||
class="panel-item"
|
||||
>
|
||||
<label class="checkbox-item">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="item.checked"
|
||||
@change="toggleItem(item)"
|
||||
>
|
||||
<span :class="{'item-label': true, 'item-select': item.checked}">{{ item.label }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-footer">
|
||||
<button
|
||||
class="btn-reset"
|
||||
@click="resetToPreset"
|
||||
>重置</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="transfer-panel target-panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-header-inner">
|
||||
<span>已选 {{ displayTargetData.length }} 项</span>
|
||||
<button
|
||||
class="btn-clear"
|
||||
@click="clearTarget"
|
||||
>全部清空</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<div
|
||||
v-for="(item, index) in displayTargetData"
|
||||
:key="'target-' + item.value"
|
||||
class="panel-item"
|
||||
>
|
||||
<span class="item-icon">⋮⋮</span>
|
||||
<span class="item-label">{{ item.label }}</span>
|
||||
<span
|
||||
class="item-remove"
|
||||
@click="removeItem(item)"
|
||||
>×</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="transfer-footer">
|
||||
<button
|
||||
class="btn-cancel"
|
||||
@click="onClose"
|
||||
>取消</button>
|
||||
<button
|
||||
class="btn-confirm"
|
||||
@click="onConfirm"
|
||||
>确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TransferList',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
presetSelected: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sourceData: [],
|
||||
targetData: [],
|
||||
sourceSearchText: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredSourceData() {
|
||||
if (!this.sourceSearchText) {
|
||||
return this.sourceData;
|
||||
}
|
||||
return this.sourceData.filter(item =>
|
||||
item.label.toLowerCase().includes(this.sourceSearchText.toLowerCase()),
|
||||
);
|
||||
},
|
||||
sourceCheckedCount() {
|
||||
return this.sourceData.filter(item => item.checked).length;
|
||||
},
|
||||
isAllSourceChecked() {
|
||||
return this.sourceData.length > 0 && this.sourceData.every(item => item.checked);
|
||||
},
|
||||
isIndeterminate() {
|
||||
const checkedCount = this.sourceCheckedCount;
|
||||
return checkedCount > 0 && checkedCount < this.sourceData.length;
|
||||
},
|
||||
displayTargetData() {
|
||||
const checkedSourceItems = this.sourceData
|
||||
.filter(item => item.checked)
|
||||
.map(item => ({ ...item, fromSource: true }));
|
||||
|
||||
const targetKeys = this.targetData.map(item => item.value);
|
||||
const uniqueCheckedItems = checkedSourceItems.filter(item => !targetKeys.includes(item.value));
|
||||
|
||||
return [...this.targetData, ...uniqueCheckedItems];
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initData();
|
||||
},
|
||||
},
|
||||
isIndeterminate: {
|
||||
handler(val) {
|
||||
if (this.$refs.allCheckbox) {
|
||||
this.$refs.allCheckbox.indeterminate = val;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.allCheckbox) {
|
||||
this.$refs.allCheckbox.indeterminate = this.isIndeterminate;
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
if (this.$refs.allCheckbox) {
|
||||
this.$refs.allCheckbox.indeterminate = this.isIndeterminate;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
const selectedKeys = this.value && this.value.length ? this.value : this.presetSelected || [];
|
||||
|
||||
this.targetData = this.data
|
||||
.filter(item => selectedKeys.includes(item.value))
|
||||
.map(item => ({ ...item }));
|
||||
|
||||
this.sourceData = this.data.map(item => ({
|
||||
...item,
|
||||
checked: selectedKeys.includes(item.value),
|
||||
}));
|
||||
},
|
||||
toggleItem(item) {
|
||||
item.checked = !item.checked;
|
||||
this.syncTargetWithChecked();
|
||||
this.emitChange();
|
||||
},
|
||||
toggleAllSource() {
|
||||
const newCheckedState = !this.isAllSourceChecked;
|
||||
|
||||
this.sourceData.forEach(item => {
|
||||
item.checked = newCheckedState;
|
||||
});
|
||||
|
||||
this.syncTargetWithChecked();
|
||||
this.emitChange();
|
||||
},
|
||||
syncTargetWithChecked() {
|
||||
const checkedKeys = this.sourceData
|
||||
.filter(item => item.checked)
|
||||
.map(item => item.value);
|
||||
|
||||
this.targetData = this.data
|
||||
.filter(item => checkedKeys.includes(item.value))
|
||||
.map(item => ({ ...item }));
|
||||
},
|
||||
resetToPreset() {
|
||||
const presetKeys = this.presetSelected || [];
|
||||
|
||||
this.sourceData.forEach(item => {
|
||||
item.checked = presetKeys.includes(item.value);
|
||||
});
|
||||
|
||||
this.targetData = this.data
|
||||
.filter(item => presetKeys.includes(item.value))
|
||||
.map(item => ({ ...item }));
|
||||
|
||||
this.sourceSearchText = '';
|
||||
this.emitChange();
|
||||
},
|
||||
clearTarget() {
|
||||
this.targetData = [];
|
||||
|
||||
this.sourceData.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
|
||||
this.emitChange();
|
||||
},
|
||||
removeItem(item) {
|
||||
const sourceItem = this.sourceData.find(sourceItem => sourceItem.value === item.value);
|
||||
if (sourceItem) {
|
||||
sourceItem.checked = false;
|
||||
}
|
||||
|
||||
const targetIndex = this.targetData.findIndex(targetItem => targetItem.value === item.value);
|
||||
if (targetIndex !== -1) {
|
||||
this.targetData.splice(targetIndex, 1);
|
||||
}
|
||||
|
||||
this.emitChange();
|
||||
},
|
||||
emitChange() {
|
||||
const selectedKeys = [];
|
||||
const selectedLabels = [];
|
||||
this.targetData.forEach(item => {
|
||||
selectedKeys.push(item.value);
|
||||
selectedLabels.push(item.label);
|
||||
});
|
||||
this.$emit('input', selectedKeys, selectedLabels);
|
||||
this.$emit('change', selectedKeys, selectedLabels);
|
||||
},
|
||||
onConfirm() {
|
||||
this.syncTargetWithChecked();
|
||||
this.$emit('confirm', this.targetData.map(item => item.value));
|
||||
},
|
||||
onClose() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transfer-container {
|
||||
// 预留 css variables
|
||||
--primary-color: #6AB2FF;
|
||||
--bg-color: #151e2e;
|
||||
--text-color: rgb(255, 255, 255, 0.9);
|
||||
--border-color: #434343;
|
||||
--item-hover-bg: #262626;
|
||||
--panel-bg: #1f1f1f;
|
||||
--button-primary-bg: #3389FF;
|
||||
--button-primary-color: rgb(255, 255, 255, 0.9);
|
||||
--button-default-bg: #151e2e;
|
||||
--button-default-color: rgb(255, 255, 255, 0.7);
|
||||
--modal-bg: #1f1f1f;
|
||||
--modal-header-bg: #141414;
|
||||
--checkbox-color: #177ddc;
|
||||
--select-text-color: #6AB2FF;
|
||||
}
|
||||
|
||||
.transfer {
|
||||
&-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
&-modal {
|
||||
width: 700px;
|
||||
background-color: var(--modal-bg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||||
box-shadow: 0px 8px 16px -8px rgba(0, 0, 0, 0.13), 0px 12px 32px rgba(0, 0, 0, 0.13), 0px 16px 48px rgba(0, 0, 0, 0.2);
|
||||
background-color: rgba(20, 29, 40, 1);
|
||||
}
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 9px 16px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
&-close {
|
||||
font-size: 22px;
|
||||
color: var(--text-color);
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
gap: 12px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-panel {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
height: 490px;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
padding: 10px 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
&-header {
|
||||
padding: 8px 12px;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
|
||||
&-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
|
||||
&-search {
|
||||
padding: 8px 12px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 12px;
|
||||
padding-right: 30px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
}
|
||||
|
||||
&-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 8px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--item-hover-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
padding: 8px 12px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 18px;
|
||||
color: var(--text-color);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
&-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&-label {
|
||||
margin-left: 8px;
|
||||
color: var(--text-color);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&-select {
|
||||
color: var(--select-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
&-icon {
|
||||
margin-right: 8px;
|
||||
color: var(--text-color);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&-label {
|
||||
flex: 1;
|
||||
margin-left: 8px;
|
||||
color: var(--text-color);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&-remove {
|
||||
color: var(--text-color);
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&-select {
|
||||
color: var(--select-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
accent-color: var(--checkbox-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn {
|
||||
&-reset, &-cancel {
|
||||
padding: 5px 16px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
background-color: var(--button-default-bg);
|
||||
color: var(--button-default-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-clear {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--primary-color);
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&-confirm {
|
||||
padding: 5px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: var(--button-primary-bg);
|
||||
color: var(--button-primary-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,657 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="visible"
|
||||
class="dialog-overlay"
|
||||
@click.self="handleCancel"
|
||||
>
|
||||
<div
|
||||
class="dialog-container"
|
||||
:class="{ 'theme-light': theme === 'light', 'theme-dark': theme === 'dark' }"
|
||||
>
|
||||
<div class="dialog-header">
|
||||
<span class="dialog-title">{{ title }}</span>
|
||||
<div class="header-actions">
|
||||
<button
|
||||
class="close-button"
|
||||
@click="handleCancel"
|
||||
>×</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-tabs">
|
||||
<div
|
||||
class="tab"
|
||||
:class="{ active: activeTab === 'account' }"
|
||||
@click="activeTab = 'account'"
|
||||
>
|
||||
账户
|
||||
</div>
|
||||
<div
|
||||
class="tab"
|
||||
:class="{ active: activeTab === 'accountGroup' }"
|
||||
@click="activeTab = 'accountGroup'"
|
||||
>
|
||||
账户组
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-container">
|
||||
<div class="search-input">
|
||||
<i class="search-icon">⚲</i>
|
||||
<div class="search-input-text">
|
||||
<input
|
||||
v-model="searchText"
|
||||
type="text"
|
||||
placeholder="输入关键词,可快速查找..."
|
||||
@input="filterTree"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账户标签内容 -->
|
||||
<div
|
||||
v-if="activeTab === 'account'"
|
||||
class="dialog-content"
|
||||
>
|
||||
<div class="tree-container">
|
||||
<el-tree
|
||||
ref="accountTree"
|
||||
:data="accountData"
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:expand-on-click-node="false"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
@node-click="handleNodeClick"
|
||||
>
|
||||
<span
|
||||
slot-scope="{ node, data }"
|
||||
class="custom-tree-node"
|
||||
@dblclick.stop="handleDoubleClick(data)"
|
||||
>
|
||||
<span class="node-title">{{ node.label.replace(/^.{1}@{2}/, '') }}</span>
|
||||
<span
|
||||
v-if="data.text"
|
||||
class="node-subtitle"
|
||||
>{{ data.text }}</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账户组标签内容 -->
|
||||
<div
|
||||
v-if="activeTab === 'accountGroup'"
|
||||
class="dialog-content"
|
||||
>
|
||||
<div class="account-group-list">
|
||||
<div
|
||||
v-for="(item, index) in filteredAccountGroups"
|
||||
:key="index"
|
||||
class="account-group-item"
|
||||
:class="{'selected': item.id == selectedItem?.id}"
|
||||
@click="selectItem(item)"
|
||||
@dblclick="handleDoubleClick(item)"
|
||||
>
|
||||
<span class="group-id">{{ item.value.replace(/^.{1}@{2}/, '') }}</span>
|
||||
<span class="group-name">{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-footer">
|
||||
<button
|
||||
class="btn-cancel"
|
||||
@click="handleCancel"
|
||||
>取消</button>
|
||||
<button
|
||||
class="btn-confirm"
|
||||
@click="handleConfirm"
|
||||
>确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TreeSearchDialog',
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 允许外部传入初始主题
|
||||
initialTheme: {
|
||||
type: String,
|
||||
default: 'dark', // 默认为暗色主题
|
||||
validator: (value) => ['dark', 'light'].includes(value),
|
||||
},
|
||||
accountData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
accountGroups: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// 默认展开的节点
|
||||
defaultExpandedKeys: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
theme: this.initialTheme,
|
||||
activeTab: 'account',
|
||||
searchText: '',
|
||||
selectedItem: null,
|
||||
filteredAccountGroups: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'value',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
if (val && this.$refs.accountTree) {
|
||||
// 当对话框显示时,重置过滤器
|
||||
this.$refs.accountTree.filter('');
|
||||
this.searchText = '';
|
||||
}
|
||||
},
|
||||
accountGroups: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initDataGroup();
|
||||
},
|
||||
},
|
||||
accountData: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initData();
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
initDataGroup() {
|
||||
this.filteredAccountGroups = [...this.accountGroups];
|
||||
},
|
||||
initData() {
|
||||
|
||||
},
|
||||
// 切换主题
|
||||
toggleTheme() {
|
||||
this.theme = this.theme === 'dark' ? 'light' : 'dark';
|
||||
this.$emit('theme-change', this.theme);
|
||||
},
|
||||
|
||||
// el-tree 的节点过滤方法
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
const searchTerm = value.toLowerCase();
|
||||
|
||||
// 检查节点标题和副标题
|
||||
return data.value.toLowerCase().includes(searchTerm) ||
|
||||
(data.text && data.text.toLowerCase().includes(searchTerm));
|
||||
},
|
||||
|
||||
// 处理搜索输入
|
||||
filterTree() {
|
||||
if (this.activeTab === 'account' && this.$refs.accountTree) {
|
||||
this.$refs.accountTree.filter(this.searchText);
|
||||
} else if (this.activeTab === 'accountGroup') {
|
||||
this.filterAccountGroups();
|
||||
}
|
||||
},
|
||||
|
||||
// 过滤账户组
|
||||
filterAccountGroups() {
|
||||
if (!this.searchText) {
|
||||
this.filteredAccountGroups = [...this.accountGroups];
|
||||
return;
|
||||
}
|
||||
|
||||
const searchTerm = this.searchText.toLowerCase();
|
||||
this.filteredAccountGroups = this.accountGroups.filter(group =>
|
||||
group.id.toLowerCase().includes(searchTerm) ||
|
||||
group.value.toLowerCase().includes(searchTerm) ||
|
||||
group.text.toLowerCase().includes(searchTerm),
|
||||
);
|
||||
},
|
||||
|
||||
// 处理节点点击
|
||||
handleNodeClick(data) {
|
||||
this.selectedItem = data;
|
||||
},
|
||||
|
||||
// 选择项目
|
||||
selectItem(data) {
|
||||
this.selectedItem = data;
|
||||
},
|
||||
|
||||
// 处理双击事件
|
||||
handleDoubleClick(data) {
|
||||
this.selectedItem = data;
|
||||
this.handleConfirm();
|
||||
},
|
||||
|
||||
// 取消按钮
|
||||
handleCancel() {
|
||||
this.$emit('cancel');
|
||||
},
|
||||
|
||||
// 确认按钮
|
||||
handleConfirm() {
|
||||
this.$emit('confirm', this.selectedItem);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 全局主题变量 */
|
||||
.dialog-overlay {
|
||||
/* 暗色主题变量 */
|
||||
--dark-bg-primary: #141D28;
|
||||
--dark-bg-secondary: #2c3347;
|
||||
--dark-bg-tertiary: #3a4257;
|
||||
--dark-tab-bg-primary: #212b39;
|
||||
--dark-text-primary: #ffffff;
|
||||
--dark-text-secondary: #8e8e8e;
|
||||
--dark-border: #2c3347;
|
||||
--dark-accent: #3a8ee6;
|
||||
--dark-hover: rgba(255, 255, 255, 0.05);
|
||||
--dark-selected: rgba(255, 255, 255, 0.1);
|
||||
|
||||
/* 亮色主题变量 */
|
||||
--light-bg-primary: #ffffff;
|
||||
--light-bg-secondary: #f5f7fa;
|
||||
--light-bg-tertiary: #e4e7ed;
|
||||
--light-tab-bg-primary: #ffffff;
|
||||
--light-text-primary: #303133;
|
||||
--light-text-secondary: #606266;
|
||||
--light-border: #dcdfe6;
|
||||
--light-accent: #409eff;
|
||||
--light-hover: rgba(0, 0, 0, 0.05);
|
||||
--light-selected: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* 主题相关样式 */
|
||||
.dialog-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 暗色主题 */
|
||||
.theme-dark {
|
||||
background-color: var(--dark-bg-primary);
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
/* 亮色主题 */
|
||||
.theme-light {
|
||||
background-color: var(--light-bg-primary);
|
||||
color: var(--light-text-primary);
|
||||
}
|
||||
|
||||
.dialog-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 16px;
|
||||
}
|
||||
|
||||
.theme-dark .dialog-header {
|
||||
border-bottom: 1px solid var(--dark-border);
|
||||
}
|
||||
|
||||
.theme-light .dialog-header {
|
||||
border-bottom: 1px solid var(--light-border);
|
||||
}
|
||||
|
||||
.dialog-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.theme-dark .close-button {
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light .close-button {
|
||||
color: var(--light-text-secondary);
|
||||
}
|
||||
|
||||
.dialog-tabs {
|
||||
display: flex;
|
||||
padding: 2px;
|
||||
margin: 12px 16px;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.theme-dark .dialog-tabs {
|
||||
background-color: var(--dark-tab-bg-primary);
|
||||
}
|
||||
|
||||
.theme-light .dialog-tabs {
|
||||
background-color: var(--light-tab-bg-primary);
|
||||
}
|
||||
|
||||
.tab {
|
||||
cursor: pointer;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.theme-dark .tab {
|
||||
background-color: transparent;
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light .tab {
|
||||
background-color: transparent;
|
||||
color: var(--light-text-secondary);
|
||||
}
|
||||
|
||||
.theme-dark .tab.active {
|
||||
background-color: var(--dark-bg-secondary);
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
.theme-light .tab.active {
|
||||
background-color: var(--light-bg-secondary);
|
||||
color: var(--light-text-primary);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.search-input-text {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.theme-dark .search-icon {
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light .search-icon {
|
||||
color: var(--light-text-secondary);
|
||||
}
|
||||
|
||||
.search-input input {
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
padding: 8px 8px 8px 36px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.theme-dark .search-input input {
|
||||
background-color: transparent;
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
.theme-light .search-input input {
|
||||
background-color: transparent;
|
||||
color: var(--light-text-primary);
|
||||
}
|
||||
|
||||
.theme-dark .search-input input::placeholder {
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light .search-input input::placeholder {
|
||||
color: var(--light-text-secondary);
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
max-height: calc(90vh - 180px);
|
||||
}
|
||||
|
||||
.tree-container {
|
||||
padding: 0 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 自定义 el-tree 样式 */
|
||||
.theme-dark :deep(.el-tree) {
|
||||
background-color: transparent !important;
|
||||
color: var(--dark-text-primary) !important;
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree) {
|
||||
background-color: transparent !important;
|
||||
color: var(--light-text-primary) !important;
|
||||
}
|
||||
|
||||
.theme-dark :deep(.el-tree-node__content) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree-node__content) {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.theme-dark :deep(.el-tree-node__content:hover) {
|
||||
background-color: var(--dark-hover) !important;
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree-node__content:hover) {
|
||||
background-color: var(--light-hover) !important;
|
||||
}
|
||||
|
||||
.theme-dark :deep(.el-tree-node:focus > .el-tree-node__content) {
|
||||
background-color: var(--dark-selected) !important;
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree-node:focus > .el-tree-node__content) {
|
||||
background-color: var(--light-selected) !important;
|
||||
}
|
||||
|
||||
.theme-dark :deep(.el-tree-node__expand-icon) {
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree-node__expand-icon) {
|
||||
color: var(--light-text-secondary) !important;
|
||||
}
|
||||
|
||||
.theme-dark :deep(.el-tree-node__expand-icon.expanded) {
|
||||
color: var(--dark-text-primary) !important;
|
||||
}
|
||||
|
||||
.theme-light :deep(.el-tree-node__expand-icon.expanded) {
|
||||
color: var(--light-text-primary) !important;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.node-title {
|
||||
font-weight: 500;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.theme-dark .node-subtitle {
|
||||
color: var(--dark-text-secondary);
|
||||
}
|
||||
|
||||
.theme-light .node-subtitle {
|
||||
color: var(--light-text-secondary);
|
||||
}
|
||||
|
||||
.account-group-list {
|
||||
padding: 0 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.account-group-item {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-dark .account-group-item {
|
||||
border-bottom: 1px solid var(--dark-border);
|
||||
}
|
||||
|
||||
.theme-light .account-group-item {
|
||||
border-bottom: 1px solid var(--light-border);
|
||||
}
|
||||
|
||||
.theme-dark .account-group-item:hover {
|
||||
background-color: var(--dark-hover);
|
||||
}
|
||||
|
||||
.theme-light .account-group-item:hover {
|
||||
background-color: var(--light-hover);
|
||||
}
|
||||
|
||||
.theme-dark .account-group-item.selected {
|
||||
background-color: var(--dark-selected);
|
||||
}
|
||||
|
||||
.theme-light .account-group-item.selected {
|
||||
background-color: var(--light-selected);
|
||||
}
|
||||
|
||||
.theme-dark .account-group-item.highlighted {
|
||||
color: var(--dark-accent);
|
||||
}
|
||||
|
||||
.theme-light .account-group-item.highlighted {
|
||||
color: var(--light-accent);
|
||||
}
|
||||
|
||||
.group-id {
|
||||
margin-right: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-dark .group-name, .theme-dark .group-desc {
|
||||
color: var(--dark-text-secondary);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.theme-light .group-name, .theme-light .group-desc {
|
||||
color: var(--light-text-secondary);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.theme-dark .dialog-footer {
|
||||
border-top: 1px solid var(--dark-border);
|
||||
}
|
||||
|
||||
.theme-light .dialog-footer {
|
||||
border-top: 1px solid var(--light-border);
|
||||
}
|
||||
|
||||
.btn-cancel, .btn-confirm {
|
||||
padding: 6px 16px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.theme-dark .btn-cancel {
|
||||
background-color: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
.theme-light .btn-cancel {
|
||||
background-color: transparent;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
color: var(--light-text-primary);
|
||||
}
|
||||
|
||||
.theme-dark .btn-confirm {
|
||||
background-color: var(--dark-accent);
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
.theme-light .btn-confirm {
|
||||
background-color: var(--light-accent);
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="show"
|
||||
:title="configData.title"
|
||||
:modal-append-to-body="false"
|
||||
:width="`${percentWidth}%`"
|
||||
@close="handleCancel"
|
||||
>
|
||||
<PublicForm
|
||||
ref="publicForm"
|
||||
:form-arr="formArr"
|
||||
:form-data="formData"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<span
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<slot name="footerBtn" />
|
||||
<el-button
|
||||
type="default"
|
||||
:size="$buttonSize"
|
||||
@click="handleCancel"
|
||||
>取 消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:size="$buttonSize"
|
||||
@click="dialogOK"
|
||||
>保 存</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PublicForm from '@/components/form/index.vue';
|
||||
export default {
|
||||
components: {
|
||||
PublicForm,
|
||||
},
|
||||
props: {
|
||||
visible: { // 是否展示弹窗
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
formArr: { // 配置数组
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
percentWidth: { // 弹窗宽度
|
||||
type: Number,
|
||||
default: 30,
|
||||
},
|
||||
formData: { // 表单数据
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
/**
|
||||
* 配置对象
|
||||
* title 标题
|
||||
* addApi 新增接口
|
||||
* editApi 修改接口
|
||||
* type 1 新增 2 编辑
|
||||
* transFormData 参数处理方法
|
||||
* 默认 transformRequest: (params) => {
|
||||
return params;
|
||||
}
|
||||
*/
|
||||
configData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
visible: {
|
||||
handler(nv) {
|
||||
this.show = nv;
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleCancel() {
|
||||
console.log('我是formArr', this.formArr);
|
||||
this.$emit('handleCancel');
|
||||
},
|
||||
outOperation(val, index, prop, num) {
|
||||
console.log('我是outOperation', val, index, prop, num);
|
||||
},
|
||||
dialogOK() {
|
||||
// 判断表单验证是否通过
|
||||
if (this.$refs.publicForm.submitForm()) {
|
||||
console.log('success');
|
||||
console.log(this.formData);
|
||||
const api = { 1: this.$apis[this.configData.addApi], 2: this.$apis[this.configData.editApi] };
|
||||
const params = this.configData.transFormData(this.formData);
|
||||
api[this.configData.type](params).then(res => {
|
||||
this.$message.success('操作成功');
|
||||
this.$emit('dialogOK', res);
|
||||
});
|
||||
} else {
|
||||
console.log('error');
|
||||
this.$emit('dialogCancel');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .titiebox .titieboxlabel {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="value"
|
||||
class="cascader"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:options="formItems.options"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
v-bind="formItems.attrs"
|
||||
:props="{ expandTrigger: 'hover' }"
|
||||
v-on="formItems.events"
|
||||
@change="handleInput"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.cascader {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.el-input__icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
::v-deep .el-cascader--mini {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-checkbox-group
|
||||
v-model="value"
|
||||
class="checkbox"
|
||||
size="mini"
|
||||
:value="value"
|
||||
v-on="formItems.events"
|
||||
@change="handleChange($event)"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="(options, i) in formItems.options"
|
||||
:key="i"
|
||||
:label="options.label"
|
||||
>
|
||||
{{ options.value }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formItems: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.checkbox {
|
||||
min-height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep.el-checkbox .el-checkbox__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="列定制"
|
||||
:visible.sync="visibleDialog"
|
||||
width="640px"
|
||||
@close="columnClose"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="left-box">
|
||||
<div class="left-select">
|
||||
<el-checkbox
|
||||
v-model="checkAll"
|
||||
:indeterminate="isIndeterminate"
|
||||
@change="handleCheckAllChange"
|
||||
>{{ checkedItems.length }} / {{ tableColumn.length }}</el-checkbox>
|
||||
<el-checkbox-group
|
||||
v-model="checkedItems"
|
||||
class="check-list"
|
||||
@change="handleCheckedCitiesChange"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="item in tableColumn"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
>{{ item.label }}</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
<div class="left-bottom">
|
||||
<el-button
|
||||
:size="$buttonSize"
|
||||
@click="resetColumn"
|
||||
>恢复默认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-box">
|
||||
<div class="right-top">
|
||||
已选{{ checkedItems.length }}项
|
||||
<el-button
|
||||
type="text"
|
||||
:size="$buttonSize"
|
||||
@click="clearSelect"
|
||||
>全部清空</el-button>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="searchParams"
|
||||
placeholder="请输入搜索内容"
|
||||
>
|
||||
<template #suffix>
|
||||
<i
|
||||
class="search-icon el-icon-search"
|
||||
@click="searchColumns"
|
||||
/>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="select-columns">
|
||||
<div
|
||||
v-for="(item,index) in showItems"
|
||||
:key="item"
|
||||
class="select-li"
|
||||
draggable="true"
|
||||
@dragstart="onDragStart(index)"
|
||||
@dragover.prevent
|
||||
@drop="onDrop(index)"
|
||||
>
|
||||
<div class="li-left">
|
||||
<i class="el-icon-s-grid" />
|
||||
<div class="li-label">{{ item }}</div>
|
||||
</div>
|
||||
<!-- <img src="../../../public/images/close.svg"> -->
|
||||
<div class="icon-groups">
|
||||
<i
|
||||
class="el-icon-close"
|
||||
style="cursor:pointer;font-size:16px"
|
||||
@click="deleteItem(item)"
|
||||
/>
|
||||
<i
|
||||
class="el-icon-top"
|
||||
style="cursor:pointer;font-size:16px"
|
||||
@click="sortItem(item,index)"
|
||||
/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<el-button
|
||||
:size="$buttonSize"
|
||||
class="drawer-footer-cancel-btn"
|
||||
@click="columnClose"
|
||||
>取 消</el-button>
|
||||
<el-button
|
||||
:size="$buttonSize"
|
||||
class="drawer-footer-confirm-btn"
|
||||
type="primary"
|
||||
@click="handleCustomColumnConfirm"
|
||||
>保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
showDialog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
tableColumn: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleDialog: false,
|
||||
columnDialog: false,
|
||||
checked: false,
|
||||
checkAll: false,
|
||||
isIndeterminate: false,
|
||||
checkedItems: [],
|
||||
showItems: [],
|
||||
searchParams: '',
|
||||
draggedIndex: '',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
showDialog: {
|
||||
handler(nv) {
|
||||
this.visibleDialog = nv;
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
onDragStart(index) {
|
||||
this.draggedIndex = index;
|
||||
this.$nextTick(() => {
|
||||
const draggedItem = this.$el.querySelector(`.draggable-item:nth-child(${index + 1})`);
|
||||
draggedItem.classList.add('dragging');
|
||||
});
|
||||
console.log(index, 'dropStart');
|
||||
},
|
||||
onDrop(index) {
|
||||
console.log(index, 'drop');
|
||||
if (this.draggedIndex !== index) {
|
||||
const draggedItem = this.items.splice(this.draggedIndex, 1)[0];
|
||||
this.items.splice(index, 0, draggedItem);
|
||||
this.draggedIndex = null;
|
||||
|
||||
// 保存新顺序到服务器或本地存储
|
||||
// this.saveOrder();
|
||||
}
|
||||
},
|
||||
handleCheckAllChange(val) {
|
||||
this.checkedItems = val ? this.tableColumn.map(v => v.label) : [];
|
||||
this.showItems = [...this.checkedItems];
|
||||
this.isIndeterminate = false;
|
||||
},
|
||||
handleCheckedCitiesChange(value) {
|
||||
const checkedCount = value.length;
|
||||
this.showItems = [...this.checkedItems];
|
||||
this.checkAll = checkedCount === this.tableColumn.length;
|
||||
this.isIndeterminate = checkedCount > 0 && checkedCount < this.tableColumn.length;
|
||||
},
|
||||
resetColumn() { // 恢复默认
|
||||
|
||||
},
|
||||
searchColumns() {
|
||||
console.log(this.searchParams, 'searchParams');
|
||||
if (this.searchParams) {
|
||||
this.showItems = this.checkedItems.filter(v => v.includes(this.searchParams));
|
||||
} else {
|
||||
this.showItems = [...this.checkedItems];
|
||||
}
|
||||
},
|
||||
clearSelect() {
|
||||
this.checkedItems = [];
|
||||
this.showItems = [];
|
||||
this.isIndeterminate = false;
|
||||
this.checkAll = this.checkedItems === this.tableColumn.length;
|
||||
},
|
||||
columnClose() {
|
||||
this.visibleDialog = false;
|
||||
this.$emit('update:showDialog', false);
|
||||
this.searchParams = '';
|
||||
this.clearSelect();
|
||||
},
|
||||
deleteItem(item) {
|
||||
this.checkedItems = this.checkedItems.filter(v => v !== item);
|
||||
this.showItems = [...this.checkedItems];
|
||||
this.checkAll = this.checkedItems === this.tableColumn.length;
|
||||
this.isIndeterminate = this.checkedItems.length > 0 && this.checkedItems.length < this.tableColumn.length;
|
||||
},
|
||||
sortItem(item, index) {
|
||||
if (index > 0) {
|
||||
const arr = this.checkedItems;
|
||||
arr.splice(index - 1, 1, ...arr.splice(index, 1, arr[index - 1]));
|
||||
this.showItems = [...this.checkedItems];
|
||||
}
|
||||
},
|
||||
handleCustomColumnConfirm() {
|
||||
console.log(this.checkedItems, 'checkItems');
|
||||
this.columnClose();
|
||||
// this.$emit('customColumnChange', this.tableData);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content{
|
||||
display: flex;
|
||||
}
|
||||
.left-box {
|
||||
width:360px;
|
||||
height:490px;
|
||||
.left-select{
|
||||
padding: 8px 0 0 16px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--input-border);
|
||||
background-color: var(--desktop-bg-color-1);
|
||||
height:456px;
|
||||
.check-list{
|
||||
height:420px;
|
||||
line-height:20px;
|
||||
overflow:auto;
|
||||
margin-top:10px
|
||||
}
|
||||
}
|
||||
.left-bottom{
|
||||
border-radius: 0px 0px 2px 2px;
|
||||
border-left: 1px solid var(--input-border);
|
||||
border-right: 1px solid var(--input-border);
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
padding:5px 12px
|
||||
}
|
||||
}
|
||||
.right-box{
|
||||
border-radius: 2px;
|
||||
border: 1px solid var(--input-border);
|
||||
opacity: 1;
|
||||
width:240px;
|
||||
height:490px;
|
||||
background:var(--desktop-bg-color-1);
|
||||
margin-left:8px;
|
||||
padding:5px 12px;
|
||||
.right-top{
|
||||
display:flex;
|
||||
justify-content: space-between;
|
||||
color:var(--text-color-1);
|
||||
font-family: "SourceHanSansSC-Regular";
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
font-style: Regular;
|
||||
letter-spacing: 0px;
|
||||
text-align: left;
|
||||
line-height: 20px;
|
||||
}
|
||||
.select-columns{
|
||||
height:424px;
|
||||
overflow:auto;
|
||||
margin-top:8px;
|
||||
.select-li{
|
||||
height:28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.li-left{
|
||||
display:flex;
|
||||
align-items: center;
|
||||
}
|
||||
.select-li:hover{
|
||||
border-radius: 2px;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
.icon-groups{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.icon-groups{
|
||||
display: none;
|
||||
i+i{
|
||||
margin-left:5px
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-icon{
|
||||
font-size:16px;
|
||||
line-height: 30px;
|
||||
cursor:pointer;
|
||||
color:var(--text-color-1)
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="导出"
|
||||
:visible.sync="visibleDialog"
|
||||
width="400px"
|
||||
class="export-dialog"
|
||||
@close="close"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
label-width="60px"
|
||||
>
|
||||
<el-row>
|
||||
<el-form-item label="范围">
|
||||
<el-radio-group v-model="form.exportScope">
|
||||
<el-radio label="page">导出当前页</el-radio>
|
||||
<el-radio label="all">导出全部</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="类型">
|
||||
<el-radio-group v-model="form.exportType">
|
||||
<el-radio label="xls">Excel</el-radio>
|
||||
<el-radio label="csv">CSV</el-radio>
|
||||
<el-radio label="txt">TxT</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="btn"
|
||||
@click="submitExport"
|
||||
>{{
|
||||
$t("button.confirm")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { commonMore } from '../../utils/index';
|
||||
export default {
|
||||
props: {
|
||||
showDialog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
exportParams: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleDialog: false,
|
||||
form: {
|
||||
exportType: 'csv',
|
||||
exportScope: 'all',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
showDialog: {
|
||||
handler(nv) {
|
||||
this.visibleDialog = nv;
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
close() {
|
||||
console.log('关闭了');
|
||||
this.visibleDialog = false;
|
||||
this.$emit('update:showDialog', false);
|
||||
this.form = {
|
||||
exportType: 'csv',
|
||||
exportScope: 'all',
|
||||
};
|
||||
},
|
||||
async submitExport() {
|
||||
const params = { ...this.form, ...this.exportParams };
|
||||
if (this.form.exportScope === 'all') {
|
||||
delete params.pageStart;
|
||||
delete params.pageLimit;
|
||||
}
|
||||
console.log(params, 'ppp');
|
||||
const exportParams = commonMore.dataHandler(params);
|
||||
|
||||
const res = await this.$apis.exportData(exportParams);
|
||||
console.log(res, 'res');
|
||||
this.download(res.data.result);
|
||||
},
|
||||
download(ticket) {
|
||||
const action = window.origin.replace(/^https?:/, '') + '/dcs/baseQuery/download.action';
|
||||
// ticket = '8572f582-f927-40f1-b487-27ce3b4e5119'
|
||||
const url = `${action}?queryParam.ticket=${ticket}`;
|
||||
console.log(action, 'aaa');
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/vnd.ms-excel;charset=UTF-8',
|
||||
},
|
||||
})
|
||||
.then(async(response) => {
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(text);
|
||||
}
|
||||
// 关键:确保服务器暴露 Content-Disposition 头
|
||||
const contentDisposition = response.headers.get(
|
||||
'Content-Disposition',
|
||||
);
|
||||
let filename = '导出文件.csv'; // 默认值
|
||||
|
||||
if (contentDisposition) {
|
||||
// 关键步骤:提取并解码 Java URLEncoder 编码的文件名
|
||||
const filenameMatch = contentDisposition.match(
|
||||
/filename=("?)([^";]+)\1/i,
|
||||
);
|
||||
if (filenameMatch && filenameMatch[2]) {
|
||||
// 替换 "+" 为 "%20"(解决 Java URLEncoder 的空格编码问题)
|
||||
const encodedName = filenameMatch[2].replace(/\+/g, '%20');
|
||||
// 解码 URL 编码
|
||||
filename = decodeURIComponent(encodedName);
|
||||
}
|
||||
}
|
||||
return response.blob().then((blob) => ({ blob, filename }));
|
||||
})
|
||||
.then(({ blob, filename }) => {
|
||||
console.log(blob, filename, '文件信息');
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = filename; // 动态设置文件名
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('下载失败:', error);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.export-dialog{
|
||||
:deep(.el-form-item__content){
|
||||
line-height:40px
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 1k => 1000 1m => 1000000 1b => 1000000000
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
// 使用的小数位数的最小数目,可能的值是从 0 到 20
|
||||
minimumFractionDigits: {
|
||||
type: Number,
|
||||
default: 2,
|
||||
},
|
||||
// 使用的小数位数的最大数目。可能的值是从 0 到 20
|
||||
maximumFractionDigits: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(nVal) {
|
||||
if (nVal) {
|
||||
const val = nVal.toString();
|
||||
this.inputValue = this.inputValueCopy = this.changePercentile(val);
|
||||
} else {
|
||||
this.inputValue = this.inputValueCopy = '';
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
},
|
||||
handleBlur() {
|
||||
this.delcomma();
|
||||
let inputValue = this.inputValue;
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'k') {
|
||||
unit = 3;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 6;
|
||||
} else if (lastLetter === 'b') {
|
||||
unit = 9;
|
||||
}
|
||||
inputValue = num * Math.pow(10, unit);
|
||||
this.inputValue = this.changePercentile(inputValue);
|
||||
}
|
||||
console.log('blurNUm', inputValue);
|
||||
|
||||
this.$emit('input', inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.delcomma();
|
||||
},
|
||||
// 转换千分位
|
||||
changePercentile(val) {
|
||||
return val.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.minimumFractionDigits,
|
||||
maximumFractionDigits: this.maximumFractionDigits,
|
||||
});
|
||||
},
|
||||
// 去掉","号
|
||||
delcomma() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="foldbox">
|
||||
<div
|
||||
class="header"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<div class="header-icon"><icon-font
|
||||
:name="titleIcon"
|
||||
size="11"
|
||||
/></div>
|
||||
<div class="header-title">{{ title }}</div>
|
||||
<div class="header-rotate">
|
||||
<i
|
||||
v-if="!isOpen"
|
||||
class="el-icon-arrow-right"
|
||||
/>
|
||||
<i
|
||||
v-if="isOpen"
|
||||
class="el-icon-arrow-down"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="content"
|
||||
/>
|
||||
<slot :row="row" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: 'title',
|
||||
},
|
||||
titleIcon: {
|
||||
type: String,
|
||||
default: 'icon-research',
|
||||
},
|
||||
isOpen: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
row: {
|
||||
handler(nVal) {
|
||||
console.log('nValnVal---row11111122', nVal);
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.foldbox {
|
||||
margin-bottom: 8px;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
background-color: var(--card-bg);
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
font-weight: 800;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
.header-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
background-color: rgba(255, 255, 255, 0.13);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.header-title {
|
||||
margin-left: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.header-rotate {
|
||||
margin-left: 14px;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
margin-top: 10px;
|
||||
padding-top: 7px;
|
||||
width: 100%;
|
||||
border-top: 1px solid var(--card-border);
|
||||
}
|
||||
.fade-enter-active {
|
||||
transition: opacity 2s ease, height 2s ease;
|
||||
}
|
||||
.fade-leave-active {
|
||||
transition: opacity 0s, height 0s;
|
||||
}
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 文本 -->
|
||||
<CInput
|
||||
v-if="formItems.type === 'input'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 文本域 -->
|
||||
<CTextarea
|
||||
v-if="formItems.type==='textarea'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器 -->
|
||||
<CInputNumber
|
||||
v-if="formItems.type==='inputNumber'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器2 -->
|
||||
<CInputNumber2
|
||||
v-if="formItems.type==='inputNumber2'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择 (单选 多选) -->
|
||||
<CSelect
|
||||
v-if="formItems.type==='select'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 自定义列展示 -->
|
||||
<CSelectLabel
|
||||
v-if="formItems.type==='selectLabel'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 选择(单选 多选) 调接口 -->
|
||||
<CSelectApi
|
||||
v-if="formItems.type==='selectApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选) -->
|
||||
<CSelectTree
|
||||
v-if="formItems.type==='selectTree'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选)调接口 未完成 -->
|
||||
<CSelectTreeApi
|
||||
v-if="formItems.type==='selectTreeApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 金额(数字输入) -->
|
||||
<CInputFinance
|
||||
v-if="formItems.type==='inputFinance'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- input数字 年月日 -->
|
||||
<CInputDate
|
||||
v-if="formItems.type==='inputDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 周选择器 -->
|
||||
<CPickerWeek
|
||||
v-if="formItems.type==='pickerWeek'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 月选择器 -->
|
||||
<CPickerMonth
|
||||
v-if="formItems.type==='pickerMonth'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 年选择器 -->
|
||||
<CPickerYear
|
||||
v-if="formItems.type==='pickerYear'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 日期选择器 -->
|
||||
<CPickerDate
|
||||
v-if="formItems.type==='pickerDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<CPickerTime
|
||||
v-if="formItems.type==='pickerTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 时间范围选择器 -->
|
||||
<CPickerTimeRange
|
||||
v-if="formItems.type==='pickerTimeRange'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 日期时间选择器 -->
|
||||
<CPickerDateTime
|
||||
v-if="formItems.type==='pickerDateTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 日期时间范围选择器 -->
|
||||
<CPickerDateTimeRange
|
||||
v-if="formItems.type==='pickerDateTimeRange'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 单选 -->
|
||||
<CRadio
|
||||
v-if="formItems.type==='radio'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 多选 -->
|
||||
<CCheckbox
|
||||
v-if="formItems.type==='checkbox'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 开关 -->
|
||||
<CSwitch
|
||||
v-if="formItems.type==='switch'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 级联选择 -->
|
||||
<CCascader
|
||||
v-if="formItems.type==='cascader'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 穿梭 -->
|
||||
<CTransfer
|
||||
v-if="formItems.type==='transfer'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 选择-选择 -->
|
||||
<CSelectSelect
|
||||
v-if="formItems.type==='selectSelect'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 文本输入-选择 -->
|
||||
<CInputSelect
|
||||
v-if="formItems.type==='inputSelect'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 下拉懒加载 -->
|
||||
<CSelectLazyLoading
|
||||
v-if="formItems.type==='selectLazyLoading'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 日期选择器拆分单个日期 -->
|
||||
<CPickerDateSingle
|
||||
v-if="formItems.type==='pickerDateSingle'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<CSelectTable
|
||||
v-if="formItems.type==='selectTable'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 上传-->
|
||||
<!-- 穿梭框 -->
|
||||
<CSelectTransfer
|
||||
v-if="formItems.type==='selectTransfer'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 树结构 -->
|
||||
<CSelectTreeTable
|
||||
v-if="formItems.type==='selectTreeTable'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import CInput from '../input';
|
||||
import CTextarea from '../textarea';
|
||||
import CSelect from '../select';
|
||||
import CSelectLabel from '../selectLabel';
|
||||
import CSelectApi from '../selectApi';
|
||||
import CSelectTree from '../selectTree';
|
||||
import CSelectTreeApi from '../selectTreeApi';
|
||||
import CInputNumber from '../inputNumber';
|
||||
import CInputFinance from '../finance';
|
||||
import CInputDate from '../inputDate';
|
||||
import CPickerDate from '../pickerDate';
|
||||
import CPickerTime from '../pickerTime';
|
||||
import CPickerTimeRange from '../pickerTimeRange';
|
||||
import CPickerDateTime from '../pickerDateTime';
|
||||
import CPickerDateTimeRange from '../pickerDateTimeRange';
|
||||
import CPickerWeek from '../pickerWeek';
|
||||
import CPickerMonth from '../pickerMonth';
|
||||
import CPickerYear from '../pickerYear';
|
||||
import CRadio from '../radio';
|
||||
import CCheckbox from '../checkbox';
|
||||
import CSwitch from '../switch';
|
||||
import CCascader from '../cascader';
|
||||
import CTransfer from '../transfer';
|
||||
import CSelectSelect from '../select-select';
|
||||
import CInputNumber2 from '../inputNumber2';
|
||||
import CInputSelect from '../input-select';
|
||||
import CSelectLazyLoading from '../selectLazyLoading';
|
||||
import CPickerDateSingle from '../pickerDateSingle';
|
||||
import CSelectTable from '../selectTable/index';
|
||||
import CSelectTransfer from '../selectTransfer/index';
|
||||
import CSelectTreeTable from '../selectTreeTable/index';
|
||||
export default {
|
||||
name: 'FormItem',
|
||||
components: {
|
||||
CInput,
|
||||
CTextarea,
|
||||
CSelect,
|
||||
CSelectApi,
|
||||
CSelectTree,
|
||||
CSelectTreeApi,
|
||||
CInputNumber,
|
||||
CInputFinance,
|
||||
CInputDate,
|
||||
CPickerDate,
|
||||
CPickerTime,
|
||||
CPickerTimeRange,
|
||||
CPickerDateTime,
|
||||
CPickerDateTimeRange,
|
||||
CRadio,
|
||||
CCheckbox,
|
||||
CSwitch,
|
||||
CCascader,
|
||||
CTransfer,
|
||||
CSelectSelect,
|
||||
CInputNumber2,
|
||||
CInputSelect,
|
||||
CSelectLazyLoading,
|
||||
CPickerDateSingle,
|
||||
CSelectLabel,
|
||||
CPickerYear,
|
||||
CPickerWeek,
|
||||
CPickerMonth,
|
||||
CSelectTable,
|
||||
CSelectTransfer,
|
||||
CSelectTreeTable,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// formItems: {},
|
||||
// formData: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// formItems(newval) {
|
||||
// this.formItems = newval;
|
||||
// },
|
||||
// formData(newval) {
|
||||
// this.formData = newval;
|
||||
// },
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
outOperation(val, num) {
|
||||
this.$emit('outOperation', val, num);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<el-form ref="ruleForm" :model="formData" class="demo-ruleForm" inline>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(formItems, index) in formObj"
|
||||
v-show="!formItems.notShow"
|
||||
:span="formItems.span"
|
||||
:key="index"
|
||||
>
|
||||
<el-form-item
|
||||
:label="null"
|
||||
:prop="formItems.prop"
|
||||
:rules="formItems.rules"
|
||||
label-width="80px"
|
||||
>
|
||||
|
||||
<!-- 文件上传 -->
|
||||
<!-- 如果对象有值就回显,没有值就为空 -->
|
||||
<el-upload
|
||||
v-if="formobj.upload"
|
||||
:ref="formobj.prop"
|
||||
:accept="formobj.accept ? formobj.accept : 'PNG,JPEG'"
|
||||
:file-list="formData[formobj.prop] ? formData[formobj.prop] : []"
|
||||
:action="`${uploadUrl}${
|
||||
formobj.uploadObj.fileType ? formobj.uploadObj.fileType : ''
|
||||
}`"
|
||||
:limit="formobj.uploadObj.limit"
|
||||
:class="{
|
||||
hide:
|
||||
formobj.uploadObj.hideUpload ||
|
||||
formData[formobj.prop].length == formobj.uploadObj.limit,
|
||||
}"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:on-remove="
|
||||
(file, fileList) =>
|
||||
handleRemove(
|
||||
file,
|
||||
fileList,
|
||||
formobj.uploadObj.limit,
|
||||
formobj.prop,
|
||||
index
|
||||
)
|
||||
"
|
||||
:on-success="
|
||||
(response, file, fileList) =>
|
||||
uploadSuccess(
|
||||
response,
|
||||
file,
|
||||
fileList,
|
||||
formobj.uploadObj.limit,
|
||||
formobj.prop,
|
||||
index
|
||||
)
|
||||
"
|
||||
list-type="picture-card"
|
||||
:auto-upload="true"
|
||||
>
|
||||
<i slot="default" class="el-icon-plus" />
|
||||
</el-upload>
|
||||
|
||||
<el-dialog
|
||||
v-if="formobj.upload"
|
||||
:visible.sync="dialogVisible"
|
||||
:append-to-body="true"
|
||||
width="40%"
|
||||
>
|
||||
<img width="100%" :src="dialogImageUrl" alt="" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- text展示 -->
|
||||
<span v-if="formobj.text" v-text="formData[formobj.prop]" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormItem from "./formItem.vue";
|
||||
export default {
|
||||
components: {
|
||||
FormItem,
|
||||
},
|
||||
props: {
|
||||
formObj: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
searchSelectOptionsCb: {
|
||||
type: Array,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uploadUrl: "",
|
||||
dialogImageUrl: "",
|
||||
searchSelectLoading: false,
|
||||
dialogVisible: false,
|
||||
disabled: false,
|
||||
searchShow: "", //高德地图input收索联想
|
||||
setSearchVal: [], //高德地图赋值搜索内容
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
watch: {},
|
||||
methods: {
|
||||
//select变化调用
|
||||
selectChange(value, index, prop) {
|
||||
this.$emit("selectChange", value, index, prop);
|
||||
},
|
||||
// input的input事件
|
||||
inputINPUT(value, index, prop) {
|
||||
this.$emit("inputINPUT", value, index, prop);
|
||||
},
|
||||
// input的change事件
|
||||
inputChange(value, index, prop) {
|
||||
this.$emit("inputChange", value, index, prop);
|
||||
},
|
||||
// 搜索类型select搜索
|
||||
remoteMethod(query, index, prop) {
|
||||
if (query) {
|
||||
this.searchSelectLoading = true;
|
||||
this.$emit("querySelectValue", query, index, prop);
|
||||
setTimeout(() => {
|
||||
this.formObj[index].options = this.searchSelectOptionsCb;
|
||||
this.searchSelectLoading = false;
|
||||
}, 500);
|
||||
} else {
|
||||
this.searchSelectOptios = [];
|
||||
}
|
||||
},
|
||||
//switch变化
|
||||
formSwitchChange(val, index, prop) {
|
||||
this.$emit("formSwitchChange", val, index, prop);
|
||||
},
|
||||
//按钮点击事件
|
||||
buttonClick(prop, index) {
|
||||
this.$emit("buttonClick", prop, index);
|
||||
},
|
||||
|
||||
//文件上传成功回调
|
||||
uploadSuccess(response, file, fileList, limit, prop, index) {
|
||||
this.formObj[index].uploadObj.hideUpload = fileList.length == limit; //文件列表变化后判断当前文件列表长度是否等于限制长度。目的,当长度相等时隐藏文件上传按钮
|
||||
this.pushUpload(file, fileList, limit, prop);
|
||||
},
|
||||
//文件删除
|
||||
handleRemove(file, fileList, limit, prop, index) {
|
||||
this.formObj[index].uploadObj.hideUpload = fileList.length == limit; //文件删除后判断当前文件列表长度是否等于限制长度。目的,当长度相等时隐藏文件上传按钮
|
||||
this.pushUpload(file, fileList, limit, prop);
|
||||
},
|
||||
// 文件预览
|
||||
handlePictureCardPreview(file) {
|
||||
this.dialogImageUrl = file.url;
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
|
||||
//提交时验证表单,直接在父级调用
|
||||
submitForm() {
|
||||
let formValidate = Boolean;
|
||||
this.$refs.ruleForm.validate((valid) => {
|
||||
if (valid) {
|
||||
formValidate = true;
|
||||
} else {
|
||||
this.$message.warning("请把信息填写完整!");
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
/* 清空表单
|
||||
逻辑:
|
||||
1 、如果要清空文件上传列表,要传入要清空的upload的字段名,假如多个upload用for循环,调用清空方法!
|
||||
2、清空upload之后,还要把upload上传框展示出来,通过字段名比对,获取到在formObj中的下标,通过下标操作对象属性,进行展示
|
||||
*/
|
||||
resetForm(uploadArr) {
|
||||
this.$refs.ruleForm.resetFields();
|
||||
if (uploadArr) {
|
||||
for (let i = 0; i < uploadArr.length; i++) {
|
||||
this.$refs[uploadArr[i]][0].clearFiles();
|
||||
let index = this.formObj.findIndex(
|
||||
(item) => item.prop == uploadArr[i]
|
||||
);
|
||||
this.formObj[index].uploadObj.hideUpload = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 单个字段验证
|
||||
validateFieldProp(prop) {
|
||||
let formValidate = Boolean;
|
||||
this.$refs.ruleForm.validateField(prop, (valid) => {
|
||||
if (!valid) {
|
||||
formValidate = true;
|
||||
} else {
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
// 对文件上传,删除进行赋值,调用form验证
|
||||
pushUpload(file, fileList, limit, prop) {
|
||||
if (fileList.length > 0) {
|
||||
this.formData[prop] = fileList;
|
||||
} else {
|
||||
// 表示没有数据,把字段置空
|
||||
this.formData[prop] = "";
|
||||
}
|
||||
this.$refs.ruleForm.validateField(prop); //调用验证form表单的文件上传
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
form {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
::v-deep.el-input,
|
||||
::v-deep.el-select,
|
||||
::v-deep.el-date-editor.el-input {
|
||||
width: 208px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor .el-range-separator {
|
||||
width: 20px !important;
|
||||
}
|
||||
::v-deep.el-range-editor--small.el-input__inner {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.el-textarea {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.hide {
|
||||
::v-deep .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.amap_div {
|
||||
overflow: hidden;
|
||||
height: 400px;
|
||||
width: 600px;
|
||||
position: relative;
|
||||
|
||||
.sreach_ul {
|
||||
position: absolute;
|
||||
top: 1;
|
||||
background-color: white;
|
||||
z-index: 9;
|
||||
min-width: 210px;
|
||||
float: auto;
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
padding: 0 20px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleForm"
|
||||
:model="formData"
|
||||
class="demo-ruleForm"
|
||||
inline
|
||||
>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(formItems, index) in formArr"
|
||||
v-show="!formItems.notShow"
|
||||
:key="index"
|
||||
:span="formItems.span"
|
||||
>
|
||||
<el-form-item
|
||||
:label="null"
|
||||
:prop="formItems.prop"
|
||||
:rules="formItems.rules"
|
||||
>
|
||||
<FormItem
|
||||
v-if="formItems.prop"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
:form-data="formData"
|
||||
@outOperation="(val,num) => outOperation(val, index, formItems.prop,num)"
|
||||
@getRequestData="getRequestData(index,formItems.prop)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<slot />
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormItem from './formItem.vue';
|
||||
export default {
|
||||
components: {
|
||||
FormItem,
|
||||
},
|
||||
props: {
|
||||
formArr: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
methods: {
|
||||
// select 请求接口
|
||||
// val返回值,index表单上第几个组件,prop组件名,num一行的组件里的第几个值
|
||||
outOperation(val, index, prop, num) {
|
||||
this.$emit('outOperation', val, index, prop, num);
|
||||
},
|
||||
// 提交时验证表单,直接在父级调用
|
||||
submitForm() {
|
||||
let formValidate = Boolean;
|
||||
this.$refs.ruleForm.validate((valid) => {
|
||||
if (valid) {
|
||||
formValidate = true;
|
||||
} else {
|
||||
this.$message.warning('请把信息填写完整!');
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
getRequestData(index, prop) {
|
||||
if (prop === 'selectLazyLoading') {
|
||||
this.$emit('getRequestData', index, true);
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.ruleForm.resetFields();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
form {
|
||||
overflow: hidden;
|
||||
}
|
||||
::v-deep.el-form-item {
|
||||
width: 100%;
|
||||
// margin-bottom: 12px;
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
::v-deep.el-form-item .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 文本 -->
|
||||
<CInput
|
||||
v-if="formItems.type==='input'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 文本域 -->
|
||||
<CTextarea
|
||||
v-if="formItems.type==='textarea'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器 -->
|
||||
<CInputNumber
|
||||
v-if="formItems.type==='inputNumber'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器2 -->
|
||||
<CInputNumber2
|
||||
v-if="formItems.type==='inputNumber2'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择 (单选 多选) -->
|
||||
<CSelect
|
||||
v-if="formItems.type==='select'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择(单选 多选) 调接口 -->
|
||||
<CSelectApi
|
||||
v-if="formItems.type==='selectApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选) -->
|
||||
<CSelectTree
|
||||
v-if="formItems.type==='selectTree'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选)调接口 未完成 -->
|
||||
<CSelectTreeApi
|
||||
v-if="formItems.type==='selectTreeApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 金额(数字输入) -->
|
||||
<CInputFinance
|
||||
v-if="formItems.type==='inputFinance'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- input数字 年月日 -->
|
||||
<CInputDate
|
||||
v-if="formItems.type==='inputDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<CPickerDate
|
||||
v-if="formItems.type==='pickerDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<CPickerTime
|
||||
v-if="formItems.type==='pickerTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 单选 -->
|
||||
<CRadio
|
||||
v-if="formItems.type==='radio'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 多选 -->
|
||||
<CCheckbox
|
||||
v-if="formItems.type==='checkbox'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 开关 -->
|
||||
<CSwitch
|
||||
v-if="formItems.type==='switch'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 级联选择 -->
|
||||
<CCascader
|
||||
v-if="formItems.type==='cascader'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 穿梭 -->
|
||||
<CTransfer
|
||||
v-if="formItems.type==='transfer'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 上传-->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import CInput from '../input';
|
||||
import CTextarea from '../textarea';
|
||||
import CSelect from '../select';
|
||||
import CSelectApi from '../selectApi';
|
||||
import CSelectTree from '../selectTree';
|
||||
import CSelectTreeApi from '../selectTreeApi';
|
||||
import CInputNumber from '../inputNumber';
|
||||
import CInputFinance from '../finance';
|
||||
import CInputDate from '../inputDate';
|
||||
import CPickerDate from '../pickerDate';
|
||||
import CPickerTime from '../pickerTime';
|
||||
import CRadio from '../radio';
|
||||
import CCheckbox from '../checkbox';
|
||||
import CSwitch from '../switch';
|
||||
import CCascader from '../cascader';
|
||||
import CTransfer from '../transfer';
|
||||
import CInputNumber2 from '../inputNumber2';
|
||||
export default {
|
||||
name: 'FormItem',
|
||||
components: {
|
||||
CInput,
|
||||
CTextarea,
|
||||
CSelect,
|
||||
CSelectApi,
|
||||
CSelectTree,
|
||||
CSelectTreeApi,
|
||||
CInputNumber,
|
||||
CInputFinance,
|
||||
CInputDate,
|
||||
CPickerDate,
|
||||
CPickerTime,
|
||||
CRadio,
|
||||
CCheckbox,
|
||||
CSwitch,
|
||||
CCascader,
|
||||
CTransfer,
|
||||
CInputNumber2,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
outOperation(val, num) {
|
||||
this.$emit('outOperation', val, num);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<el-collapse
|
||||
v-model="activeNames"
|
||||
@change="collapseChange"
|
||||
>
|
||||
<el-collapse-item
|
||||
v-for="(item,index) in formArr"
|
||||
:key="index"
|
||||
:title="item.title"
|
||||
:name="index.toString()"
|
||||
>
|
||||
<el-form
|
||||
:ref="`ruleForm${index}`"
|
||||
:model="formData"
|
||||
class="demo-ruleForm"
|
||||
inline
|
||||
>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(formItems, index1) in item.formArr"
|
||||
v-show="!formItems.notShow"
|
||||
:key="index1"
|
||||
:span="formItems.span"
|
||||
>
|
||||
<el-form-item
|
||||
:label="null"
|
||||
:prop="formItems.prop"
|
||||
:rules="formItems.rules"
|
||||
>
|
||||
<FormItem
|
||||
v-if="formItems.prop"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
:form-data="formData"
|
||||
@outOperation="(val,num) => outOperation(val, index, formItems.prop,num)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormItem from './formItem.vue';
|
||||
export default {
|
||||
components: {
|
||||
FormItem,
|
||||
},
|
||||
props: {
|
||||
formArr: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
activeNames() {
|
||||
return this.getActiveNames();
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
methods: {
|
||||
collapseChange(val) {
|
||||
console.log(val);
|
||||
},
|
||||
outOperation(val, index, prop, num) {
|
||||
this.$emit('outOperation', val, index, prop, num);
|
||||
},
|
||||
async submitForm() {
|
||||
let formValidate = true;
|
||||
this.formArr.forEach((_, index) => {
|
||||
this.$refs[`ruleForm${index}`][0].validate((valid) => {
|
||||
if (!valid) {
|
||||
// this.$message.warning('请把信息填写完整!');
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.ruleForm.resetFields();
|
||||
},
|
||||
getActiveNames() {
|
||||
const arr = [];
|
||||
for (const i in this.formArr) {
|
||||
if (this.formArr[i].isActive) {
|
||||
arr.push(i.toString());
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
form {
|
||||
overflow: hidden;
|
||||
}
|
||||
::v-deep.el-form-item {
|
||||
width: 100%;
|
||||
// margin-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
::v-deep.el-form-item .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="value"
|
||||
class="cascader"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:options="formItems.options"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
v-bind="formItems.attrs"
|
||||
:props="{ expandTrigger: 'hover' }"
|
||||
@change="handleChangeEvent"
|
||||
@expand-change="handleExpandchangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.cascader {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.el-input__icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
::v-deep .el-cascader--mini {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-checkbox-group
|
||||
v-model="value"
|
||||
class="checkbox"
|
||||
size="mini"
|
||||
:value="value"
|
||||
@change="handleChangeEvent($event)"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="(options, i) in formItems.options"
|
||||
:key="i"
|
||||
:label="options.label"
|
||||
>
|
||||
{{ options.value }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.checkbox {
|
||||
min-height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep.el-checkbox .el-checkbox__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
export default {
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
methods: {
|
||||
// --------------------- 组件内部方法 begin ------------------//
|
||||
handleInputEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleChangeEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleBlurEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleFocusEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleClearEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleExpandchangeEvent() {},
|
||||
// --------------------- 组件内部方法 end ------------------//
|
||||
|
||||
// --------------------- 事件处理 begin ------------------//
|
||||
|
||||
// --------------------- 以上为组件支持外部调用的API方法 end ------------------//
|
||||
|
||||
},
|
||||
};
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
@focus="handleFocus"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 1k => 1000 1m => 1000000 1b => 1000000000
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
digit: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.inputValue = this.value
|
||||
? this.value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
})
|
||||
: ''; // 转换千分位
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
},
|
||||
handleBlur() {
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'k') {
|
||||
unit = 3;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 6;
|
||||
} else if (lastLetter === 'b') {
|
||||
unit = 9;
|
||||
}
|
||||
this.inputValue = (num * Math.pow(10, unit)).toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
}); // 转换千分位
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="input-select">
|
||||
<el-input
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleChange"
|
||||
>
|
||||
<!-- 前文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.prepend
|
||||
}}
|
||||
</template>
|
||||
<!-- 后文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.append
|
||||
}}
|
||||
</template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
style="margin-left:5px;"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs2?.filterable || true"
|
||||
v-bind="formItems.attrs2"
|
||||
@change="handleChange1"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.value[0] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 0);
|
||||
},
|
||||
handleChange1(val) {
|
||||
this.value[1] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.input-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
@blur="handleBlurEvent"
|
||||
@change="handleChangeEvent"
|
||||
@focus="handleFocusEvent"
|
||||
@clear="handleClearEvent"
|
||||
>
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>{{
|
||||
formItems.attrs.prepend
|
||||
}}</template>
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>{{
|
||||
formItems.attrs.append
|
||||
}}</template>
|
||||
</el-input>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
@focus="handleFocus"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// d天 m月,y年,
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
digit: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.inputValue = this.value
|
||||
? this.value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
})
|
||||
: ''; // 转换千分位
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
},
|
||||
handleBlur() {
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'd') {
|
||||
unit = 1;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 30;
|
||||
} else if (lastLetter === 'y') {
|
||||
unit = 365;
|
||||
}
|
||||
this.inputValue = (num * unit).toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
}); // 转换千分位
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
:controls-position="formItems.attrs?.['controls-position'] || 'right'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 12px !important;
|
||||
}
|
||||
.el-input-number__increase{
|
||||
top:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.el-input-number--mini.is-controls-right {
|
||||
.el-input-number__decrease {
|
||||
bottom:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="titiebox">
|
||||
<div
|
||||
v-if="label"
|
||||
:style="{ width: width }"
|
||||
class="titieboxlabel"
|
||||
>
|
||||
<span
|
||||
v-if="needStar"
|
||||
style="color: #f00"
|
||||
>{{ "*" }}</span>{{ label }} <span>{{ ':' }}</span>
|
||||
</div>
|
||||
<div class="titieboxvalue">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
needStar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '80px',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.titiebox {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
.titieboxlabel {
|
||||
padding-right: 12px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: right;
|
||||
}
|
||||
.titieboxvalue {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div
|
||||
class="operateCard"
|
||||
:style="{width: foldCard ? '24px': width}"
|
||||
>
|
||||
<div
|
||||
v-if="!foldCard"
|
||||
class="card"
|
||||
>
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<el-tooltip
|
||||
v-for="(item,index) in iconLeftList"
|
||||
:key="index"
|
||||
:content="item.text"
|
||||
placement="bottom"
|
||||
effect="dark"
|
||||
class="custom-tooltip"
|
||||
>
|
||||
<i
|
||||
:class="[item.type,'left-icon']"
|
||||
@click="item.callback(value)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="center"><slot /></div>
|
||||
|
||||
<div class="right">
|
||||
<i
|
||||
v-for="(item,index) in iconRightList"
|
||||
:key="index"
|
||||
:class="[item.type,'right-icon']"
|
||||
@click="item.callback()"
|
||||
/>
|
||||
<i
|
||||
v-if="showFold"
|
||||
:class="['el-icon-d-arrow-left','right-icon']"
|
||||
@click="handlefoldCard(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tree
|
||||
:data="formList"
|
||||
:props="{
|
||||
children: children,
|
||||
label: label
|
||||
}"
|
||||
v-bind="operateCardTreeAttrs"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="foldCard"
|
||||
class="fold"
|
||||
>
|
||||
<i
|
||||
v-if="showFold"
|
||||
:class="['el-icon-d-arrow-right']"
|
||||
@click="handlefoldCard(false)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'OperatedCard',
|
||||
props: {
|
||||
iconLeftList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
iconRightList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
formList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 折叠按钮
|
||||
showFold: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 组件宽度
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px',
|
||||
},
|
||||
//
|
||||
children: {
|
||||
type: String,
|
||||
default: 'children',
|
||||
},
|
||||
//
|
||||
label: {
|
||||
type: String,
|
||||
default: 'label',
|
||||
},
|
||||
operateCardTreeAttrs: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
foldCard: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handlefoldCard(bool) {
|
||||
this.foldCard = bool;
|
||||
},
|
||||
handleNodeClick(row) {
|
||||
this.$emit('handleNodeClick', row);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.operateCard {
|
||||
height: 100%;
|
||||
.card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding: 0 5px;
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.left-icon {
|
||||
margin-right: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.center {
|
||||
font-size: 14px;
|
||||
}
|
||||
.right-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
height: calc(100% - 30px);
|
||||
// padding: 12px;
|
||||
overflow: scroll;
|
||||
.content-items {
|
||||
height: 32px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
padding-left: 19px;
|
||||
font-size: 12px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.content-items:hover {
|
||||
background-color: #e6f2ff;
|
||||
}
|
||||
.content-items-selected {
|
||||
height: 32px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
padding-left: 19px;
|
||||
font-size: 12px;
|
||||
line-height: 32px;
|
||||
background: #7489ff;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.el-tree>.el-tree-node){
|
||||
min-width:100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.fold {
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
padding-left: 2px;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-tooltip {
|
||||
--el-tooltip-fill: #000000; /* 背景色 */
|
||||
--el-tooltip-color: #ffffff; /* 文字颜色 */
|
||||
}
|
||||
</style>
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-date-picker
|
||||
class="datePicker"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择日期'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
@blur="handleBlurEvent"
|
||||
@focus="handleFocusEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.el-range-editor {
|
||||
// height: 20px;
|
||||
// }
|
||||
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner, .eui-theme-default .el-date-editor--timerange.el-input, .eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-date-picker
|
||||
class="datePicker"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择日期'"
|
||||
v-bind="formItems.attrs"
|
||||
value-format="yyyy-MM-dd"
|
||||
@input="handleInputEvent"
|
||||
@blur="handleBlurEvent"
|
||||
@focus="handleFocusEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.el-range-editor {
|
||||
// height: 20px;
|
||||
// }
|
||||
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner,
|
||||
.eui-theme-default .el-date-editor--timerange.el-input,
|
||||
.eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
// 修复placeholder与日期图标重合的样式
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-time-picker
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择时间'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner, .eui-theme-default .el-date-editor--timerange.el-input, .eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner{
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-radio-group
|
||||
class="radio"
|
||||
size="mini"
|
||||
:value="value"
|
||||
@input="handleInputEvent"
|
||||
>
|
||||
<el-radio
|
||||
v-for="(options, i) in formItems.options"
|
||||
:key="i"
|
||||
:label="options.label"
|
||||
>
|
||||
{{ options.value }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.radio {
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="rcs-search">
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="form"
|
||||
label-position="left"
|
||||
:inline="true"
|
||||
:rules="customRules || rules"
|
||||
@submit.native.prevent
|
||||
>
|
||||
<template v-for=" (item,index) in search">
|
||||
<template v-if="item.type === 'input'">
|
||||
<el-form-item
|
||||
:key="item.name"
|
||||
:prop="item.name"
|
||||
:label="item.label"
|
||||
:label-width="item.labelWidth?item.labelWidth + 'px':labelWidth + 'px'"
|
||||
>
|
||||
<el-input
|
||||
v-model.trim="form[item.name]"
|
||||
:placeholder="item.placeholder||'请输入'"
|
||||
:title="item.placeholder"
|
||||
:maxlength="item.maxLength"
|
||||
clearable
|
||||
:style="item.styleWidth || defaultWidth"
|
||||
@keyup.enter.native="doEnter(item.type)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="item.type === 'select'">
|
||||
<el-form-item
|
||||
:key="item.name"
|
||||
:prop="item.name"
|
||||
:label="item.label&&(!item.isNoSign)?item.label+':':item.label"
|
||||
:label-width="item.labelWidth?item.labelWidth + 'px':labelWidth + 'px'"
|
||||
>
|
||||
<el-select
|
||||
v-model.trim="form[item.name]"
|
||||
:disabled="item.disabled"
|
||||
:placeholder="item.placeholder||'请选择'"
|
||||
:filterable="item.filterable||true"
|
||||
:multiple="item.multiple"
|
||||
:collapse-tags="item.collapseTags"
|
||||
:clearable="item.clearable||true"
|
||||
:remote="item.remote||false"
|
||||
:remote-method="(query)=>remoteMethod(query,item.name)"
|
||||
:style="item.styleWidth || defaultWidth"
|
||||
>
|
||||
<el-option
|
||||
v-for="inner in item.options"
|
||||
:key="inner.value"
|
||||
:label="inner.text"
|
||||
:value="inner.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="item.type === 'date'">
|
||||
<el-form-item
|
||||
:key="item.name"
|
||||
:prop="item.name"
|
||||
:label="item.label&&(!item.isNoSign)?item.label+':':item.label"
|
||||
:label-width="item.labelWidth?item.labelWidth + 'px':labelWidth + 'px'"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model.trim="form[item.name]"
|
||||
type="date"
|
||||
:value-format="item.format||'yyyy-MM-dd'"
|
||||
:placeholder="item.placeholder||'请选择'"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-form-item v-if="isShowExpandParams">
|
||||
<el-button
|
||||
v-if="!isExpand"
|
||||
type="text"
|
||||
@click="updateExpandParams(1)"
|
||||
>+更多筛选</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="text"
|
||||
@click="updateExpandParams(0)"
|
||||
>-收起筛选</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="dosearch()"
|
||||
>
|
||||
查 询
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isShowReset">
|
||||
<el-button @click="reset()">
|
||||
重 置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SearchForm',
|
||||
props: {
|
||||
search: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
required: true,
|
||||
},
|
||||
labelWidth: {
|
||||
type: [Number, String],
|
||||
default: () => '70',
|
||||
required: false,
|
||||
},
|
||||
defaultValues: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
customRules: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
isShowExpandParams: { // 扩展展开/收起功能 默认值false:没有展开收起功能
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isShowReset: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: null,
|
||||
rules: {},
|
||||
defaultWidth: {
|
||||
width: '200px',
|
||||
},
|
||||
isExpand: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
defaultValues: {
|
||||
handler(val) {
|
||||
this.defaultValues.forEach(item => {
|
||||
this.$set(this.form, item.key, item.value);
|
||||
});
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const obj = {};
|
||||
for (const item of this.search) {
|
||||
obj[item.name] = undefined;
|
||||
if (item.isValid) { // 校验必选条件
|
||||
const message = item.type === 'input' ? '请输入' : '请选择';
|
||||
this.rules[item.name] = [
|
||||
{ required: true, message: item.message ? item.message : message, trigger: 'change' },
|
||||
];
|
||||
} else if (item.regex) {
|
||||
this.rules[item.name] = [
|
||||
{ required: item.required ?? true, validator: item.validator || this.validator, trigger: 'change' }, // 规则校验:默认是必填,有配置required用配置的值
|
||||
];
|
||||
}
|
||||
}
|
||||
this.defaultValues.forEach(item => {
|
||||
obj[item.key] = item.value;
|
||||
});
|
||||
this.form = obj;
|
||||
},
|
||||
mounted() {
|
||||
console.log('this.form, this.rules------', this.form, this.rules);
|
||||
},
|
||||
methods: {
|
||||
updateExpandParams(val) {
|
||||
// val:1 展开 0 收起
|
||||
this.isExpand = !this.isExpand;
|
||||
},
|
||||
remoteMethod(query, prop) {
|
||||
this.$emit('onRemote', query, prop);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rcs-search{
|
||||
::v-deep .el-date-editor .el-input__inner{
|
||||
padding-left: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<!-- formItems.attrs为假的时候会返空-->
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="select-select">
|
||||
<el-select
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
@change="(val)=> handleChange(val,0)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options1"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
style="margin-left:5px;"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs2?.filterable || true"
|
||||
v-bind="formItems.attrs2"
|
||||
@change="(val)=> handleChange(val,1)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options2"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formItems: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val, i) {
|
||||
this.value[i] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, i);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.select-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item[formItems.attrs?.optionLabel]||item.label||item.text"
|
||||
:value="item[formItems.attrs?.optionValue]||item.value"
|
||||
>
|
||||
<span style="float: left">{{ item[formItems.attrs?.optionLabel]||item.label||item.text }}</span>
|
||||
<span
|
||||
v-if="formItems.attrs?.showValue"
|
||||
>({{ item[formItems.attrs?.optionValue]||item.value }})</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:remote-method="selectApi"
|
||||
:loading="loading"
|
||||
@focus="selectfocusApi"
|
||||
@change="handleInput"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
this.$emit('input', value);
|
||||
},
|
||||
selectApi(val) {
|
||||
// this.loading = true;
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
// 聚焦时候拿全部数据
|
||||
selectfocusApi() {
|
||||
// this.loading = true;
|
||||
this.$emit('outOperation', undefined);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
popper-class="lazy-load-select"
|
||||
remote
|
||||
:loading="loading"
|
||||
:remote-method="remoteMethod"
|
||||
@change="handleChange"
|
||||
@visible-change="handleVisibleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<!-- 加载状态提示 -->
|
||||
<div
|
||||
v-if="formItems.attrs.loadingMore"
|
||||
class="load-more-tip"
|
||||
>
|
||||
<i class="el-icon-loading" /> 加载中...
|
||||
</div>
|
||||
<div
|
||||
v-if="formItems.attrs.noMore"
|
||||
class="no-more-tip"
|
||||
>没有更多数据了</div>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// loading: false,
|
||||
// loadingMore: false, //加载更多状态
|
||||
// noMore: false, // 是否没有更多数据
|
||||
// page: 1,
|
||||
// pageSize: 10,
|
||||
// total: 0,
|
||||
scrollEl: null, // 保存滚动元素引用
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
console.log(formItems.attrs.loadingMore);
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 关键点5:组件销毁前移除监听
|
||||
if (this.scrollEl) {
|
||||
this.scrollEl.removeEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
// 下拉框显示/隐藏状态变化
|
||||
handleVisibleChange(visible) {
|
||||
if (visible) {
|
||||
this.$nextTick(() => {
|
||||
// 关键点2:获取下拉框滚动元素
|
||||
this.scrollEl = document.querySelector(
|
||||
'.lazy-load-select .el-select-dropdown__wrap',
|
||||
);
|
||||
if (this.scrollEl) {
|
||||
this.scrollEl.addEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
});
|
||||
} else if (this.scrollEl) {
|
||||
// 移除监听
|
||||
this.scrollEl.removeEventListener('scroll', this.handleScroll);
|
||||
this.scrollEl = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 滚动事件处理
|
||||
handleScroll() {
|
||||
if (!this.scrollEl) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = this.scrollEl;
|
||||
const threshold = 50; // 距离底部阈值(px)
|
||||
|
||||
// 关键点3:判断是否滚动到底部
|
||||
if (scrollHeight - (scrollTop + clientHeight) < threshold) {
|
||||
this.loadMoreData();
|
||||
}
|
||||
},
|
||||
// 加载更多数据
|
||||
loadMoreData() {
|
||||
if (this.formItems.attrs.loadingMore || this.formItems.attrs.noMore) return;
|
||||
// this.page++;
|
||||
// this.loadData(true);
|
||||
this.$emit('getRequestData');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
/* 关键点6:自定义下拉框样式 */
|
||||
::v-deep.lazy-load-select .el-select-dropdown__wrap {
|
||||
max-height: 300px; /* 限制下拉框高度 */
|
||||
}
|
||||
|
||||
/* 加载提示样式 */
|
||||
.load-more-tip,
|
||||
.no-more-tip {
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.load-more-tip .el-icon-loading {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
ref="select"
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:multiple="false"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
style="width: 100%"
|
||||
v-bind="formItems.attrs"
|
||||
>
|
||||
<el-option
|
||||
ref="option"
|
||||
class="tree-select__option"
|
||||
:value="optionData.value"
|
||||
:label="optionData.label"
|
||||
>
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="tree-select__tree"
|
||||
:class="`tree-select__tree--${
|
||||
formItems.attrs?.multiple ? 'checked' : 'radio'
|
||||
}`"
|
||||
:node-key="nodeKey"
|
||||
:data="formItems.options"
|
||||
:props="props"
|
||||
:show-checkbox="formItems.attrs?.multiple || false"
|
||||
:highlight-current="!formItems.attrs?.multiple || false"
|
||||
:expand-on-click-node="formItems.attrs?.multiple || false"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="handleNodeClick"
|
||||
@check-change="handleCheckChange"
|
||||
/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'TreeSelect',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 每个树节点用来作为唯一标识的属性
|
||||
nodeKey: {
|
||||
type: [String, Number],
|
||||
default: 'value',
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// tree的props配置
|
||||
props: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
optionData: {
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
formItems: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
init(val) {
|
||||
// 多选
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
const arr = val.toString().split(',');
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys(arr);
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = nodes
|
||||
.map((item) => item[this.props.label])
|
||||
.join(',');
|
||||
});
|
||||
}
|
||||
// 单选
|
||||
else {
|
||||
val = val === '' ? null : val;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCurrentKey(val);
|
||||
if (val === null) {
|
||||
return;
|
||||
}
|
||||
const node = this.$refs.tree.getNode(val);
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = node.label;
|
||||
});
|
||||
}
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
return;
|
||||
}
|
||||
this.$emit('input', data[this.nodeKey]);
|
||||
this.$emit('outOperation', data[this.nodeKey]);
|
||||
this.$refs.select.visible = false;
|
||||
},
|
||||
handleCheckChange() {
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
const value = nodes.map((item) => item[this.nodeKey]).join(',');
|
||||
this.$emit('input', value);
|
||||
this.$emit('outOperation', value);
|
||||
},
|
||||
filterMethod(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
const label = this.props.label || 'label';
|
||||
return data[label].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tree-select__option {
|
||||
&.el-select-dropdown__item {
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-select__tree {
|
||||
padding: 4px 0px;
|
||||
font-weight: 400;
|
||||
&.tree-select__tree--radio {
|
||||
.el-tree-node.is-current > .el-tree-node__content {
|
||||
font-weight: 700;
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
ref="select"
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:multiple="false"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
style="width: 100%"
|
||||
v-bind="formItems.attrs"
|
||||
>
|
||||
<el-option
|
||||
ref="option"
|
||||
class="tree-select__option"
|
||||
:value="optionData.value"
|
||||
:label="optionData.label"
|
||||
>
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="tree-select__tree"
|
||||
:class="`tree-select__tree--${
|
||||
formItems.attrs?.multiple ? 'checked' : 'radio'
|
||||
}`"
|
||||
:node-key="nodeKey"
|
||||
:data="formItems.options"
|
||||
:props="props"
|
||||
:show-checkbox="formItems.attrs?.multiple || false"
|
||||
:highlight-current="!formItems.attrs?.multiple || false"
|
||||
:expand-on-click-node="formItems.attrs?.multiple || false"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="handleNodeClick"
|
||||
@check-change="handleCheckChange"
|
||||
/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'TreeSelect',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 每个树节点用来作为唯一标识的属性
|
||||
nodeKey: {
|
||||
type: [String, Number],
|
||||
default: 'id',
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// tree的props配置
|
||||
props: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
optionData: {
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
formItems: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
init(val) {
|
||||
// 多选
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
const arr = val.toString().split(',');
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys(arr);
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = nodes
|
||||
.map((item) => item[this.props.label])
|
||||
.join(',');
|
||||
});
|
||||
}
|
||||
// 单选
|
||||
else {
|
||||
val = val === '' ? null : val;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCurrentKey(val);
|
||||
if (val === null) {
|
||||
return;
|
||||
}
|
||||
const node = this.$refs.tree.getNode(val);
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = node.label;
|
||||
});
|
||||
}
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
return;
|
||||
}
|
||||
this.$emit('input', data[this.nodeKey]);
|
||||
this.$emit('outOperation', data[this.nodeKey]);
|
||||
this.$refs.select.visible = false;
|
||||
},
|
||||
handleCheckChange() {
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
const value = nodes.map((item) => item[this.nodeKey]).join(',');
|
||||
this.$emit('input', value);
|
||||
this.$emit('outOperation', value);
|
||||
},
|
||||
filterMethod(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
const label = this.props.label || 'label';
|
||||
return data[label].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tree-select__option {
|
||||
&.el-select-dropdown__item {
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-select__tree {
|
||||
padding: 4px 0px;
|
||||
font-weight: 400;
|
||||
&.tree-select__tree--radio {
|
||||
.el-tree-node.is-current > .el-tree-node__content {
|
||||
font-weight: 700;
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
class="switch"
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-switch
|
||||
v-model="value"
|
||||
size="mini"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.switch {
|
||||
min-height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,549 @@
|
||||
<template>
|
||||
<div class="table-box">
|
||||
<div
|
||||
v-if="tableTopButton.length > 0 || isNeedCustomcolumn"
|
||||
class="need-btn-line"
|
||||
>
|
||||
<!-- 列定制按钮 -->
|
||||
<el-button
|
||||
v-if="isNeedCustomcolumn"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handlecustomcolumnOpen"
|
||||
>列定制</el-button>
|
||||
<!-- 自定义按钮 -->
|
||||
<el-button
|
||||
v-for="(value, i) in tableTopButton"
|
||||
:key="'$' + i"
|
||||
:style="{ fontSize: fontSize + 'px' }"
|
||||
size="small"
|
||||
:type="value.type || 'text'"
|
||||
:icon="value.icon"
|
||||
:class="value.class"
|
||||
@click="value.callback(value)"
|
||||
>{{ value.text }}</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
ref="tableData"
|
||||
v-loading="loading"
|
||||
size="default"
|
||||
:row-key="rowKey"
|
||||
:style="{ width: '100%', fontSize: fontSize + 'px' }"
|
||||
:show-header="showHeader"
|
||||
:data="tableData"
|
||||
:height="tableHeight"
|
||||
:cell-style="cellStyle"
|
||||
:cell-class-name="tableCellClassName"
|
||||
:span-method="arraySpanMethod"
|
||||
:border="border"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
v-bind="tableInfo"
|
||||
:stripe="isStripe"
|
||||
:tree-props="{
|
||||
children: treePropsChildren,
|
||||
hasChildren: treePropshasChildren,
|
||||
}"
|
||||
v-on="events"
|
||||
@selection-change="handleSelectionChange"
|
||||
@select-all="handleSelectionAllChange"
|
||||
>
|
||||
<slot name="expand" />
|
||||
<!-- 多选 -->
|
||||
<el-table-column
|
||||
v-if="needSelect"
|
||||
type="selection"
|
||||
width="30"
|
||||
:reserve-selection="isReserve"
|
||||
/>
|
||||
<!-- 序号 -->
|
||||
<el-table-column
|
||||
v-if="hasIndex"
|
||||
label="序号"
|
||||
width="50"
|
||||
type="index"
|
||||
/>
|
||||
|
||||
<template v-for="(item, index) in tableColumn">
|
||||
<el-table-column
|
||||
:key="'%' + index"
|
||||
:show-overflow-tooltip="!item.notTooltip"
|
||||
v-bind="item"
|
||||
v-on="events"
|
||||
>
|
||||
<!-- 头部 -->
|
||||
<template
|
||||
slot="header"
|
||||
slot-scope="scope"
|
||||
>
|
||||
<i
|
||||
v-if="item.tableTopColumnIcon"
|
||||
:class="item.tableTopColumnIcon"
|
||||
@click="handleTableTopColumnIconClick(item,index)"
|
||||
/>
|
||||
{{ item.label }}
|
||||
<span v-if="item.tableTopColumnCheck">
|
||||
<el-checkbox
|
||||
v-model="item.tableTopColumnCheckValue"
|
||||
:v-bind="item.tableTopColumnCheckValue"
|
||||
:indeterminate="false"
|
||||
@change="(val)=>
|
||||
handleTableTopColumncheckChange(item,index,val)"
|
||||
/>
|
||||
</span>
|
||||
|
||||
</template>
|
||||
|
||||
<template slot-scope="scope">
|
||||
<!-- render 函数式 -->
|
||||
<template v-if="item.render">
|
||||
<ex-slot
|
||||
:render="item.render"
|
||||
:index="scope.$index"
|
||||
:row="scope.row"
|
||||
:column="item"
|
||||
:class="item.prop"
|
||||
:default-value="item.defaultValue"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- progress 进度条 -->
|
||||
<template v-else-if="item.progress">
|
||||
<el-progress :percentage="parseFloat(scope.row[item.prop])" />
|
||||
</template>
|
||||
|
||||
<!-- formatter 自定义 -->
|
||||
<template v-else-if="item.formatter">
|
||||
<span v-html="item.formatter(scope.row, item)" />
|
||||
</template>
|
||||
|
||||
<!-- checkbox -->
|
||||
<template v-else-if="item.tableTopColumnCheck">
|
||||
<el-checkbox
|
||||
v-model="scope.row[item.prop]"
|
||||
@change="(val)=>
|
||||
handleTableTopColumnRowcheckChange(scope,index,val)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 正常列 -->
|
||||
<template v-else>
|
||||
<span>
|
||||
{{ scope.row[item.prop] }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!-- 操作 -->
|
||||
<el-table-column
|
||||
v-if="hasOperation"
|
||||
label="操作"
|
||||
:min-width="operationWidth"
|
||||
:fixed="operationFixed ? 'right' : false"
|
||||
align="center"
|
||||
>
|
||||
<template
|
||||
v-if="btnButton.length"
|
||||
slot-scope="{ row, column, $index }"
|
||||
>
|
||||
<el-button
|
||||
v-for="(value, i) in btnButton"
|
||||
:key="'$' + i"
|
||||
:style="{ fontSize: fontSize + 'px' }"
|
||||
size="small"
|
||||
:type="value.type || 'text'"
|
||||
:icon="value.icon"
|
||||
:class="value.class || 'el-text-color'"
|
||||
@click="value.callback(row, column, $index)"
|
||||
>{{ value.text }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页 -->
|
||||
<div
|
||||
v-if="isNeedPagination"
|
||||
:style="{
|
||||
display: 'flex',
|
||||
justifyContent: operatedString ? 'space-between' : 'flex-end',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="operatedString"
|
||||
class="operated"
|
||||
>{{ operatedString }}</div>
|
||||
<el-pagination
|
||||
ref="pagination"
|
||||
class="no-border-top"
|
||||
:page-sizes="pageSizes"
|
||||
:page-size.sync="computedPageSize"
|
||||
:hide-on-single-page="isSinglePageHide"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:current-page.sync="computedCurrentPage"
|
||||
:total="total"
|
||||
:small="small"
|
||||
:pager-count="pagerCount"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
/>
|
||||
</div>
|
||||
<el-drawer
|
||||
title="数据列"
|
||||
:visible.sync="drawer"
|
||||
direction="rtl"
|
||||
:before-close="handlecustomcolumnClose"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in tableData"
|
||||
:key="index"
|
||||
class="drawer-custom"
|
||||
>
|
||||
<el-checkbox v-model="item.check">{{ item.label }}</el-checkbox>
|
||||
</div>
|
||||
<div class="drawer-footer">
|
||||
<el-button
|
||||
size="mini"
|
||||
class="drawer-footer-confirm-btn"
|
||||
type="primary"
|
||||
@click="handlecustomcolumnConfirm"
|
||||
>确定</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
class="drawer-footer-cancel-btn"
|
||||
@click="handlecustomcolumnCancel"
|
||||
>取 消</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// 自定义组件的内容
|
||||
const exSlot = {
|
||||
functional: true,
|
||||
props: {
|
||||
row: Object,
|
||||
render: Function,
|
||||
index: Number,
|
||||
column: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
render: (h, ctx) => {
|
||||
const params = {
|
||||
row: ctx.props.row,
|
||||
index: ctx.props.index,
|
||||
};
|
||||
if (ctx.props.column) params.column = ctx.props.column;
|
||||
return ctx.props.render(h, params);
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'PublicTable',
|
||||
components: {
|
||||
'ex-slot': exSlot,
|
||||
},
|
||||
props: {
|
||||
// key(唯一key值,和reserve-selection搭配使用)
|
||||
rowKey: {
|
||||
type: [Object, Function],
|
||||
default: () => ({}),
|
||||
},
|
||||
// 多选框是否记住上一页数据(必须与row-key唯一值搭配使用)
|
||||
isReserve: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 单元格的 style 的回调方法
|
||||
cellStyle: {
|
||||
type: [Object, Function],
|
||||
default: () => ({}),
|
||||
},
|
||||
pagerCount: {
|
||||
type: Number,
|
||||
default: 7,
|
||||
},
|
||||
// 是否显示表头
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 是否要高亮当前行
|
||||
highlightCurrentRow: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 获取表格行列索引值
|
||||
tableCellClassName: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
// 合并行或列
|
||||
arraySpanMethod: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
// 是否需要多选
|
||||
needSelect: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 是否需要序号
|
||||
hasIndex: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 默认是否选中第一列
|
||||
isSetCurrentRow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 是否需要分页
|
||||
isNeedPagination: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 是否需要 列定制 按钮
|
||||
isNeedCustomcolumn: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 是否单页隐藏,默认为true
|
||||
isSinglePageHide: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 当前页页码,支持.sync修饰符
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
// 每页数据条数, 支持.sync修饰符默认为每页10条
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
// 数据总条数
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
// 每页多少数据
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [10, 20, 50, 100],
|
||||
},
|
||||
tableInfo: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
// 获取数据时是否需要加载loading
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格展示数据
|
||||
tableColumn: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 是否需要操作列
|
||||
hasOperation: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 是否需要边框
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 操作 自定义按钮
|
||||
btnButton: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 表格顶部自定义按钮
|
||||
tableTopButton: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 操作列宽度
|
||||
operationWidth: {
|
||||
type: String,
|
||||
default: '60px',
|
||||
},
|
||||
// 固定操作栏
|
||||
operationFixed: {
|
||||
type: [Boolean, String],
|
||||
default: false,
|
||||
},
|
||||
// 表格方法
|
||||
events: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
// 是否为斑马纹 table
|
||||
isStripe: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 树结构(树结构必须有rowKey)
|
||||
treePropsChildren: {
|
||||
type: String,
|
||||
default: 'children',
|
||||
},
|
||||
// 树结构(树结构必须有rowKey)
|
||||
treePropshasChildren: {
|
||||
type: String,
|
||||
default: 'hasChildren',
|
||||
},
|
||||
// 点击图标计算的值
|
||||
operatedString: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fontSize: sessionStorage.getItem('fontSize') || '',
|
||||
drawer: false,
|
||||
checked: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
computedCurrentPage: {
|
||||
get() {
|
||||
return this.currentPage;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:currentPage', val);
|
||||
},
|
||||
},
|
||||
computedPageSize: {
|
||||
get() {
|
||||
return this.pageSize;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:pageSize', val);
|
||||
},
|
||||
},
|
||||
tableHeight() {
|
||||
return this.tableInfo?.tableHeight ? this.tableInfo?.tableHeight : !this.isNeedPagination ? '100%' : 'calc(100% - 47px)';
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
mounted() {
|
||||
if (this.isSetCurrentRow) {
|
||||
setTimeout(() => {
|
||||
this.$refs.tableData.setCurrentRow(this.tableData[0]);
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTableRef() {
|
||||
return this.$refs.tableData;
|
||||
},
|
||||
currentChange(val) {
|
||||
this.$emit('currentChange', val);
|
||||
},
|
||||
sizeChange(val) {
|
||||
this.$emit('sizeChange', val);
|
||||
},
|
||||
handlecustomcolumnOpen() {
|
||||
this.drawer = true;
|
||||
},
|
||||
handlecustomcolumnClose(done) {
|
||||
done();
|
||||
},
|
||||
handlecustomcolumnCancel() {
|
||||
this.drawer = false;
|
||||
},
|
||||
handlecustomcolumnConfirm() {
|
||||
this.drawer = false;
|
||||
this.$emit('customColumnChange', this.tableData);
|
||||
},
|
||||
handleTableTopColumnIconClick(item, index) {
|
||||
this.$emit('handleTableTopColumnIconClick', item, index);
|
||||
},
|
||||
handleTableTopColumncheckChange(item, index, val) {
|
||||
this.$emit('handleTableTopColumncheckChange', item, index, val);
|
||||
},
|
||||
handleTableTopColumnRowcheckChange(item, index, val) {
|
||||
this.$emit('handleTableTopColumnRowcheckChange', item, index, val);
|
||||
},
|
||||
handleSelectionChange(row) {
|
||||
this.$emit('handleSelectionChange', row);
|
||||
},
|
||||
handleSelectionAllChange(row) {
|
||||
this.$emit('handleSelectionAllChange', row);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.table-box {
|
||||
margin-top: 12px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dfe6ec;
|
||||
}
|
||||
|
||||
.need-btn-line {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
::v-deep .el-table td {
|
||||
padding: 0;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
// // table选中行高亮
|
||||
// ::v-deep .el-table__body tr.current-row {
|
||||
// .flex_div {
|
||||
// background: rgba(21, 91, 212, 0.3) !important;
|
||||
// }
|
||||
// td {
|
||||
// background: rgba(21, 91, 212, 0.3) !important;
|
||||
// }
|
||||
// td {
|
||||
// background: rgba(21, 91, 212, 0.2) !important;
|
||||
// }
|
||||
// }
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.drawer-custom {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
.drawer-footer {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
.drawer-footer-confirm-btn,
|
||||
.drawer-footer-cancel-btn {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
.operated {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
width: 50%;
|
||||
}
|
||||
</style>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
type="textarea"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
:value="value"
|
||||
v-bind="formItems.attrs"
|
||||
:autosize="{
|
||||
minRows: formItems.attrs.minRows,
|
||||
maxRows: formItems.attrs.maxRows,
|
||||
}"
|
||||
@input="handleInputEvent"
|
||||
@blur="handleBlurEvent"
|
||||
@change="handleChangeEvent"
|
||||
@focus="handleFocusEvent"
|
||||
@clear="handleClearEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-textarea .el-textarea__inner {
|
||||
padding: 0 7px;
|
||||
line-height: 22px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-transfer
|
||||
v-model="value"
|
||||
class="transferBox"
|
||||
:value="value"
|
||||
:data="formItems.options"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val, direction, movedKeys) {
|
||||
this.$emit('input', val, direction, movedKeys);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.transferBox {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep .el-transfer-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
::v-deep.transferBox .el-transfer__buttons {
|
||||
padding: 0 10px !important;
|
||||
.el-button {
|
||||
padding: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.transferBox {
|
||||
line-height: 24px;
|
||||
|
||||
.el-transfer-panel__header {
|
||||
height: 24px;
|
||||
.el-checkbox {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
.el-checkbox__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-checkbox__label {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.el-checkbox__input {
|
||||
// top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 文本 -->
|
||||
<CInput
|
||||
v-if="formItems.type === 'input'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 文本域 -->
|
||||
<CTextarea
|
||||
v-if="formItems.type==='textarea'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器 -->
|
||||
<CInputNumber
|
||||
v-if="formItems.type==='inputNumber'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器2 -->
|
||||
<CInputNumber2
|
||||
v-if="formItems.type==='inputNumber2'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择 (单选 多选) -->
|
||||
<CSelect
|
||||
v-if="formItems.type==='select'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择(单选 多选) 调接口 -->
|
||||
<CSelectApi
|
||||
v-if="formItems.type==='selectApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选) -->
|
||||
<CSelectTree
|
||||
v-if="formItems.type==='selectTree'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选)调接口 未完成 -->
|
||||
<CSelectTreeApi
|
||||
v-if="formItems.type==='selectTreeApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 金额(数字输入) -->
|
||||
<CInputFinance
|
||||
v-if="formItems.type==='inputFinance'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- input数字 年月日 -->
|
||||
<CInputDate
|
||||
v-if="formItems.type==='inputDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<CPickerDate
|
||||
v-if="formItems.type==='pickerDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<CPickerTime
|
||||
v-if="formItems.type==='pickerTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 单选 -->
|
||||
<CRadio
|
||||
v-if="formItems.type==='radio'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 多选 -->
|
||||
<CCheckbox
|
||||
v-if="formItems.type==='checkbox'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 开关 -->
|
||||
<CSwitch
|
||||
v-if="formItems.type==='switch'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 级联选择 -->
|
||||
<CCascader
|
||||
v-if="formItems.type==='cascader'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 穿梭 -->
|
||||
<CTransfer
|
||||
v-if="formItems.type==='transfer'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 选择-选择 -->
|
||||
<CSelectSelect
|
||||
v-if="formItems.type==='selectSelect'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 文本输入-选择 -->
|
||||
<CInputSelect
|
||||
v-if="formItems.type==='inputSelect'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期选择器拆分单个日期 -->
|
||||
<CPickerDateSingle
|
||||
v-if="formItems.type==='pickerDateSingle'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
<!-- 上传-->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import CInput from './components/input';
|
||||
import CTextarea from './components/textarea';
|
||||
import CSelect from './components/select';
|
||||
import CSelectApi from './components/selectApi';
|
||||
import CSelectTree from './components/selectTree';
|
||||
import CSelectTreeApi from './components/selectTreeApi';
|
||||
import CInputNumber from './components/inputNumber';
|
||||
import CInputFinance from './components/finance';
|
||||
import CInputDate from './components/inputDate';
|
||||
import CPickerDate from './components/pickerDate';
|
||||
import CPickerTime from './components/pickerTime';
|
||||
import CRadio from './components/radio';
|
||||
import CCheckbox from './components/checkbox';
|
||||
import CSwitch from './components/switch';
|
||||
import CCascader from './components/cascader';
|
||||
import CTransfer from './components/transfer';
|
||||
import CSelectSelect from './components/select-select';
|
||||
import CInputNumber2 from './components/inputNumber2';
|
||||
import CInputSelect from './components/input-select';
|
||||
import CSelectLazyLoading from './components/selectLazyLoading';
|
||||
import CPickerDateSingle from './components/pickerDateSingle';
|
||||
export default {
|
||||
name: 'FormItem',
|
||||
components: {
|
||||
CInput,
|
||||
CTextarea,
|
||||
CSelect,
|
||||
CSelectApi,
|
||||
CSelectTree,
|
||||
CSelectTreeApi,
|
||||
CInputNumber,
|
||||
CInputFinance,
|
||||
CInputDate,
|
||||
CPickerDate,
|
||||
CPickerTime,
|
||||
CRadio,
|
||||
CCheckbox,
|
||||
CSwitch,
|
||||
CCascader,
|
||||
CTransfer,
|
||||
CSelectSelect,
|
||||
CInputNumber2,
|
||||
CInputSelect,
|
||||
CSelectLazyLoading,
|
||||
CPickerDateSingle,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
outOperation(val, num) {
|
||||
this.$emit('outOperation', val, num);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleForm"
|
||||
:model="formData"
|
||||
class="demo-ruleForm"
|
||||
inline
|
||||
>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(formItems, index) in formArr"
|
||||
v-show="!formItems.notShow"
|
||||
:key="index"
|
||||
:span="formItems.span"
|
||||
>
|
||||
<el-form-item
|
||||
:label="null"
|
||||
:prop="formItems.prop"
|
||||
:rules="formItems.rules"
|
||||
>
|
||||
<FormItem
|
||||
v-if="formItems.prop"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
:form-data="formData"
|
||||
@outOperation="(val,num) => outOperation(val, index, formItems,num)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormItem from './formItem.vue';
|
||||
export default {
|
||||
components: {
|
||||
FormItem,
|
||||
},
|
||||
props: {
|
||||
formArr: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
methods: {
|
||||
outOperation(val, index, formItems, num) {
|
||||
// console.log('val, index, formItems, num', val, index, formItems, num);
|
||||
|
||||
if (formItems.onchange) {
|
||||
const changeFn = new Function('value', 'oldValue', formItems.onchange);
|
||||
changeFn.call(this, val, index, formItems, num);
|
||||
}
|
||||
|
||||
this.$emit('outOperation', val, index, formItems, num);
|
||||
},
|
||||
// 提交时验证表单,直接在父级调用
|
||||
submitForm() {
|
||||
let formValidate = Boolean;
|
||||
this.$refs.ruleForm.validate((valid) => {
|
||||
if (valid) {
|
||||
formValidate = true;
|
||||
} else {
|
||||
this.$message.warning('请把信息填写完整!');
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.ruleForm.resetFields();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
form {
|
||||
overflow: hidden;
|
||||
}
|
||||
::v-deep.el-form-item {
|
||||
width: 100%;
|
||||
// margin-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
::v-deep.el-form-item .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="value"
|
||||
class="cascader"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:options="formItems.options"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
v-bind="formItems.attrs"
|
||||
:props="{ expandTrigger: 'hover' }"
|
||||
v-on="formItems.events"
|
||||
@change="handleChangeEvent"
|
||||
@expand-change="handleExpandchangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.cascader {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.el-input__icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
::v-deep .el-cascader--mini {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-checkbox-group
|
||||
v-model="value"
|
||||
class="checkbox"
|
||||
size="mini"
|
||||
:value="value"
|
||||
v-on="formItems.events"
|
||||
@change="handleChangeEvent($event)"
|
||||
>
|
||||
<el-checkbox
|
||||
v-for="(options, i) in formItems.options"
|
||||
:key="i"
|
||||
:label="options.label"
|
||||
>
|
||||
{{ options.value }}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.checkbox {
|
||||
min-height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep.el-checkbox .el-checkbox__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
export default {
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
methods: {
|
||||
// --------------------- 组件内部方法 begin ------------------//
|
||||
handleInputEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleChangeEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleBlurEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleFocusEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleClearEvent(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
handleExpandchangeEvent() {},
|
||||
// --------------------- 组件内部方法 end ------------------//
|
||||
|
||||
// --------------------- 事件处理 begin ------------------//
|
||||
|
||||
// --------------------- 以上为组件支持外部调用的API方法 end ------------------//
|
||||
|
||||
},
|
||||
};
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="input-select">
|
||||
<el-input
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleChange"
|
||||
>
|
||||
<!-- 前文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.prepend
|
||||
}}
|
||||
</template>
|
||||
<!-- 后文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.append
|
||||
}}
|
||||
</template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs2?.filterable || true"
|
||||
v-bind="formItems.attrs2"
|
||||
@change="handleChange1"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.value[0] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 0);
|
||||
},
|
||||
handleChange1(val) {
|
||||
this.value[1] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.input-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInputEvent"
|
||||
@change="handleChangeEvent"
|
||||
@clear="handleClearEvent"
|
||||
>
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>{{
|
||||
formItems.attrs.prepend
|
||||
}}</template>
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>{{
|
||||
formItems.attrs.append
|
||||
}}</template>
|
||||
</el-input>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
::v-deep.el-input .el-input__inner::placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
@focus="handleFocus"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// d天 m月,y年,
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
digit: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.inputValue = this.value
|
||||
? this.value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
})
|
||||
: ''; // 转换千分位
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
},
|
||||
handleBlur() {
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'd') {
|
||||
unit = 1;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 30;
|
||||
} else if (lastLetter === 'y') {
|
||||
unit = 365;
|
||||
}
|
||||
this.inputValue = (num * unit).toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
}); // 转换千分位
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInput"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 1k => 1000 1m => 1000000 1b => 1000000000
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(nVal) {
|
||||
if (nVal) {
|
||||
const val = nVal.toString();
|
||||
this.inputValue = this.inputValueCopy = this.changePercentile(val);
|
||||
} else {
|
||||
this.inputValue = this.inputValueCopy = '';
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
},
|
||||
handleBlur() {
|
||||
this.delcomma();
|
||||
let inputValue = this.inputValue;
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'k') {
|
||||
unit = 3;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 6;
|
||||
} else if (lastLetter === 'b') {
|
||||
unit = 9;
|
||||
}
|
||||
inputValue = num * Math.pow(10, unit);
|
||||
}
|
||||
this.inputValue = this.changePercentile(inputValue);
|
||||
this.$emit('input', inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.delcomma();
|
||||
},
|
||||
// 转换千分位
|
||||
changePercentile(val) {
|
||||
return val.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.formItems?.attrs?.precision || 2,
|
||||
maximumFractionDigits: this.formItems?.attrs?.precision || 2,
|
||||
});
|
||||
},
|
||||
// 去掉","号
|
||||
delcomma() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="displayValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
@keydown="handleKeyDown"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isFocused: false,
|
||||
localValue: this.parseValue(this.value),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
displayValue() {
|
||||
if (this.isFocused) {
|
||||
return this.localValue.toString();
|
||||
}
|
||||
return this.formatNumber(this.localValue);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
if (!this.isFocused) {
|
||||
this.localValue = this.parseValue(newVal);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
parseValue(value) {
|
||||
const num = parseFloat(value);
|
||||
if (isNaN(num)) return 0;
|
||||
return num;
|
||||
},
|
||||
formatNumber(num) {
|
||||
if (isNaN(num)) return '0.00';
|
||||
return num.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.formItems?.attrs?.precision || 2,
|
||||
maximumFractionDigits: this.formItems?.attrs?.precision || 2,
|
||||
});
|
||||
},
|
||||
handleInput(e) {
|
||||
let value = e
|
||||
.replace(/[^\d.]/g, '') // 移除非数字和小数点
|
||||
.replace(/\.{2,}/g, '.') // 只保留第一个小数点
|
||||
.replace(/(\.\d*)\./g, '$1'); // 禁止输入多个小数点
|
||||
|
||||
// 处理开头的小数点
|
||||
if (value.startsWith('.')) {
|
||||
value = '0' + value;
|
||||
}
|
||||
|
||||
// 拆分整数和小数部分
|
||||
const parts = value.split('.');
|
||||
const integerPart = parts[0].replace(/\D/g, '');
|
||||
let decimalPart = parts[1] || '';
|
||||
|
||||
// 限制小数位数
|
||||
if (decimalPart.length > (this.formItems?.attrs?.precision || 2)) {
|
||||
decimalPart = decimalPart.substring(0, (this.formItems?.attrs?.precision || 2));
|
||||
}
|
||||
|
||||
// 拼接最终值
|
||||
const newValue = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
|
||||
const numericValue = parseFloat(newValue) || 0;
|
||||
|
||||
// 更新本地值和触发事件
|
||||
this.localValue = numericValue;
|
||||
// console.log('this.localValue', this.localValue);
|
||||
|
||||
this.$emit('input', this.localValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.isFocused = true;
|
||||
},
|
||||
handleBlur() {
|
||||
this.isFocused = false;
|
||||
this.localValue = this.parseValue(this.localValue);
|
||||
this.$emit('input', this.localValue);
|
||||
this.$emit('outOperation', this.localValue);
|
||||
},
|
||||
handleKeyDown(e) {
|
||||
// 阻止非法字符输入
|
||||
if (['e', 'E', '+', '-'].includes(e.key)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
:controls-position="formItems.attrs?.['controls-position'] || 'right'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 12px !important;
|
||||
}
|
||||
.el-input-number__increase{
|
||||
top:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.el-input-number--mini.is-controls-right {
|
||||
.el-input-number__decrease {
|
||||
bottom:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="titiebox">
|
||||
<div
|
||||
v-if="label"
|
||||
:style="{ width: width }"
|
||||
class="titieboxlabel"
|
||||
>
|
||||
{{ label }} <span
|
||||
v-if="needStar"
|
||||
style="color: #f00"
|
||||
>{{ "*" }}</span>
|
||||
</div>
|
||||
<div class="titieboxvalue">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
needStar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '150px',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.titiebox {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
border-left: 1px solid var(--card-border);
|
||||
width: 100%;
|
||||
.titieboxlabel {
|
||||
border-top: 1px solid var(--card-border);
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: left;
|
||||
background-color: var(--desktop-bg-color-2);
|
||||
}
|
||||
.titieboxvalue {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-date-picker
|
||||
class="datePicker"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择日期'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.el-range-editor {
|
||||
// height: 20px;
|
||||
// }
|
||||
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor .el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-date-picker
|
||||
class="datePicker"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择日期'"
|
||||
v-bind="formItems.attrs"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyyMMdd"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.el-range-editor {
|
||||
// height: 20px;
|
||||
// }
|
||||
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner,
|
||||
.eui-theme-default .el-date-editor--timerange.el-input,
|
||||
.eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
// 修复placeholder与日期图标重合的样式
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-date-picker
|
||||
class="datePicker"
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择日期'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.el-range-editor {
|
||||
// height: 20px;
|
||||
// }
|
||||
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner, .eui-theme-default .el-date-editor--timerange.el-input, .eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-time-picker
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择时间'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner, .eui-theme-default .el-date-editor--timerange.el-input, .eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner{
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-time-picker
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '选择时间'"
|
||||
v-bind="formItems.attrs"
|
||||
format="hh:mm"
|
||||
value-format="hhmm"
|
||||
@input="handleInputEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
import fieldMixin from '../fieldMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
mixins: [fieldMixin],
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-range-editor--mini .el-range-separator {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor--mini .el-range__icon {
|
||||
line-height: 16px;
|
||||
}
|
||||
::v-deep.el-range-editor.el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-date-editor--daterange.el-input__inner, .eui-theme-default .el-date-editor--timerange.el-input, .eui-theme-default .el-date-editor--timerange.el-input__inner {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner{
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-radio-group
|
||||
class="radio"
|
||||
size="mini"
|
||||
:value="value"
|
||||
@input="handleInputEvent"
|
||||
>
|
||||
<el-radio
|
||||
v-for="(options, i) in formItems.options"
|
||||
:key="i"
|
||||
:label="options.label"
|
||||
>
|
||||
{{ options.value }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.radio {
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="input-select">
|
||||
<el-select
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChange1"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs2"
|
||||
@input="handleChange"
|
||||
>
|
||||
<!-- 前文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs2?.prepend"
|
||||
slot="prepend"
|
||||
>
|
||||
{{
|
||||
formItems.attrs2.prepend
|
||||
}}
|
||||
</template>
|
||||
<!-- 后文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs2?.append"
|
||||
slot="append"
|
||||
>
|
||||
{{
|
||||
formItems.attrs2.append
|
||||
}}
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange1(val) {
|
||||
this.value[0] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 0);
|
||||
},
|
||||
handleChange(val) {
|
||||
this.value[1] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.input-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
::v-deep.el-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<!-- formItems.attrs为假的时候会返空-->
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="select-select">
|
||||
<el-select
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
@change="(val)=> handleChange(val,0)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options1"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs2?.filterable || true"
|
||||
v-bind="formItems.attrs2"
|
||||
@change="(val)=> handleChange(val,1)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options2"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formItems: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val, i) {
|
||||
this.value[i] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, i);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.select-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@change="handleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item[formItems.attrs?.optionLabel]||item.label||item.text"
|
||||
:value="item[formItems.attrs?.optionValue]||item.value"
|
||||
>
|
||||
<span style="float: left">{{ item[formItems.attrs?.optionLabel]||item.label||item.text }}</span>
|
||||
<span
|
||||
v-if="formItems.attrs?.showValueName"
|
||||
>({{ item[formItems.attrs?.showValueName]||item.value }})</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:remote-method="selectApi"
|
||||
:loading="loading"
|
||||
@focus="selectfocusApi"
|
||||
@change="handleInput"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
this.$emit('input', value);
|
||||
},
|
||||
selectApi(val) {
|
||||
// this.loading = true;
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
// 聚焦时候拿全部数据
|
||||
selectfocusApi() {
|
||||
// this.loading = true;
|
||||
this.$emit('outOperation', undefined);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs?.filterable || true"
|
||||
v-bind="formItems.attrs"
|
||||
popper-class="lazy-load-select"
|
||||
remote
|
||||
:loading="loading"
|
||||
:remote-method="remoteMethod"
|
||||
@change="handleChange"
|
||||
@visible-change="handleVisibleChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
<!-- 加载状态提示 -->
|
||||
<div
|
||||
v-if="formItems.attrs.loadingMore"
|
||||
class="load-more-tip"
|
||||
>
|
||||
<i class="el-icon-loading" /> 加载中...
|
||||
</div>
|
||||
<div
|
||||
v-if="formItems.attrs.noMore"
|
||||
class="no-more-tip"
|
||||
>没有更多数据了</div>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// loading: false,
|
||||
// loadingMore: false, //加载更多状态
|
||||
// noMore: false, // 是否没有更多数据
|
||||
// page: 1,
|
||||
// pageSize: 10,
|
||||
// total: 0,
|
||||
scrollEl: null, // 保存滚动元素引用
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
console.log(formItems.attrs.loadingMore);
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 关键点5:组件销毁前移除监听
|
||||
if (this.scrollEl) {
|
||||
this.scrollEl.removeEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
// 下拉框显示/隐藏状态变化
|
||||
handleVisibleChange(visible) {
|
||||
if (visible) {
|
||||
this.$nextTick(() => {
|
||||
// 关键点2:获取下拉框滚动元素
|
||||
this.scrollEl = document.querySelector(
|
||||
'.lazy-load-select .el-select-dropdown__wrap',
|
||||
);
|
||||
if (this.scrollEl) {
|
||||
this.scrollEl.addEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
});
|
||||
} else if (this.scrollEl) {
|
||||
// 移除监听
|
||||
this.scrollEl.removeEventListener('scroll', this.handleScroll);
|
||||
this.scrollEl = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 滚动事件处理
|
||||
handleScroll() {
|
||||
if (!this.scrollEl) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = this.scrollEl;
|
||||
const threshold = 50; // 距离底部阈值(px)
|
||||
|
||||
// 关键点3:判断是否滚动到底部
|
||||
if (scrollHeight - (scrollTop + clientHeight) < threshold) {
|
||||
this.loadMoreData();
|
||||
}
|
||||
},
|
||||
// 加载更多数据
|
||||
loadMoreData() {
|
||||
if (this.formItems.attrs.loadingMore || this.formItems.attrs.noMore) return;
|
||||
// this.page++;
|
||||
// this.loadData(true);
|
||||
this.$emit('getRequestData');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
/* 关键点6:自定义下拉框样式 */
|
||||
::v-deep.lazy-load-select .el-select-dropdown__wrap {
|
||||
max-height: 300px; /* 限制下拉框高度 */
|
||||
}
|
||||
|
||||
/* 加载提示样式 */
|
||||
.load-more-tip,
|
||||
.no-more-tip {
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.load-more-tip .el-icon-loading {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
ref="select"
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:multiple="false"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
style="width: 100%"
|
||||
v-bind="formItems.attrs"
|
||||
>
|
||||
<el-option
|
||||
ref="option"
|
||||
class="tree-select__option"
|
||||
:value="optionData.value"
|
||||
:label="optionData.label"
|
||||
>
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="tree-select__tree"
|
||||
:class="`tree-select__tree--${
|
||||
formItems.attrs?.multiple ? 'checked' : 'radio'
|
||||
}`"
|
||||
:node-key="nodeKey"
|
||||
:data="formItems.options"
|
||||
:props="props"
|
||||
:show-checkbox="formItems.attrs?.multiple || false"
|
||||
:highlight-current="!formItems.attrs?.multiple || false"
|
||||
:expand-on-click-node="formItems.attrs?.multiple || false"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="handleNodeClick"
|
||||
@check-change="handleCheckChange"
|
||||
/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'TreeSelect',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 每个树节点用来作为唯一标识的属性
|
||||
nodeKey: {
|
||||
type: [String, Number],
|
||||
default: 'value',
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// tree的props配置
|
||||
props: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
optionData: {
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
formItems: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
init(val) {
|
||||
// 多选
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
const arr = val.toString().split(',');
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys(arr);
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = nodes
|
||||
.map((item) => item[this.props.label])
|
||||
.join(',');
|
||||
});
|
||||
}
|
||||
// 单选
|
||||
else {
|
||||
val = val === '' ? null : val;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCurrentKey(val);
|
||||
if (val === null) {
|
||||
return;
|
||||
}
|
||||
const node = this.$refs.tree.getNode(val);
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = node.label;
|
||||
});
|
||||
}
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
return;
|
||||
}
|
||||
this.$emit('input', data[this.nodeKey]);
|
||||
this.$emit('outOperation', data[this.nodeKey]);
|
||||
this.$refs.select.visible = false;
|
||||
},
|
||||
handleCheckChange() {
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
const value = nodes.map((item) => item[this.nodeKey]).join(',');
|
||||
this.$emit('input', value);
|
||||
this.$emit('outOperation', value);
|
||||
},
|
||||
filterMethod(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
const label = this.props.label || 'label';
|
||||
return data[label].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tree-select__option {
|
||||
&.el-select-dropdown__item {
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-select__tree {
|
||||
padding: 4px 0px;
|
||||
font-weight: 400;
|
||||
&.tree-select__tree--radio {
|
||||
.el-tree-node.is-current > .el-tree-node__content {
|
||||
font-weight: 700;
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-select
|
||||
ref="select"
|
||||
v-model="value"
|
||||
size="mini"
|
||||
:multiple="false"
|
||||
:placeholder="formItems.attrs?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
style="width: 100%"
|
||||
v-bind="formItems.attrs"
|
||||
>
|
||||
<el-option
|
||||
ref="option"
|
||||
class="tree-select__option"
|
||||
:value="optionData.value"
|
||||
:label="optionData.label"
|
||||
>
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="tree-select__tree"
|
||||
:class="`tree-select__tree--${
|
||||
formItems.attrs?.multiple ? 'checked' : 'radio'
|
||||
}`"
|
||||
:node-key="nodeKey"
|
||||
:data="formItems.options"
|
||||
:props="props"
|
||||
:show-checkbox="formItems.attrs?.multiple || false"
|
||||
:highlight-current="!formItems.attrs?.multiple || false"
|
||||
:expand-on-click-node="formItems.attrs?.multiple || false"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="handleNodeClick"
|
||||
@check-change="handleCheckChange"
|
||||
/>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'TreeSelect',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 每个树节点用来作为唯一标识的属性
|
||||
nodeKey: {
|
||||
type: [String, Number],
|
||||
default: 'id',
|
||||
},
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// tree的props配置
|
||||
props: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {
|
||||
label: 'label',
|
||||
children: 'children',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
optionData: {
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
formItems: {
|
||||
handler(val) {
|
||||
if (this.formItems.prop && val) {
|
||||
this.init(val);
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
init(val) {
|
||||
// 多选
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
const arr = val.toString().split(',');
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCheckedKeys(arr);
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = nodes
|
||||
.map((item) => item[this.props.label])
|
||||
.join(',');
|
||||
});
|
||||
}
|
||||
// 单选
|
||||
else {
|
||||
val = val === '' ? null : val;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.tree.setCurrentKey(val);
|
||||
if (val === null) {
|
||||
return;
|
||||
}
|
||||
const node = this.$refs.tree.getNode(val);
|
||||
this.optionData.value = val;
|
||||
this.optionData.label = node.label;
|
||||
});
|
||||
}
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
if (this.formItems.attrs?.multiple) {
|
||||
return;
|
||||
}
|
||||
this.$emit('input', data[this.nodeKey]);
|
||||
this.$emit('outOperation', data[this.nodeKey]);
|
||||
this.$refs.select.visible = false;
|
||||
},
|
||||
handleCheckChange() {
|
||||
const nodes = this.$refs.tree.getCheckedNodes();
|
||||
const value = nodes.map((item) => item[this.nodeKey]).join(',');
|
||||
this.$emit('input', value);
|
||||
this.$emit('outOperation', value);
|
||||
},
|
||||
filterMethod(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
const label = this.props.label || 'label';
|
||||
return data[label].indexOf(value) !== -1;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tree-select__option {
|
||||
&.el-select-dropdown__item {
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.tree-select__tree {
|
||||
padding: 4px 0px;
|
||||
font-weight: 400;
|
||||
&.tree-select__tree--radio {
|
||||
.el-tree-node.is-current > .el-tree-node__content {
|
||||
font-weight: 700;
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 32px;
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
class="switch"
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-switch
|
||||
v-model="value"
|
||||
size="mini"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChangeEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.switch {
|
||||
min-height: 28px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
type="textarea"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
:value="value"
|
||||
v-bind="formItems.attrs"
|
||||
:autosize="{
|
||||
minRows: formItems.attrs.minRows,
|
||||
maxRows: formItems.attrs.maxRows,
|
||||
}"
|
||||
@input="handleInputEvent"
|
||||
@blur="handleBlurEvent"
|
||||
@change="handleChangeEvent"
|
||||
@focus="handleFocusEvent"
|
||||
@clear="handleClearEvent"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-textarea .el-textarea__inner {
|
||||
padding: 0 7px;
|
||||
line-height: 30px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-transfer
|
||||
v-model="value"
|
||||
class="transferBox"
|
||||
:value="value"
|
||||
:data="formItems.options"
|
||||
v-bind="formItems.attrs"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val, direction, movedKeys) {
|
||||
this.$emit('input', val, direction, movedKeys);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.transferBox {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep .el-transfer-panel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
::v-deep.transferBox .el-transfer__buttons {
|
||||
padding: 0 10px !important;
|
||||
.el-button {
|
||||
padding: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.transferBox {
|
||||
line-height: 24px;
|
||||
|
||||
.el-transfer-panel__header {
|
||||
height: 24px;
|
||||
.el-checkbox {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
.el-checkbox__label {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-checkbox__label {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.el-checkbox__input {
|
||||
// top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 文本 -->
|
||||
<CInput
|
||||
v-if="formItems.type === 'input'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 文本域 -->
|
||||
<CTextarea
|
||||
v-if="formItems.type==='textarea'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器 -->
|
||||
<CInputNumber
|
||||
v-if="formItems.type==='inputNumber'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 计数器2 -->
|
||||
<CInputNumber2
|
||||
v-if="formItems.type==='inputNumber2'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择 (单选 多选) -->
|
||||
<CSelect
|
||||
v-if="formItems.type==='select'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择(单选 多选) 调接口 -->
|
||||
<CSelectApi
|
||||
v-if="formItems.type==='selectApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选) -->
|
||||
<CSelectTree
|
||||
v-if="formItems.type==='selectTree'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 选择树(单选 多选)调接口 未完成 -->
|
||||
<CSelectTreeApi
|
||||
v-if="formItems.type==='selectTreeApi'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 金额(数字输入) -->
|
||||
<CInputFinance
|
||||
v-if="formItems.type==='inputFinance'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- input数字 年月日 -->
|
||||
<CInputDate
|
||||
v-if="formItems.type==='inputDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期选择器 -->
|
||||
<CPickerDate
|
||||
v-if="formItems.type==='pickerDate'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<CPickerTime
|
||||
v-if="formItems.type==='pickerTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 时间选择器 -->
|
||||
<CPickerTimeHHMM
|
||||
v-if="formItems.type==='pickerTimeHHMM'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期 时间 选择器 -->
|
||||
<CpickerDateTime
|
||||
v-if="formItems.type==='pickerDateTime'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 单选 -->
|
||||
<CRadio
|
||||
v-if="formItems.type==='radio'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 多选 -->
|
||||
<CCheckbox
|
||||
v-if="formItems.type==='checkbox'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 开关 -->
|
||||
<CSwitch
|
||||
v-if="formItems.type==='switch'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 级联选择 -->
|
||||
<CCascader
|
||||
v-if="formItems.type==='cascader'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 穿梭 -->
|
||||
<CTransfer
|
||||
v-if="formItems.type==='transfer'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 日期选择器拆分单个日期 -->
|
||||
<CPickerDateSingle
|
||||
v-if="formItems.type==='pickerDateSingle'"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
@outOperation="outOperation"
|
||||
/>
|
||||
|
||||
<!-- 上传-->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import CInput from './components/input';
|
||||
import CTextarea from './components/textarea';
|
||||
import CSelect from './components/select';
|
||||
import CSelectApi from './components/selectApi';
|
||||
import CSelectTree from './components/selectTree';
|
||||
import CSelectTreeApi from './components/selectTreeApi';
|
||||
import CInputNumber from './components/inputNumber';
|
||||
import CInputFinance from './components/inputFinance';
|
||||
import CInputDate from './components/inputDate';
|
||||
import CPickerDate from './components/pickerDate';
|
||||
import CPickerTime from './components/pickerTime';
|
||||
import CPickerTimeHHMM from './components/pickerTimeHHMM';
|
||||
import CpickerDateTime from './components/pickerDateTime';
|
||||
import CRadio from './components/radio';
|
||||
import CCheckbox from './components/checkbox';
|
||||
import CSwitch from './components/switch';
|
||||
import CCascader from './components/cascader';
|
||||
import CTransfer from './components/transfer';
|
||||
import CInputNumber2 from './components/inputNumber2';
|
||||
import CPickerDateSingle from './components/pickerDateSingle';
|
||||
export default {
|
||||
name: 'FormItem',
|
||||
components: {
|
||||
CInput,
|
||||
CTextarea,
|
||||
CSelect,
|
||||
CSelectApi,
|
||||
CSelectTree,
|
||||
CSelectTreeApi,
|
||||
CInputNumber,
|
||||
CInputFinance,
|
||||
CInputDate,
|
||||
CPickerDate,
|
||||
CPickerTime,
|
||||
CPickerTimeHHMM,
|
||||
CPickerDateSingle,
|
||||
CpickerDateTime,
|
||||
CRadio,
|
||||
CCheckbox,
|
||||
CSwitch,
|
||||
CCascader,
|
||||
CTransfer,
|
||||
CInputNumber2,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
},
|
||||
outOperation(val, num) {
|
||||
this.$emit('outOperation', val, num);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
v-for="(item, num) in formArr"
|
||||
:key="num"
|
||||
>
|
||||
<div class="card">
|
||||
<div class="htitle">
|
||||
<span class="label" />
|
||||
<span class="value">{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-form
|
||||
:ref="`ruleForm${num}`"
|
||||
:model="formData"
|
||||
class="bookkeeping-form"
|
||||
inline
|
||||
>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(formItems, num1) in item.formArr"
|
||||
v-show="!formItems.notShow"
|
||||
:key="num1"
|
||||
:span="formItems.span"
|
||||
>
|
||||
<el-form-item
|
||||
:label="null"
|
||||
:prop="formItems.prop"
|
||||
:rules="formItems.rules"
|
||||
>
|
||||
<FormItem
|
||||
v-if="formItems.prop"
|
||||
v-model="formData[formItems.prop]"
|
||||
:form-items="formItems"
|
||||
:form-data="formData"
|
||||
@outOperation="
|
||||
(val, num2) => outOperation(val, num, num1, num2, formItems,formItems.prop)
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormItem from './formItem.vue';
|
||||
export default {
|
||||
components: {
|
||||
FormItem,
|
||||
},
|
||||
props: {
|
||||
formArr: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
outOperation(val, num1, num2, num3, formItems, prop) {
|
||||
if (formItems.onchange) {
|
||||
const changeFn = new Function('value', 'oldValue', formItems.onchange);
|
||||
changeFn.call(this, val, num1, num2, num3, formItems);
|
||||
}
|
||||
this.$emit('outOperation', val, num1, num2, num3, formItems, prop);
|
||||
},
|
||||
submitForm() {
|
||||
let formValidate = true;
|
||||
this.formArr.forEach((_, index) => {
|
||||
this.$refs[`ruleForm${index}`][0].validate((valid) => {
|
||||
if (!valid) {
|
||||
formValidate = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
return formValidate;
|
||||
},
|
||||
resetForm() {
|
||||
this.formArr.forEach((_, index) => {
|
||||
this.$refs[`ruleForm${index}`][0].resetFields();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
form {
|
||||
overflow: hidden;
|
||||
}
|
||||
.bookkeeping-form {
|
||||
border-bottom: 1px solid var(--card-border);
|
||||
}
|
||||
.card {
|
||||
.htitle {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px 4px 0 0;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-top: 1px solid var(--card-border);
|
||||
border-left: 1px solid var(--card-border);
|
||||
border-right: 1px solid var(--card-border);
|
||||
.label {
|
||||
margin-left: 9px;
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
background-color: rgb(51, 137, 255);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.value {
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep.el-form-item {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
::v-deep.el-form-item .el-form-item__content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div
|
||||
class="search-form"
|
||||
:class="{ close: !search_open }"
|
||||
>
|
||||
<Form
|
||||
ref="form"
|
||||
class="form"
|
||||
:form-arr="formArr"
|
||||
:form-data="formData"
|
||||
@outOperation="outOperation"
|
||||
>
|
||||
<el-col
|
||||
v-if="!isShowSpread||(search_open&&isShowSpread)"
|
||||
:span="4"
|
||||
:class="searchStyle"
|
||||
>
|
||||
<div
|
||||
class="search"
|
||||
:style="isShowSpread?'text-align:right':''"
|
||||
>
|
||||
<slot name="defineBtn" />
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="searchSubmit"
|
||||
>查询</el-button>
|
||||
<!-- icon="el-icon-search" -->
|
||||
<el-button
|
||||
size="small"
|
||||
plain
|
||||
@click="reset"
|
||||
>重置</el-button>
|
||||
<el-button
|
||||
v-if="search_open&&isShowSpread"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="searchOpenClose(false)"
|
||||
>收起<i class="el-icon-arrow-up" /></el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</Form>
|
||||
<div
|
||||
v-if="!search_open&&isShowSpread"
|
||||
class="search"
|
||||
:style="isShowSpread?'text-align:right':''"
|
||||
>
|
||||
<slot name="defineBtn" />
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="searchSubmit"
|
||||
>查询</el-button>
|
||||
<!-- icon="el-icon-search" -->
|
||||
<el-button
|
||||
size="small"
|
||||
plain
|
||||
@click="reset"
|
||||
>重置</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="searchOpenClose(true)"
|
||||
>展开<i class="el-icon-arrow-down" /></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Form from '../form';
|
||||
export default {
|
||||
components: {
|
||||
Form,
|
||||
},
|
||||
props: {
|
||||
formArr: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search_open: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isShowSpread() {
|
||||
return this.formArr.reduce((sum, item) => sum + item.span, 0) > 24;
|
||||
},
|
||||
searchStyle() {
|
||||
return this.formArr.length % 6 === 0 ? 'search-class' : '';
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
created() {},
|
||||
methods: {
|
||||
outOperation(val, index, prop, num) {
|
||||
this.$emit('outOperation', val, index, prop, num);
|
||||
},
|
||||
searchSubmit() {
|
||||
if (this.$refs.form.submitForm()) {
|
||||
this.$emit('searchSubmit', this.formData);
|
||||
} else {
|
||||
console.log('submitForm Error');
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
this.$emit('reset');
|
||||
},
|
||||
resetForm() {
|
||||
this.$refs.form.resetForm();
|
||||
},
|
||||
searchOpenClose(boolean) {
|
||||
this.search_open = boolean;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-form {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
background-color: var(--bg-color-2);
|
||||
padding: 8px;
|
||||
.form {
|
||||
flex: 1;
|
||||
}
|
||||
.search {
|
||||
width: 220px;
|
||||
padding:3px 8px 0 ;
|
||||
|
||||
}
|
||||
}
|
||||
.search-class{
|
||||
float:right;
|
||||
.search{
|
||||
float:right
|
||||
}
|
||||
}
|
||||
.close {
|
||||
height: 50px;
|
||||
// overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="历史版本比较"
|
||||
:visible.sync="ownVisible"
|
||||
@close="handleCancel"
|
||||
>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
border
|
||||
:row-key="rowKey"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column align="right">
|
||||
<template
|
||||
slot="header"
|
||||
slot-scope="scope"
|
||||
>
|
||||
<span>{{ $t('field.version') }}</span>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ $t(`${scope.row.langId}`) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="right">
|
||||
<template
|
||||
slot="header"
|
||||
slot-scope="scope"
|
||||
>
|
||||
<el-select
|
||||
v-model="selectedValue[0]"
|
||||
@change="(value)=>versionChange(value,0)"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item,index) in options"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.text"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
:style="scope.row.versionData1===scope.row.versionData2?'':'color:red'"
|
||||
>{{ scope.row.versionData1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="right">
|
||||
<template
|
||||
slot="header"
|
||||
slot-scope="scope"
|
||||
>
|
||||
<el-select
|
||||
v-model="selectedValue[1]"
|
||||
@change="(value)=>versionChange(value,1)"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item,index) in options"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.text"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
:style="scope.row.versionData1===scope.row.versionData2?'':'color:red'"
|
||||
>{{ scope.row.versionData2 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
dataId: {
|
||||
type: String,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: false,
|
||||
},
|
||||
rowKey: {
|
||||
type: String,
|
||||
default: 'id',
|
||||
},
|
||||
module: {
|
||||
type: String,
|
||||
default: 'pub',
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
options: [],
|
||||
loading: false,
|
||||
ownVisible: false,
|
||||
selectedValue: [],
|
||||
apiObj: {
|
||||
pub: {
|
||||
getCompareVersion: 'getCompareVersion',
|
||||
versionsCombox: 'versionsCombox',
|
||||
compare: 'compare',
|
||||
},
|
||||
dcs: {
|
||||
getCompareVersion: 'getCompareVersionLog',
|
||||
versionsCombox: 'versionsLogCombox',
|
||||
compare: 'compareVersionLog',
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
handleCancel() {
|
||||
this.$emit('handleCancel');
|
||||
},
|
||||
versionChange(value, index) {
|
||||
this.getDataList();
|
||||
},
|
||||
onOpen() {
|
||||
this.$nextTick(async () => {
|
||||
const versionRes = await this.$apis[this.apiObj[this.module].getCompareVersion]({ dataId: this.dataId })
|
||||
if (versionRes.data.result.length === 0) {
|
||||
this.$message.warning('该条数据未存储过历史版本数据');
|
||||
this.$emit('handleCancel');
|
||||
this.ownVisible = false;
|
||||
return;
|
||||
}
|
||||
this.ownVisible = this.visible;
|
||||
this.loading = true;
|
||||
this.selectedValue = versionRes.data.result
|
||||
await this.getHistoryVersions();
|
||||
this.getDataList();
|
||||
})
|
||||
},
|
||||
async getHistoryVersions() {
|
||||
// 请求版本号接口
|
||||
const versionRes = await this.$apis[this.apiObj[this.module].versionsCombox]({ dataId: this.dataId })
|
||||
this.options = versionRes.data.result;
|
||||
},
|
||||
async getDataList() {
|
||||
// 请求表格数据
|
||||
const params = {
|
||||
type: this.type ? this.type : this.dataId.split('_')[0],
|
||||
dataId: this.dataId,
|
||||
version1: this.selectedValue[0],
|
||||
version2: this.selectedValue[1]
|
||||
}
|
||||
const versionRes = await this.$apis[this.apiObj[this.module].compare](params)
|
||||
if (versionRes.success) {
|
||||
this.tableData = versionRes.data.result
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep .el-table thead {
|
||||
// display: none;
|
||||
// }
|
||||
</style>
|
||||
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<svg
|
||||
class="icon"
|
||||
aria-hidden="true"
|
||||
:style="iconStyle"
|
||||
@click="handleClick"
|
||||
>
|
||||
<use :xlink:href="`#${name}`" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'IconFont',
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 16,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
iconStyle() {
|
||||
return {
|
||||
fontSize: typeof this.size === 'number' ? `${this.size}px` : this.size,
|
||||
color: this.color,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
this.$emit('click');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,324 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
title="导入"
|
||||
:visible.sync="visibleDialog"
|
||||
width="640px"
|
||||
@close="close"
|
||||
>
|
||||
<el-upload
|
||||
drag
|
||||
v-bind="$attrs"
|
||||
:show-file-list="false"
|
||||
:accept="fileConfig?.accept||'.xls,.xlsx'"
|
||||
:auto-upload="false"
|
||||
:on-change="uploadChange"
|
||||
>
|
||||
<i class="el-icon-upload" />
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div
|
||||
slot="tip"
|
||||
class="el-upload__tip"
|
||||
>
|
||||
<div>请按照数据模板的格式准备导入数据,模板中的表头名称不可更改,表头行不能删除
|
||||
<el-button
|
||||
type="text"
|
||||
:size="$buttonSize"
|
||||
@click="downloadTemplate"
|
||||
>下载模板</el-button></div>
|
||||
<div style="margin-bottom:16px">文件后缀名必须为xls 或xlsx(即Excel格式),文件大小不得大于1GB</div>
|
||||
<div class="file-list">
|
||||
<div
|
||||
v-for="(v,i) in fileList"
|
||||
:key="i"
|
||||
class="file-li"
|
||||
>
|
||||
<div>
|
||||
{{ v.name }}
|
||||
<el-button
|
||||
v-if="v.data.notImportableNum>0"
|
||||
type="text"
|
||||
:size="$buttonSize"
|
||||
@click="viewReason(v)"
|
||||
>查看原因</el-button>
|
||||
</div>
|
||||
<div class="right-status">
|
||||
<i
|
||||
:class="v.data.notImportableNum>0?'el-icon-error':'el-icon-success'"
|
||||
:style="v.data.notImportableNum>0?'color:red':'color:green'"
|
||||
/>
|
||||
</div>
|
||||
<div class="right-btn">
|
||||
<i
|
||||
class="el-icon-delete-solid"
|
||||
@click="deleteFileItem(v,i)"
|
||||
/>
|
||||
</div>
|
||||
<!-- <el-progress
|
||||
v-if="v.process!=100"
|
||||
:percentage="v.process"
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div></el-upload>
|
||||
<div
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<el-button
|
||||
:size="$buttonSize"
|
||||
@click="close"
|
||||
>{{
|
||||
$t("button.cancel")
|
||||
}}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:size="$buttonSize"
|
||||
@click="submit"
|
||||
>{{
|
||||
$t("button.confirm")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
title="查看原因"
|
||||
:visible.sync="failDialog"
|
||||
width="640px"
|
||||
@close="failClose"
|
||||
>
|
||||
<div class="import-false">
|
||||
<div class="false-box">
|
||||
<span class="fail-text">导入失败明细</span>
|
||||
<span class="fail-num">总数</span><span>{{ failObj.failNum+failObj.successNum }}</span>
|
||||
<span class="fail-num">通过</span><span style="color: rgba(32, 201, 139, 1);font-size: 16px;">{{ failObj.successNum }}</span>
|
||||
<span class="fail-num">失败</span><span style="color: rgba(233, 86, 82, 1);font-size: 16px;">{{ failObj.failNum }}</span>
|
||||
</div>
|
||||
<p style="margin-top:16px">以下是本次导入失败的列表详情,请修改后重新导入<el-button
|
||||
type="text"
|
||||
:size="$buttonSize"
|
||||
@click="downLoadReason"
|
||||
>下载失败原因</el-button></p>
|
||||
<el-table :data="failObj.list">
|
||||
<el-table-column
|
||||
v-for="v in tableColumns"
|
||||
:key="v.prop"
|
||||
:prop="v.prop"
|
||||
:label="v.label"
|
||||
:width="v.width"
|
||||
/>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
showDialog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
fileConfig: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleDialog: false,
|
||||
processData: {},
|
||||
fileList: [],
|
||||
failObj: {},
|
||||
failDialog: false,
|
||||
tableColumns: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
showDialog: {
|
||||
handler(nv) {
|
||||
this.visibleDialog = nv;
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
failClose() {
|
||||
this.failObj = {};
|
||||
},
|
||||
viewReason(row) { // 查看原因
|
||||
this.failObj = row.data;
|
||||
console.log(this.failObj, 'failObj');
|
||||
this.failDialog = true;
|
||||
},
|
||||
downLoadReason() { // 下载失败原因
|
||||
|
||||
},
|
||||
deleteFileItem(v, i) {
|
||||
this.fileList.splice(i, 1);
|
||||
},
|
||||
close() {
|
||||
this.visibleDialog = false;
|
||||
this.fileList = [];
|
||||
this.failObj = {};
|
||||
this.processData = {};
|
||||
this.$emit('update:showDialog', false);
|
||||
},
|
||||
jyFile(file) { // 校验文件
|
||||
console.log(file, 'file');
|
||||
const maxSize = this.fileConfig?.size ? this.fileConfig?.size * 1024 * 1024 : 1024 * 1024 * 1024; // 10MB,根据你的需求设置最大文件大小
|
||||
if (file.size > maxSize) {
|
||||
this.$message.warning(`文件大小超过了${maxSize / (1024 * 1024)}MB的限制`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
async uploadChange(e, fileList) {
|
||||
const file = e.raw;
|
||||
if (!this.jyFile(file)) return;
|
||||
console.log(file, fileList, this.fileConfig, 'file');
|
||||
const fileData = new FormData();
|
||||
for (const key in this.fileConfig.uploadParams) {
|
||||
if (Object.hasOwnProperty.call(this.fileConfig.uploadParams, key)) {
|
||||
fileData.append(key, key === 'param' ? JSON.stringify(this.fileConfig.uploadParams[key]) : this.fileConfig.uploadParams[key]);
|
||||
}
|
||||
}
|
||||
fileData.append('file', file);
|
||||
// const res = await this.$apis.importCheck(params);
|
||||
const url = window.origin.replace(/^https?:/, '') + (process.env.NODE_ENV !== 'production' ? '/dev' : '') + '/pub/baseData/importCheck.action';
|
||||
console.log(url, 'uuu');
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
body: fileData,
|
||||
}).then(response => response.json()) // 假设服务器返回 JSON 数据
|
||||
.then(async res => {
|
||||
await this.$apis.getProcess({ importKey: res.data.result }).then(res => {
|
||||
this.processData = res.data.result;
|
||||
this.fileList = [...this.fileList, { name: file.name, process: res.data.result.progress, data: res.data.result }];
|
||||
console.log(this.fileList, '文件');
|
||||
this.tableColumns = [
|
||||
{ label: '行号', prop: 'line', width: 100 },
|
||||
...res.data.result.columns.map(v => {
|
||||
return {
|
||||
label: v.title,
|
||||
prop: v.field,
|
||||
};
|
||||
}),
|
||||
{ label: '失败原因', prop: 'reason' },
|
||||
];
|
||||
console.log(this.tableColumns, 'this.tableColumns ');
|
||||
});
|
||||
this.$emit('importCallBack', file);
|
||||
});
|
||||
},
|
||||
async downloadTemplate() {
|
||||
const { data, fileName } = await this.$apis.downLoadTemplate({ moduleName: this.fileConfig.uploadParams.moduleName });
|
||||
console.log(data, fileName, 'flfl');
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(data);
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href);
|
||||
// const url = window.origin.replace(/^https?:/, '') + (process.env.NODE_ENV !== 'production' ? '/dev' : '') + `/pub/baseData/downloadTemplate.action?moduleName=${this.fileConfig.uploadParams.moduleName}`;
|
||||
// fetch(url, {
|
||||
// method: 'GET',
|
||||
// })
|
||||
// .then(async(response) => {
|
||||
// if (!response.ok) {
|
||||
// const text = await response.text();
|
||||
// throw new Error(text);
|
||||
// }
|
||||
// const contentDisposition = response.headers.get(
|
||||
// 'Content-Disposition',
|
||||
// );
|
||||
// let filename = '导出文件.csv'; // 默认值
|
||||
// if (contentDisposition) {
|
||||
// const filenameMatch = contentDisposition.match(
|
||||
// /filename=("?)([^";]+)\1/i,
|
||||
// );
|
||||
// if (filenameMatch && filenameMatch[2]) {
|
||||
// const encodedName = filenameMatch[2].replace(/\+/g, '%20');
|
||||
// filename = decodeURIComponent(encodedName);
|
||||
// }
|
||||
// }
|
||||
// return response.blob().then((blob) => ({ blob, filename }));
|
||||
// })
|
||||
// .then(({ blob, filename }) => {
|
||||
// console.log(blob, filename, '文件信息');
|
||||
// const link = document.createElement('a');
|
||||
// link.href = URL.createObjectURL(blob);
|
||||
// link.download = filename; // 动态设置文件名
|
||||
// document.body.appendChild(link);
|
||||
// link.click();
|
||||
// document.body.removeChild(link);
|
||||
// URL.revokeObjectURL(link.href);
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// console.error('下载失败:', error);
|
||||
// });
|
||||
// console.log(res, 'res');
|
||||
},
|
||||
submit() {
|
||||
this.$apis.importData({ importKey: this.processData.importKey }).then(res => {
|
||||
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-upload-dragger),:deep(.el-upload){
|
||||
width:100%
|
||||
}
|
||||
.import-false{
|
||||
color:var(--table-text-color);
|
||||
background-color: var(--card-bg);
|
||||
.false-box{
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
height:45px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.fail-text{
|
||||
color:var(--color-90);
|
||||
margin-right:12px
|
||||
}
|
||||
.fail-num{
|
||||
color:var(--color-44);
|
||||
font-size:12px;
|
||||
margin-left:25px
|
||||
}
|
||||
.file-li{
|
||||
height:24px;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding:0 8px;
|
||||
font-size:14px;
|
||||
.right-btn{
|
||||
display: none;
|
||||
}
|
||||
.right-status{
|
||||
display:block
|
||||
}
|
||||
i{
|
||||
font-size:14px
|
||||
}
|
||||
}
|
||||
.file-li:hover{
|
||||
background:var(--card-border);
|
||||
.right-btn{
|
||||
display:block
|
||||
}
|
||||
.right-status{
|
||||
display:none
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="config.title"
|
||||
:visible.sync="dialogVisible"
|
||||
:width="config.width"
|
||||
class="infoShow"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<ul
|
||||
class="box"
|
||||
:style="{ maxHeight: config.height }"
|
||||
>
|
||||
<li
|
||||
v-for="(item, index) in config.lists"
|
||||
:key="index"
|
||||
class="item"
|
||||
>
|
||||
<h4>{{ item.group }}</h4>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="(inner, idx) in item.children"
|
||||
:key="idx"
|
||||
:span="inner.col"
|
||||
>
|
||||
<span>{{ inner.key }}</span>
|
||||
<span>{{ inner.value }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</li>
|
||||
</ul>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InfoShow',
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
handleClose() {
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.infoShow{
|
||||
.box{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
.item{
|
||||
margin-bottom: 10px;
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
h4{
|
||||
margin: 10px 0;
|
||||
}
|
||||
.el-col{
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
span{
|
||||
display: inline-block;
|
||||
&:nth-of-type(1) {
|
||||
width: 90px;
|
||||
margin-right: 10px;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<div class="input-select">
|
||||
<el-input
|
||||
v-model="value[0]"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
@input="handleChange"
|
||||
>
|
||||
<!-- 前文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.prepend
|
||||
}}
|
||||
</template>
|
||||
<!-- 后文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>
|
||||
{{
|
||||
formItems.attrs.append
|
||||
}}
|
||||
</template>
|
||||
</el-input>
|
||||
<el-select
|
||||
v-model="value[1]"
|
||||
size="mini"
|
||||
style="margin-left:5px;"
|
||||
:placeholder="formItems.attrs2?.placeholder || '请选择'"
|
||||
:clearable="formItems.clearable || true"
|
||||
:filterable="formItems.attrs2?.filterable || true"
|
||||
v-bind="formItems.attrs2"
|
||||
@change="handleChange1"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in formItems.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleChange(val) {
|
||||
this.value[0] = val;
|
||||
console.log(this.value);
|
||||
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 0);
|
||||
},
|
||||
handleChange1(val) {
|
||||
this.value[1] = val;
|
||||
this.$emit('input', this.value);
|
||||
this.$emit('outOperation', val, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-select {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-select .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.input-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
size="mini"
|
||||
:value="value"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInput"
|
||||
>
|
||||
<!-- 前文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.prepend"
|
||||
slot="prepend"
|
||||
>{{
|
||||
formItems.attrs.prepend
|
||||
}}</template>
|
||||
<!-- 后文字 -->
|
||||
<template
|
||||
v-if="formItems.attrs?.append"
|
||||
slot="append"
|
||||
>{{
|
||||
formItems.attrs.append
|
||||
}}</template>
|
||||
</el-input>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input--prefix .el-input__inner {
|
||||
padding-left: 19px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@input="handleInput"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// d天 m月,y年,
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
export default {
|
||||
name: 'NumberInput',
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: null,
|
||||
},
|
||||
digit: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
inputValueCopy: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.inputValue = this.value
|
||||
? this.value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
})
|
||||
: ''; // 转换千分位
|
||||
},
|
||||
methods: {
|
||||
handleInput(value) {
|
||||
// 使用正则表达式限制只能输入数字、指定英文和一个小数点
|
||||
const regex = /^[0-9bkmBKM]*\.?[0-9bkmBKM]*$/;
|
||||
// 如果输入的值不符合正则规则,则回退到上一次的值
|
||||
if (!regex.test(value)) {
|
||||
this.inputValue = this.inputValueCopy;
|
||||
} else {
|
||||
this.inputValue = value;
|
||||
this.inputValueCopy = value;
|
||||
}
|
||||
},
|
||||
handleBlur() {
|
||||
if (this.inputValue) {
|
||||
const lastLetter = this.getLastLetter(this.inputValue);
|
||||
const firstLetter = this.getFirstLetter(this.inputValue);
|
||||
const num = firstLetter
|
||||
? this.inputValue.split(firstLetter)[0].replace(/[a-zA-Z]/g, '') * 1
|
||||
: this.inputValue.replace(/[a-zA-Z]/g, '') * 1; // 去除字母
|
||||
let unit = 0;
|
||||
if (lastLetter === 'd') {
|
||||
unit = 1;
|
||||
} else if (lastLetter === 'm') {
|
||||
unit = 30;
|
||||
} else if (lastLetter === 'y') {
|
||||
unit = 365;
|
||||
}
|
||||
this.inputValue = (num * unit).toLocaleString('en-US', {
|
||||
minimumFractionDigits: this.digit,
|
||||
maximumFractionDigits: this.digit,
|
||||
}); // 转换千分位
|
||||
}
|
||||
this.$emit('input', this.inputValue);
|
||||
this.$emit('outOperation', this.inputValue);
|
||||
},
|
||||
handleFocus() {
|
||||
this.inputValue = this.inputValueCopy = this.inputValue.replace(/,/g, '');
|
||||
},
|
||||
// 获取第一个字母
|
||||
getFirstLetter(str) {
|
||||
return str.match(/[a-zA-Z]/)?.[0] || '';
|
||||
},
|
||||
// 获取最后一个字母
|
||||
getLastLetter(str) {
|
||||
const letters = str.match(/[a-zA-Z]/g); // 使用正则表达式匹配所有字母
|
||||
if (letters) {
|
||||
return letters[letters.length - 1]; // 返回最后一个字母
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.input-box {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__icon {
|
||||
height: 24px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input-group__prepend {
|
||||
box-sizing: border-box;
|
||||
padding: 0 10px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
::v-deep.el-input .el-input__inner {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@change="handleInput"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formItems: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<LabelBox
|
||||
:label="formItems.attrs?.label"
|
||||
:need-star="formItems.attrs?.needStar"
|
||||
:width="formItems.attrs?.width"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="value"
|
||||
class="numberInput"
|
||||
size="mini"
|
||||
:placeholder="formItems.attrs?.placeholder || '请填写'"
|
||||
:controls-position="formItems.attrs?.['controls-position'] || 'right'"
|
||||
label="描述文字"
|
||||
v-bind="formItems.attrs"
|
||||
v-on="formItems.events"
|
||||
@change="handleInput"
|
||||
/>
|
||||
</LabelBox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LabelBox from '../labelBox/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LabelBox,
|
||||
},
|
||||
props: {
|
||||
formItems: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formItems: {},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formItems(newval) {
|
||||
this.formItems = newval;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput(val) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('outOperation', val);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep.el-input {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
::v-deep .el-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep.el-input-number--mini {
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease {
|
||||
width: 22px;
|
||||
height: 12px !important;
|
||||
}
|
||||
.el-input-number__increase{
|
||||
top:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.el-input-number--mini.is-controls-right {
|
||||
.el-input-number__decrease {
|
||||
bottom:2px;
|
||||
}
|
||||
}
|
||||
::v-deep.numberInput .el-input--mini {
|
||||
.el-input__inner {
|
||||
text-align: center;
|
||||
height: 24px;
|
||||
line-height: 23px;
|
||||
// color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="titiebox">
|
||||
<div
|
||||
v-if="label"
|
||||
:style="{ width: width }"
|
||||
class="titieboxlabel"
|
||||
>
|
||||
<span
|
||||
v-if="needStar"
|
||||
style="color: #f00"
|
||||
>{{ "*" }}</span>{{ label }}
|
||||
<!-- <span>{{ ':' }}</span> -->
|
||||
</div>
|
||||
<div class="titieboxvalue">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
needStar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100px',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.titiebox {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
.titieboxlabel {
|
||||
padding-right: 12px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: right;
|
||||
}
|
||||
.titieboxvalue {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
|
||||
export default [{
|
||||
value: 'zhinan',
|
||||
label: '指南1',
|
||||
children: [{
|
||||
value: 'shejiyuanze',
|
||||
label: '设计原则',
|
||||
children: [{
|
||||
value: 'yizhi',
|
||||
label: '一致',
|
||||
}, {
|
||||
value: 'fankui',
|
||||
label: '反馈',
|
||||
}, {
|
||||
value: 'xiaolv',
|
||||
label: '效率',
|
||||
}, {
|
||||
value: 'kekong',
|
||||
label: '可控',
|
||||
}],
|
||||
}, {
|
||||
value: 'daohang',
|
||||
label: '导航',
|
||||
children: [{
|
||||
value: 'cexiangdaohang',
|
||||
label: '侧向导航',
|
||||
}, {
|
||||
value: 'dingbudaohang',
|
||||
label: '顶部导航',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'zujian',
|
||||
label: '组件',
|
||||
children: [{
|
||||
value: 'basic',
|
||||
label: 'Basic',
|
||||
children: [{
|
||||
value: 'layout',
|
||||
label: 'Layout 布局',
|
||||
}, {
|
||||
value: 'color',
|
||||
label: 'Color 色彩',
|
||||
}, {
|
||||
value: 'typography',
|
||||
label: 'Typography 字体',
|
||||
}, {
|
||||
value: 'icon',
|
||||
label: 'Icon 图标',
|
||||
}, {
|
||||
value: 'button',
|
||||
label: 'Button 按钮',
|
||||
}],
|
||||
}, {
|
||||
value: 'form',
|
||||
label: 'Form',
|
||||
children: [{
|
||||
value: 'radio',
|
||||
label: 'Radio 单选框',
|
||||
}, {
|
||||
value: 'checkbox',
|
||||
label: 'Checkbox 多选框',
|
||||
}, {
|
||||
value: 'input',
|
||||
label: 'Input 输入框',
|
||||
}, {
|
||||
value: 'input-number',
|
||||
label: 'InputNumber 计数器',
|
||||
}, {
|
||||
value: 'select',
|
||||
label: 'Select 选择器',
|
||||
}, {
|
||||
value: 'cascader',
|
||||
label: 'Cascader 级联选择器',
|
||||
}, {
|
||||
value: 'switch',
|
||||
label: 'Switch 开关',
|
||||
}, {
|
||||
value: 'slider',
|
||||
label: 'Slider 滑块',
|
||||
}, {
|
||||
value: 'time-picker',
|
||||
label: 'TimePicker 时间选择器',
|
||||
}, {
|
||||
value: 'date-picker',
|
||||
label: 'DatePicker 日期选择器',
|
||||
}, {
|
||||
value: 'datetime-picker',
|
||||
label: 'DateTimePicker 日期时间选择器',
|
||||
}, {
|
||||
value: 'upload',
|
||||
label: 'Upload 上传',
|
||||
}, {
|
||||
value: 'rate',
|
||||
label: 'Rate 评分',
|
||||
}, {
|
||||
value: 'form',
|
||||
label: 'Form 表单',
|
||||
}],
|
||||
}, {
|
||||
value: 'data',
|
||||
label: 'Data',
|
||||
children: [{
|
||||
value: 'table',
|
||||
label: 'Table 表格',
|
||||
}, {
|
||||
value: 'tag',
|
||||
label: 'Tag 标签',
|
||||
}, {
|
||||
value: 'progress',
|
||||
label: 'Progress 进度条',
|
||||
}, {
|
||||
value: 'tree',
|
||||
label: 'Tree 树形控件',
|
||||
}, {
|
||||
value: 'pagination',
|
||||
label: 'Pagination 分页',
|
||||
}, {
|
||||
value: 'badge',
|
||||
label: 'Badge 标记',
|
||||
}],
|
||||
}, {
|
||||
value: 'notice',
|
||||
label: 'Notice',
|
||||
children: [{
|
||||
value: 'alert',
|
||||
label: 'Alert 警告',
|
||||
}, {
|
||||
value: 'loading',
|
||||
label: 'Loading 加载',
|
||||
}, {
|
||||
value: 'message',
|
||||
label: 'Message 消息提示',
|
||||
}, {
|
||||
value: 'message-box',
|
||||
label: 'MessageBox 弹框',
|
||||
}, {
|
||||
value: 'notification',
|
||||
label: 'Notification 通知',
|
||||
}],
|
||||
}, {
|
||||
value: 'navigation',
|
||||
label: 'Navigation',
|
||||
children: [{
|
||||
value: 'menu',
|
||||
label: 'NavMenu 导航菜单',
|
||||
}, {
|
||||
value: 'tabs',
|
||||
label: 'Tabs 标签页',
|
||||
}, {
|
||||
value: 'breadcrumb',
|
||||
label: 'Breadcrumb 面包屑',
|
||||
}, {
|
||||
value: 'dropdown',
|
||||
label: 'Dropdown 下拉菜单',
|
||||
}, {
|
||||
value: 'steps',
|
||||
label: 'Steps 步骤条',
|
||||
}],
|
||||
}, {
|
||||
value: 'others',
|
||||
label: 'Others',
|
||||
children: [{
|
||||
value: 'dialog',
|
||||
label: 'Dialog 对话框',
|
||||
}, {
|
||||
value: 'tooltip',
|
||||
label: 'Tooltip 文字提示',
|
||||
}, {
|
||||
value: 'popover',
|
||||
label: 'Popover 弹出框',
|
||||
}, {
|
||||
value: 'card',
|
||||
label: 'Card 卡片',
|
||||
}, {
|
||||
value: 'carousel',
|
||||
label: 'Carousel 走马灯',
|
||||
}, {
|
||||
value: 'collapse',
|
||||
label: 'Collapse 折叠面板',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'ziyuan',
|
||||
label: '资源',
|
||||
children: [{
|
||||
value: 'axure',
|
||||
label: 'Axure Components',
|
||||
}, {
|
||||
value: 'sketch',
|
||||
label: 'Sketch Templates',
|
||||
}, {
|
||||
value: 'jiaohu',
|
||||
label: '组件交互文档',
|
||||
}],
|
||||
}];
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<div
|
||||
class="operateCard"
|
||||
:style="{width: foldCard ? '24px': width}"
|
||||
>
|
||||
<div
|
||||
v-if="!foldCard"
|
||||
class="card"
|
||||
>
|
||||
<div class="title">
|
||||
<div
|
||||
v-if="iconLeftList?.length >0"
|
||||
class="left"
|
||||
>
|
||||
<el-tooltip
|
||||
v-for="(item,index) in iconLeftList"
|
||||
:key="index"
|
||||
:content="item.text"
|
||||
placement="bottom"
|
||||
effect="dark"
|
||||
class="custom-tooltip"
|
||||
>
|
||||
<i
|
||||
:class="[item.type,'left-icon']"
|
||||
@click="item.callback(value)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="center">
|
||||
<span class="ctitle">{{ title }}</span>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="iconRightList?.length >0"
|
||||
class="right"
|
||||
>
|
||||
<i
|
||||
v-for="(item,index) in iconRightList"
|
||||
:key="index"
|
||||
:class="[item.type,'right-icon']"
|
||||
@click="item.callback()"
|
||||
/>
|
||||
<i
|
||||
v-if="showFold"
|
||||
:class="['el-icon-d-arrow-left','right-icon']"
|
||||
@click="handlefoldCard(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
<el-input
|
||||
style="width: 90%;margin-left: 7%;margin-top: 8px;margin-bottom: 8px;"
|
||||
v-if="showSearch"
|
||||
placeholder="输入关键词,可快速查找..."
|
||||
v-model="filterText">
|
||||
</el-input>
|
||||
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:node-key="nodeKey"
|
||||
:data="formList"
|
||||
:render-content="renderContent"
|
||||
:props="{
|
||||
children: children,
|
||||
label: label
|
||||
}"
|
||||
v-bind="operateCardTreeAttrs"
|
||||
@node-click="handleNodeClick"
|
||||
:filter-node-method="filterNode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="foldCard"
|
||||
class="fold"
|
||||
>
|
||||
<i
|
||||
v-if="showFold"
|
||||
:class="['el-icon-d-arrow-right']"
|
||||
@click="handlefoldCard(false)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'OperatedCard',
|
||||
props: {
|
||||
//
|
||||
showSearch: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 标题
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
// key
|
||||
nodeKey: {
|
||||
type: String,
|
||||
default: 'id',
|
||||
},
|
||||
iconLeftList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
iconRightList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
formList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 折叠按钮
|
||||
showFold: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 组件宽度
|
||||
width: {
|
||||
type: String,
|
||||
default: '220px',
|
||||
},
|
||||
//
|
||||
children: {
|
||||
type: String,
|
||||
default: 'children',
|
||||
},
|
||||
//
|
||||
label: {
|
||||
type: String,
|
||||
default: 'label',
|
||||
},
|
||||
operateCardTreeAttrs: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
// 是否自定义渲染节点
|
||||
customRenderContent: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
renderContent: {
|
||||
type: Function,
|
||||
require: false,
|
||||
default: (h, { node, data }) => {
|
||||
return (<span class="">{data}</span>);
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filterText: '',
|
||||
foldCard: false,
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data[this.label].indexOf(value) !== -1;
|
||||
},
|
||||
handlefoldCard(bool) {
|
||||
this.foldCard = bool;
|
||||
},
|
||||
handleNodeClick(row) {
|
||||
this.$emit('handleNodeClick', row);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.operateCard {
|
||||
height: 100%;
|
||||
.card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--desktop-bg-color-1);
|
||||
// border: 1px solid var(--input-border);
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding: 0 5px;
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.left-icon {
|
||||
margin-right: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.center {
|
||||
font-size: 14px;
|
||||
.ctitle {
|
||||
font-weight: 700;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
.right-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
height: calc(100% - 30px);
|
||||
// padding: 12px;
|
||||
overflow: scroll;
|
||||
.content-items {
|
||||
height: 32px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
padding-left: 19px;
|
||||
font-size: 12px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.content-items:hover {
|
||||
background-color: #e6f2ff;
|
||||
}
|
||||
.content-items-selected {
|
||||
height: 32px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
padding-left: 19px;
|
||||
font-size: 12px;
|
||||
line-height: 32px;
|
||||
background: var(--blue-50);
|
||||
color: var(--card-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content){
|
||||
background: var(--blue-20);
|
||||
}
|
||||
:deep(.el-tree>.el-tree-node){
|
||||
min-width:100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.fold {
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
padding-left: 2px;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-tooltip {
|
||||
--el-tooltip-fill: #000000; /* 背景色 */
|
||||
--el-tooltip-color: #ffffff; /* 文字颜色 */
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user