Browse Source

feat:优化

master
wang 2 weeks ago
parent
commit
b512ccdb81
  1. 2
      src/components/support/file-upload/index.vue
  2. 101
      src/components/system/service-count/excel-statistics-detail.vue
  3. 21
      src/views/business/erp/cost/firm-reports-form.vue
  4. 24
      src/views/business/erp/service/service-applications-form.vue
  5. 31
      src/views/business/erp/service/service-applications-list.vue
  6. 2
      src/views/business/erp/service/service-applications-report-list.vue
  7. 32
      src/views/mobile/service/create.vue
  8. 4
      src/views/mobile/service/detail.vue
  9. 2
      src/views/system/account/components/center/index.vue
  10. 59
      src/views/system/home/home-header.vue
  11. 11
      src/views/system/login/login.less
  12. 1
      src/views/system/login/login.vue
  13. 19
      src/views/system/login3/login.less
  14. 69
      src/views/system/login3/login.vue

2
src/components/support/file-upload/index.vue

@ -213,7 +213,7 @@
}, },
maxSize: { maxSize: {
type: Number, type: Number,
default: 10, default: 50,
}, },
// //
accept: { accept: {

101
src/components/system/service-count/excel-statistics-detail.vue

@ -63,10 +63,22 @@
<div class="report-cell">序号</div> <div class="report-cell">序号</div>
<div class="report-cell">律师姓名</div> <div class="report-cell">律师姓名</div>
<div class="report-cell">执业证号</div> <div class="report-cell">执业证号</div>
<div class="report-cell">季度累计公益服务时长</div> <div class="report-cell sortable" @click="handleSort('quarterlyServiceDuration')">
<div class="report-cell">季度累计公益服务成本</div> 季度累计公益服务时长
<div class="report-cell">年度累计公益服务时长</div> <span class="sort-icon">{{ getSortIcon('quarterlyServiceDuration') }}</span>
<div class="report-cell">年度累计公益服务成本</div> </div>
<div class="report-cell sortable" @click="handleSort('quarterlyServiceCost')">
季度累计公益服务成本
<span class="sort-icon">{{ getSortIcon('quarterlyServiceCost') }}</span>
</div>
<div class="report-cell sortable" @click="handleSort('annualServiceDuration')">
年度累计公益服务时长
<span class="sort-icon">{{ getSortIcon('annualServiceDuration') }}</span>
</div>
<div class="report-cell sortable" @click="handleSort('annualServiceCost')">
年度累计公益服务成本
<span class="sort-icon">{{ getSortIcon('annualServiceCost') }}</span>
</div>
</div> </div>
<!-- 数据行 --> <!-- 数据行 -->
@ -76,9 +88,7 @@
<div class="report-cell">{{ item.certificateNumber || '-' }}</div> <div class="report-cell">{{ item.certificateNumber || '-' }}</div>
<div class="report-cell">{{ formatNumber(item.quarterlyServiceDuration) }}</div> <div class="report-cell">{{ formatNumber(item.quarterlyServiceDuration) }}</div>
<div class="report-cell">{{ formatCurrency(item.quarterlyServiceCost) }}</div> <div class="report-cell">{{ formatCurrency(item.quarterlyServiceCost) }}</div>
<!--<div class="report-cell">0</div>-->
<div class="report-cell">{{ formatNumber(item.annualServiceDuration) }}</div> <div class="report-cell">{{ formatNumber(item.annualServiceDuration) }}</div>
<!--<div class="report-cell">0</div>-->
<div class="report-cell">{{ formatCurrency(item.annualServiceCost) }}</div> <div class="report-cell">{{ formatCurrency(item.annualServiceCost) }}</div>
</div> </div>
@ -150,6 +160,66 @@ function initYearOptions() {
// //
const tableData = ref(props.tableData || []); const tableData = ref(props.tableData || []);
// { field: 'annualServiceCost', order: 'desc' | 'asc' | null }
const sortState = ref({ field: '', order: '' });
//
async function handleSort(field) {
let newOrder;
if (sortState.value.field !== field) {
//
newOrder = 'desc';
} else if (sortState.value.order === 'desc') {
//
newOrder = 'asc';
} else {
//
newOrder = 'desc';
}
sortState.value = { field, order: newOrder };
//
queryLoading.value = true;
try {
const params = {
...localQueryForm,
sortField: field,
sortOrder: newOrder
};
const res = await serviceApplicationsApi.statistics(params);
if (res.data && Array.isArray(res.data)) {
tableData.value = res.data.map(item => ({
...item,
quarterlyServiceDuration: Number(item.quarterlyServiceDuration) || 0,
quarterlyServiceCost: Number(item.quarterlyServiceCost) || 0,
annualServiceDuration: Number(item.annualServiceDuration) || 0,
annualServiceCost: Number(item.annualServiceCost) || 0
}));
} else {
tableData.value = [];
}
} catch (error) {
console.error('排序失败', error);
message.error('排序失败');
} finally {
queryLoading.value = false;
}
}
//
function getSortIcon(field) {
if (sortState.value.field !== field) {
return '⇅';
}
if (sortState.value.order === 'asc') {
return '↑';
}
if (sortState.value.order === 'desc') {
return '↓';
}
return '⇅';
}
// //
const summaryData = computed(() => { const summaryData = computed(() => {
@ -191,6 +261,8 @@ function formatCurrency(value) {
// //
async function handleQuery() { async function handleQuery() {
queryLoading.value = true; queryLoading.value = true;
//
sortState.value = { field: '', order: '' };
try { try {
const params = { const params = {
...localQueryForm ...localQueryForm
@ -368,4 +440,21 @@ onMounted(() => {
.report-row:last-child .report-cell { .report-row:last-child .report-cell {
border-bottom: none; border-bottom: none;
} }
/* 可排序列样式 */
.report-cell.sortable {
cursor: pointer;
user-select: none;
transition: background-color 0.2s;
}
.report-cell.sortable:hover {
background-color: #003399;
}
.sort-icon {
margin-left: 4px;
font-size: 12px;
opacity: 0.85;
}
</style> </style>

21
src/views/business/erp/cost/firm-reports-form.vue

@ -399,17 +399,21 @@
calculatedPublicWelfareCost.value = Math.min(publicWelfareCost, remainingAllowedCost).toFixed(2); calculatedPublicWelfareCost.value = Math.min(publicWelfareCost, remainingAllowedCost).toFixed(2);
const actualTotalCost = annualActualCost.value + parseFloat(calculatedPublicWelfareCost.value); // = /
const ratio = (actualTotalCost / totalRevenue) * 100; const ratio = (parseFloat(calculatedPublicWelfareCost.value) / totalRevenue) * 100;
form.costIncomeRatio = ratio.toFixed(2); form.costIncomeRatio = ratio.toFixed(2);
} else { } else {
calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2); calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2);
form.costIncomeRatio = costRatio.value.toFixed(2); // = /
const ratio = (publicWelfareCost / totalRevenue) * 100;
form.costIncomeRatio = ratio.toFixed(2);
} }
} else { } else {
showCostWarning.value = false; showCostWarning.value = false;
calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2); calculatedPublicWelfareCost.value = publicWelfareCost.toFixed(2);
form.costIncomeRatio = costRatio.value.toFixed(2); // = /
const ratio = (publicWelfareCost / totalRevenue) * 100;
form.costIncomeRatio = ratio.toFixed(2);
} }
} else { } else {
showCostWarning.value = false; showCostWarning.value = false;
@ -484,15 +488,10 @@
// //
saveData.publicWelfareCost = parseFloat(calculatedPublicWelfareCost.value); saveData.publicWelfareCost = parseFloat(calculatedPublicWelfareCost.value);
// // /
const totalRevenue = safeParseFloat(saveData.revenue) + safeParseFloat(annualIncomeInfo.value.revenue); const totalRevenue = safeParseFloat(saveData.revenue) + safeParseFloat(annualIncomeInfo.value.revenue);
const annualTotalCost = annualActualCost.value + safeParseFloat(saveData.publicWelfareCost); const ratio = totalRevenue > 0 ? ((safeParseFloat(saveData.publicWelfareCost) / totalRevenue) * 100) : 0;
let ratio = totalRevenue > 0 ? ((annualTotalCost / totalRevenue) * 100) : 0;
// 25%
if (ratio > 25) {
ratio = 25;
}
saveData.costIncomeRatio = ratio.toFixed(2); saveData.costIncomeRatio = ratio.toFixed(2);
} }

24
src/views/business/erp/service/service-applications-form.vue

@ -93,12 +93,12 @@
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="8"> <a-col :span="8">
<a-form-item label="服务开始时间" name="serviceStart" label-align="left"> <a-form-item label="服务开始时间" name="serviceStart" label-align="left">
<a-date-picker show-time format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceStart" style="width: 100%" placeholder="服务开始时间" :disabled="readonlyMode" /> <a-date-picker show-time format="YYYY-MM-DD HH:mm" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceStart" style="width: 100%" placeholder="服务开始时间" :disabled="readonlyMode" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
<a-form-item label="服务结束时间" name="serviceEnd" label-align="left"> <a-form-item label="服务结束时间" name="serviceEnd" label-align="left">
<a-date-picker show-time format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceEnd" style="width: 100%" placeholder="服务结束时间" :disabled="readonlyMode" /> <a-date-picker show-time format="YYYY-MM-DD HH:mm" valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceEnd" style="width: 100%" placeholder="服务结束时间" :disabled="readonlyMode" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="8"> <a-col :span="8">
@ -214,6 +214,20 @@
</template> </template>
<SmartWangeditor ref="serviceContentRef" v-model="form.serviceContent" :height="200" :readonly="readonlyMode" /> <SmartWangeditor ref="serviceContentRef" v-model="form.serviceContent" :height="200" :readonly="readonlyMode" />
</a-form-item> </a-form-item>
<!-- 备案信息仅详情模式且已备案时展示 -->
<a-row :gutter="16" v-if="readonlyMode && form.recordStatus === 1">
<a-col :span="12">
<a-form-item label="备案编号">
<a-input :value="form.filingNo" :disabled="true" />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="备案时间">
<a-input :value="form.recordTime" :disabled="true" />
</a-form-item>
</a-col>
</a-row>
<a-form-item name="proofMaterials" required> <a-form-item name="proofMaterials" required>
<template #label> <template #label>
<span class="ant-form-item-required">证明材料</span> <span class="ant-form-item-required">证明材料</span>
@ -224,7 +238,7 @@
<Upload <Upload
:defaultFileList="defaultFileList" :defaultFileList="defaultFileList"
:maxUploadSize="5" :maxUploadSize="5"
:maxSize="10" :maxSize="50"
:multiple="true" :multiple="true"
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.ppt,.pptx,.PNG,.JPG,.GIF" accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.ppt,.pptx,.PNG,.JPG,.GIF"
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value" :folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
@ -242,7 +256,7 @@
v-else v-else
:defaultFileList="defaultFileList" :defaultFileList="defaultFileList"
:maxUploadSize="5" :maxUploadSize="5"
:maxSize="10" :maxSize="50"
:multiple="true" :multiple="true"
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.ppt,.pptx,.PNG,.JPG,.GIF" accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.ppt,.pptx,.PNG,.JPG,.GIF"
:folder="FILE_FOLDER_TYPE_ENUM.COMMON.value" :folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
@ -580,6 +594,8 @@
attachmentIds: undefined, //ID attachmentIds: undefined, //ID
firmAuditStatus: undefined, //0-1-2-退 firmAuditStatus: undefined, //0-1-2-退
recordStatus: undefined, //0-1- recordStatus: undefined, //0-1-
filingNo: undefined, //
recordTime: undefined, //
updateTime: undefined, // updateTime: undefined, //
createTime: undefined, // createTime: undefined, //
}; };

31
src/views/business/erp/service/service-applications-list.vue

@ -62,6 +62,9 @@
<a-form-item label="执业机构审核时间" v-if="isCtoRole || isFirmRole" class="smart-query-form-item"> <a-form-item label="执业机构审核时间" v-if="isCtoRole || isFirmRole" class="smart-query-form-item">
<a-range-picker style="width: 240px" v-model:value="queryForm.firmAuditTimeRange" :placeholder="['开始时间', '结束时间']" /> <a-range-picker style="width: 240px" v-model:value="queryForm.firmAuditTimeRange" :placeholder="['开始时间', '结束时间']" />
</a-form-item> </a-form-item>
<a-form-item label="备案编号" class="smart-query-form-item">
<a-input style="width: 160px" v-model:value="queryForm.filingNo" placeholder="请输入备案编号" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10"> <a-form-item class="smart-query-form-item smart-margin-left10">
<a-button v-privilege="'serviceApplications:query'" type="primary" @click="onSearch"> <a-button v-privilege="'serviceApplications:query'" type="primary" @click="onSearch">
<template #icon> <template #icon>
@ -372,12 +375,14 @@ import dayjs from 'dayjs';
dataIndex: 'serviceStart', dataIndex: 'serviceStart',
ellipsis: true, ellipsis: true,
width: 100, width: 100,
customRender: ({ text }) => text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '',
}, },
{ {
title: '服务结束时间', title: '服务结束时间',
dataIndex: 'serviceEnd', dataIndex: 'serviceEnd',
ellipsis: true, ellipsis: true,
width: 100, width: 100,
customRender: ({ text }) => text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '',
}, },
{ {
title: '服务时长(小时)', title: '服务时长(小时)',
@ -450,6 +455,12 @@ import dayjs from 'dayjs';
dataIndex: 'associationAuditUserName', dataIndex: 'associationAuditUserName',
ellipsis: true, ellipsis: true,
}, },
{
title: '备案编号',
dataIndex: 'filingNo',
ellipsis: true,
width: 150,
},
{ {
title: '操作', title: '操作',
@ -472,6 +483,7 @@ import dayjs from 'dayjs';
firmAuditStatus: undefined, // firmAuditStatus: undefined, //
firmAuditTimeRange: undefined, // firmAuditTimeRange: undefined, //
associationAuditStatus: undefined, // associationAuditStatus: undefined, //
filingNo: undefined, //
selfFirmFilter: undefined, // selfFirmFilter: undefined, //
}; };
// form // form
@ -1487,19 +1499,18 @@ async function requestDelete(data){
return canReject; return canReject;
} else if (isCtoRole.value || isFirmAdmin.value) { } else if (isCtoRole.value || isFirmAdmin.value) {
// CTO44 // CTO
if (record.associationAuditStatus !== 4) { // 144
console.log('驳回按钮不显示:协会审核状态不是驳回', record.associationAuditStatus); // 230/null/undefined
return false; const isAssociationRejected = record.associationAuditStatus === 4 && record.firmAuditStatus !== 4;
} const isFirmApprovedNotReported = record.firmAuditStatus === 3 && (record.associationAuditStatus === 0 || record.associationAuditStatus === null || record.associationAuditStatus === undefined);
// 4 if (isAssociationRejected || isFirmApprovedNotReported) {
if (record.firmAuditStatus === 4) { return true;
console.log('驳回按钮不显示:执业机构审核状态是驳回', record.firmAuditStatus);
return false;
} }
return true; console.log('驳回按钮不显示:不满足(协会已驳回且律所未驳回),也不满足(律所已审核且协会未提交)');
return false;
} }
return false; return false;

2
src/views/business/erp/service/service-applications-report-list.vue

@ -290,12 +290,14 @@ import { getRoleInfo } from '/@/utils/role-util';
dataIndex: 'serviceStart', dataIndex: 'serviceStart',
ellipsis: true, ellipsis: true,
width: 100, width: 100,
customRender: ({ text }) => text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '',
}, },
{ {
title: '服务结束时间', title: '服务结束时间',
dataIndex: 'serviceEnd', dataIndex: 'serviceEnd',
ellipsis: true, ellipsis: true,
width: 100, width: 100,
customRender: ({ text }) => text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '',
}, },
{ {
title: '服务时长(小时)', title: '服务时长(小时)',

32
src/views/mobile/service/create.vue

@ -118,11 +118,13 @@
<label class="form-label required">服务开始时间</label> <label class="form-label required">服务开始时间</label>
<a-date-picker <a-date-picker
show-time show-time
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
v-model:value="form.serviceStart" v-model:value="form.serviceStart"
class="form-input" class="form-input"
placeholder="服务开始时间" placeholder="服务开始时间"
:minuteStep="5"
inputReadOnly
/> />
</div> </div>
@ -131,11 +133,13 @@
<label class="form-label required">服务结束时间</label> <label class="form-label required">服务结束时间</label>
<a-date-picker <a-date-picker
show-time show-time
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
v-model:value="form.serviceEnd" v-model:value="form.serviceEnd"
class="form-input" class="form-input"
placeholder="服务结束时间" placeholder="服务结束时间"
:minuteStep="5"
inputReadOnly
/> />
</div> </div>
@ -671,8 +675,8 @@ async function handleFileUpload(event) {
} }
for (let file of files) { for (let file of files) {
if (file.size > 10 * 1024 * 1024) { if (file.size > 50 * 1024 * 1024) {
message.error(`文件 ${file.name} 超过10MB限制`) message.error(`文件 ${file.name} 超过50MB限制`)
continue continue
} }
@ -1373,4 +1377,24 @@ onMounted(async () => {
font-size: 14px; font-size: 14px;
} }
} }
/* 时间选择器优化(移动端滚动体验) */
:deep(.ant-picker-time-panel) {
touch-action: pan-y;
-webkit-overflow-scrolling: touch;
}
:deep(.ant-picker-time-panel-column) {
-webkit-overflow-scrolling: touch;
overflow-y: auto;
}
:deep(.ant-picker-time-panel-cell-inner) {
font-size: 16px;
padding: 4px 0;
}
:deep(.ant-picker-dropdown) {
max-width: 100vw;
}
</style> </style>

4
src/views/mobile/service/detail.vue

@ -159,7 +159,7 @@
<label class="form-label">服务开始时间</label> <label class="form-label">服务开始时间</label>
<a-date-picker <a-date-picker
show-time show-time
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
v-model:value="form.serviceStart" v-model:value="form.serviceStart"
class="form-input" class="form-input"
@ -173,7 +173,7 @@
<label class="form-label">服务结束时间</label> <label class="form-label">服务结束时间</label>
<a-date-picker <a-date-picker
show-time show-time
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
v-model:value="form.serviceEnd" v-model:value="form.serviceEnd"
class="form-input" class="form-input"

2
src/views/system/account/components/center/index.vue

@ -164,7 +164,7 @@
// //
const accept = ref('.jpg,.jpeg,.png,.gif,.PNG,.GIF,.JPG'); const accept = ref('.jpg,.jpeg,.png,.gif,.PNG,.GIF,.JPG');
const maxSize = ref(10); const maxSize = ref(50);
const folder = ref(FILE_FOLDER_TYPE_ENUM.COMMON.value); const folder = ref(FILE_FOLDER_TYPE_ENUM.COMMON.value);
let updateAvatarLoading = ref(false); let updateAvatarLoading = ref(false);
function beforeUpload(file, files) { function beforeUpload(file, files) {

59
src/views/system/home/home-header.vue

@ -6,7 +6,7 @@
<a-card class="user-header"> <a-card class="user-header">
<a-page-header :title="welcomeSentence"> <a-page-header :title="welcomeSentence">
<template #subTitle> <template #subTitle>
<a-typography-text type="secondary" style="margin-left: 20px">所属部门 {{ departmentName }}</a-typography-text> <a-typography-text type="secondary" style="margin-left: 20px">执业机构 {{ departmentName }}</a-typography-text>
</template> </template>
<template #extra> <template #extra>
<a-typography-text type="secondary">{{ dayInfo }}</a-typography-text> <a-typography-text type="secondary">{{ dayInfo }}</a-typography-text>
@ -16,22 +16,13 @@
<p class="last-login-info"><AlertOutlined />{{ lastLoginInfo }}</p> <p class="last-login-info"><AlertOutlined />{{ lastLoginInfo }}</p>
<a class="sentence" href="#" target="_blank"> <smile-outlined spin /> {{ heartSentence }} </a> <a class="sentence" href="#" target="_blank"> <smile-outlined spin /> {{ heartSentence }} </a>
</span> </span>
<div class="weather">
<iframe
width="100%"
scrolling="no"
height="50"
frameborder="0"
allowtransparency="true"
src="//i.tianqi.com/index.php?c=code&id=12&icon=1&num=3&site=12"
></iframe>
</div>
</a-row> </a-row>
</a-page-header> </a-page-header>
</a-card> </a-card>
</template> </template>
<script setup> <script setup>
import { computed } from 'vue'; import { computed, ref, onMounted, onUnmounted } from 'vue';
import { useUserStore } from '/@/store/modules/system/user'; import { useUserStore } from '/@/store/modules/system/user';
import uaparser from 'ua-parser-js'; import uaparser from 'ua-parser-js';
import { Solar, Lunar } from 'lunar-javascript'; import { Solar, Lunar } from 'lunar-javascript';
@ -42,6 +33,27 @@
const departmentName = computed(() => userStore.departmentName); const departmentName = computed(() => userStore.departmentName);
//
const currentTime = ref('');
let timer = null;
function updateTime() {
const now = new Date();
const pad = (n) => String(n).padStart(2, '0');
currentTime.value = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
}
onMounted(() => {
updateTime();
timer = setInterval(updateTime, 1000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
// //
const welcomeSentence = computed(() => { const welcomeSentence = computed(() => {
let sentence = ''; let sentence = '';
@ -101,12 +113,11 @@
let lunar = Lunar.fromDate(new Date()); let lunar = Lunar.fromDate(new Date());
let lunarMonth = lunar.getMonthInChinese(); let lunarMonth = lunar.getMonthInChinese();
let lunarDay = lunar.getDayInChinese(); let lunarDay = lunar.getDayInChinese();
// // -
let jieqi = lunar.getJieQi();
let next = lunar.getNextJieQi(); let next = lunar.getNextJieQi();
let nextJieqi = next.getName() + ' ' + next.getSolar().toYmd(); let nextJieqi = next.getName() + ' ' + next.getSolar().toYmd();
return `${day} 星期${week},农历${lunarMonth}${lunarDay}当前${jieqi}${nextJieqi} `; return `${day} 星期${week},农历${lunarMonth}${lunarDay}下一个节气:${nextJieqi}`;
}); });
// //
@ -135,9 +146,25 @@
.content { .content {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
.weather { .city-time {
width: 400px; width: 400px;
text-align: right;
color: rgba(0, 0, 0, 0.65);
.city {
font-size: 16px;
font-weight: 500;
margin: 0;
color: #1890ff;
}
.time {
font-size: 14px;
margin: 4px 0 0 0;
color: #666;
}
} }
} }

11
src/views/system/login/login.less

@ -211,4 +211,15 @@
} }
} }
} }
.tech-contact {
position: fixed;
bottom: 20px;
left: 0;
right: 0;
text-align: center;
color: #ffffff;
font-size: 14px;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
} }

1
src/views/system/login/login.vue

@ -31,6 +31,7 @@
</a-form-item> </a-form-item>
</a-form> </a-form>
</div> </div>
<div class="tech-contact">技术支持电话18226700205</div>
</div> </div>
</template> </template>
<script setup> <script setup>

19
src/views/system/login3/login.less

@ -4,8 +4,16 @@
background: url(/@/assets/images/login/login-bg.png) no-repeat center; background: url(/@/assets/images/login/login-bg.png) no-repeat center;
background-size: cover; background-size: cover;
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.box-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.box-item { .box-item {
width: 460px; width: 460px;
height: 600px; height: 600px;
@ -24,6 +32,8 @@
border-radius: 0px 12px 12px 0px; border-radius: 0px 12px 12px 0px;
padding: 34px 42px; padding: 34px 42px;
position: relative; position: relative;
display: flex;
flex-direction: column;
} }
.login-qr { .login-qr {
position: absolute; position: absolute;
@ -170,6 +180,15 @@
line-height: 50px; line-height: 50px;
cursor: pointer; cursor: pointer;
} }
.tech-contact {
text-align: center;
color: #333333;
font-size: 13px;
margin-top: auto;
margin-bottom: 0;
padding-bottom: 0;
}
} }
.more { .more {

69
src/views/system/login3/login.vue

@ -4,40 +4,43 @@
--> -->
<template> <template>
<div class="login-container"> <div class="login-container">
<div class="box-item desc"> <div class="box-wrapper">
<div class="welcome"> <div class="box-item desc">
<p>欢迎登录</p> <div class="welcome">
<p class="sub-welcome">合肥市律师公益法律服务管理系统</p> <p>欢迎登录</p>
<p class="sub-welcome">合肥市律师公益法律服务管理系统</p>
</div>
<img class="welcome-img" :src="loginGif" />
</div>
<div class="box-item login">
<img class="login-qr" :src="loginQR" />
<div class="login-title">账号登录</div>
<a-form ref="formRef" class="login-form" :model="loginForm" :rules="rules">
<a-form-item name="loginName">
<a-input v-model:value.trim="loginForm.loginName" placeholder="请输入用户名" />
</a-form-item>
<a-form-item name="password">
<a-input-password
v-model:value="loginForm.password"
autocomplete="on"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入密码:至少三种字符,最小 8 位"
/>
</a-form-item>
<a-form-item name="captchaCode">
<a-input class="captcha-input" v-model:value.trim="loginForm.captchaCode" placeholder="请输入验证码" />
<img class="captcha-img" :src="captchaBase64Image" @click="getCaptcha" />
</a-form-item>
<a-form-item>
<a-checkbox v-model:checked="rememberPwd">记住密码</a-checkbox>
</a-form-item>
<a-form-item>
<div class="btn" @click="onLogin">登录</div>
</a-form-item>
</a-form>
<div class="tech-contact">技术支持联系电话王经理 18226700205</div>
</div> </div>
<img class="welcome-img" :src="loginGif" />
</div>
<div class="box-item login">
<img class="login-qr" :src="loginQR" />
<div class="login-title">账号登录</div>
<a-form ref="formRef" class="login-form" :model="loginForm" :rules="rules">
<a-form-item name="loginName">
<a-input v-model:value.trim="loginForm.loginName" placeholder="请输入用户名" />
</a-form-item>
<a-form-item name="password">
<a-input-password
v-model:value="loginForm.password"
autocomplete="on"
:type="showPassword ? 'text' : 'password'"
placeholder="请输入密码:至少三种字符,最小 8 位"
/>
</a-form-item>
<a-form-item name="captchaCode">
<a-input class="captcha-input" v-model:value.trim="loginForm.captchaCode" placeholder="请输入验证码" />
<img class="captcha-img" :src="captchaBase64Image" @click="getCaptcha" />
</a-form-item>
<a-form-item>
<a-checkbox v-model:checked="rememberPwd">记住密码</a-checkbox>
</a-form-item>
<a-form-item>
<div class="btn" @click="onLogin">登录</div>
</a-form-item>
</a-form>
</div> </div>
</div> </div>
</template> </template>

Loading…
Cancel
Save