Browse Source

提交代码

master
“wangzihua” 3 months ago
parent
commit
e0c371563a
  1. 2
      .env.development
  2. 2
      .env.localhost
  3. 2
      .env.pre
  4. 2
      .env.production
  5. 2
      .env.test
  6. BIN
      dist.zip
  7. 4
      index.html
  8. 7
      src/api/business/service-applications/service-applications-api.js
  9. BIN
      src/assets/images/logo/logo-min.png
  10. BIN
      src/assets/images/logo/logo-min2.png
  11. BIN
      src/assets/images/logo/smart-admin-logo.png
  12. BIN
      src/assets/images/logo/smart-admin-logo1.png
  13. 7
      src/components/business/category-tree-select/index.vue
  14. 2
      src/components/framework/icon-select/index.vue
  15. 2
      src/components/framework/smart-copy-icon/index.vue
  16. 46
      src/components/framework/wangeditor/index.vue
  17. 4
      src/components/system/service-count/firm-statistics-detail.vue
  18. 18
      src/components/system/service-count/quarter-statistics.vue
  19. 2
      src/config/app-config.js
  20. 2
      src/layout/components/side-expand-menu/top-menu.vue
  21. 9
      src/layout/components/side-menu/index.vue
  22. 110
      src/layout/components/side-menu/recursion-menu.vue
  23. 7
      src/layout/components/side-menu/sub-menu.vue
  24. 2
      src/layout/components/smart-footer/index.vue
  25. 2
      src/layout/components/top-expand-menu/recursion-menu.vue
  26. 6
      src/layout/components/top-menu/index.vue
  27. 4
      src/layout/help-doc-layout.vue
  28. 27
      src/layout/side-layout.vue
  29. 4
      src/layout/top-layout.vue
  30. 43
      src/views/business/erp/cost/firm-reports-form.vue
  31. 8
      src/views/business/erp/cost/firm-reports-list.vue
  32. 26
      src/views/business/erp/service/service-applications-count.vue
  33. 107
      src/views/business/erp/service/service-applications-form.vue
  34. 39
      src/views/business/erp/service/service-applications-list.vue
  35. 26
      src/views/system/home/components/agreement-modal.vue
  36. 2
      src/views/system/login3/login.vue
  37. 6
      src/views/system/position/position-form.vue
  38. 5
      src/views/system/position/position-list.vue
  39. 8
      vite.config.js

2
.env.development

@ -1,3 +1,3 @@
NODE_ENV=development
VITE_APP_TITLE='律师公益法律服务活动申报子系统'
VITE_APP_TITLE='合肥市律师公益法律服务管理系统'
VITE_APP_API_URL='/api'

2
.env.localhost

@ -1,3 +1,3 @@
NODE_ENV=development
VITE_APP_TITLE='律师公益法律服务活动申报子系统'
VITE_APP_TITLE='合肥市律师公益法律服务管理系统'
VITE_APP_API_URL='/api'

2
.env.pre

@ -1,3 +1,3 @@
NODE_ENV=production
VITE_APP_TITLE='律师公益法律服务活动申报子系统'
VITE_APP_TITLE='合肥市律师公益法律服务管理系统'
VITE_APP_API_URL='/api'

2
.env.production

@ -1,3 +1,3 @@
NODE_ENV=production
VITE_APP_TITLE='律师公益法律服务活动申报子系统'
VITE_APP_TITLE='合肥市律师公益法律服务管理系统'
VITE_APP_API_URL='/api'

2
.env.test

@ -1,3 +1,3 @@
NODE_ENV=production
VITE_APP_TITLE='律师公益法律服务活动申报子系统'
VITE_APP_TITLE='合肥市律师公益法律服务管理系统'
VITE_APP_API_URL='/api'

BIN
dist.zip

Binary file not shown.

4
index.html

@ -1,9 +1,5 @@
<!--
* @Description: 首页
* @Author: zhuoda
* @Date: 2021-08-03
* @LastEditTime: 2022-06-23
* @LastEditors: zhuoda
-->
<!DOCTYPE html>
<html lang="en" id="htmlRoot">

7
src/api/business/service-applications/service-applications-api.js

@ -98,6 +98,13 @@ export const serviceApplicationsApi = {
statisticsDepartment: (params) => {
return postRequest('/serviceApplications/statistics/department', params);
},
/**
* 查询详情 @author wzh
*/
queryDetail: (applicationId) => {
return getRequest(`/serviceApplications/queryDetail/${applicationId}`);
},
/**
* 导出律所统计信息 @author wzh

BIN
src/assets/images/logo/logo-min.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/assets/images/logo/logo-min2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/images/logo/smart-admin-logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/assets/images/logo/smart-admin-logo1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

7
src/components/business/category-tree-select/index.vue

@ -14,6 +14,7 @@
tree-default-expand-all
@change="onChange"
:field-names="{ label: 'label', value: 'value', children: 'children' }"
:disabled="disabled"
/>
</div>
</template>
@ -34,6 +35,10 @@
type: String,
default: '100%',
},
disabled: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['update:value', 'change']);
@ -159,6 +164,6 @@
:deep(.ant-select-tree-title::before) {
font-weight: bold;
margin-right: 5px;
color: #1890ff;
color: #1e3a8a;
}
</style>

2
src/components/framework/icon-select/index.vue

@ -128,6 +128,6 @@
}
}
.icon-content:hover {
background: #1890ff;
background: #1e3a8a;
}
</style>

2
src/components/framework/smart-copy-icon/index.vue

@ -17,7 +17,7 @@
},
color: {
type: String,
default: '#1890ff',
default: '#1e3a8a',
},
});

46
src/components/framework/wangeditor/index.vue

@ -50,30 +50,66 @@
editorConfig.MENU_CONF['uploadVideo'] = customUpload;
// ----------------------- emits props ----------------
const editorHtml = ref();
let props = defineProps({
modelValue: String,
modelValue: {
type: String,
default: ''
},
height: {
type: Number,
default: 500,
},
readonly: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['update:modelValue']);
const editorRef = shallowRef();
const editorHtml = ref(props.modelValue || '');
watch(
() => props.modelValue,
(nVal) => {
editorHtml.value = nVal;
editorHtml.value = nVal || '';
},
{
immediate: true,
deep: true,
}
);
//
watch(
() => props.readonly,
(newVal) => {
if (editorRef.value) {
if (newVal) {
//
if (!editorHtml.value) {
editorHtml.value = '<p>&nbsp;</p>';
}
editorRef.value.disable();
} else {
editorRef.value.enable();
}
}
},
{
immediate: true
}
);
// html
const emit = defineEmits(['update:modelValue']);
const editorRef = shallowRef();
const handleCreated = (editor) => {
editorRef.value = editor;
//
if (!editorHtml.value) {
editorHtml.value = '<p>&nbsp;</p>';
}
//
if (props.readonly) {
editor.disable();
}
};
const handleChange = (editor) => {
emit('update:modelValue', editorHtml.value);

4
src/components/system/service-count/firm-statistics-detail.vue

@ -175,7 +175,7 @@ onMounted(() => {
.back-btn {
margin-right: 20px;
color: #1890ff;
color: #1e3a8a;
}
.detail-title h2 {
@ -260,7 +260,7 @@ onMounted(() => {
}
.excel-header .excel-cell {
background: #1890ff;
background: #1e3a8a;
color: white;
border-right: 1px solid #40a9ff;
}

18
src/components/system/service-count/quarter-statistics.vue

@ -10,14 +10,7 @@
<!-- 查询表单 -->
<a-card title="查询条件" size="small" class="query-card">
<a-form :model="queryForm" layout="inline">
<a-form-item label="季度">
<a-select v-model:value="queryForm.quarter" placeholder="请选择季度" style="width: 120px">
<a-select-option v-for="quarter in quarterOptions" :key="quarter.value" :value="quarter.value">
{{ quarter.label }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="年度">
<a-select v-model:value="queryForm.year" placeholder="请选择年度" style="width: 120px">
<a-select-option v-for="year in yearOptions" :key="year" :value="year">
@ -25,6 +18,13 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="季度">
<a-select v-model:value="queryForm.quarter" placeholder="请选择季度" style="width: 120px">
<a-select-option v-for="quarter in quarterOptions" :key="quarter.value" :value="quarter.value">
{{ quarter.label }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="律师姓名" v-if="!isAdmin">
<a-input v-model:value="queryForm.lawyerName" placeholder="请输入律师姓名" style="width: 150px" />
@ -52,7 +52,7 @@
</a-card>
<!-- 统计表格 -->
<a-card :title="props.isAdmin ? '机构数据统计' : '季/年度服务统计'" size="small" class="table-card">
<a-card :title="props.isAdmin ? '机构数据统计' : '年/季度服务统计'" size="small" class="table-card">
<a-table
:columns="columns"
:dataSource="tableData"

2
src/config/app-config.js

@ -37,7 +37,7 @@ export const appDefaultConfig = {
// 水印
watermarkFlag: true,
// 网站名称
websiteName: '律师公益法律服务活动申报子系统',
websiteName: '合肥市律师公益法律服务管理系统',
// 主题颜色
primaryColor: '#1677ff',
// 紧凑

2
src/layout/components/side-expand-menu/top-menu.vue

@ -104,7 +104,7 @@
overflow: hidden;
word-wrap: break-word;
white-space: nowrap;
color: v-bind('theme === "light" ? "#001529": "#ffffff"');
color: v-bind('theme === "light" ? "#1e3a8a": "#ffffff"');
}
}
</style>

9
src/layout/components/side-menu/index.vue

@ -58,9 +58,8 @@
}
const color = computed(() => {
let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
return {
background: isLight ? '#FFFFFF' : '#001529',
background: '#1e3a8a',
};
});
</script>
@ -73,6 +72,9 @@
min-height: 100vh;
overflow-y: auto;
z-index: 10;
background-color: #1e3a8a !important;
box-shadow: none !important;
border-bottom: none !important;
.min-logo {
height: @header-user-height;
@ -115,7 +117,7 @@
padding: 4px 0;
}
.title-light {
color: #001529;
color: #1e3a8a;
}
.title-dark {
color: #ffffff;
@ -124,5 +126,6 @@
}
.menu {
margin-top: @header-user-height;
background-color: #1e3a8a;
}
</style>

110
src/layout/components/side-menu/recursion-menu.vue

@ -117,5 +117,115 @@
<style lang="less" scoped>
.smart-menu {
position: relative;
background-color: #1e3a8a !important;
/* 覆盖所有菜单组件的背景色 */
:deep(.ant-menu) {
background-color: #1e3a8a !important;
border: none !important;
box-shadow: none !important;
background-image: none !important;
}
:deep(.ant-menu-root) {
background-color: #1e3a8a !important;
}
:deep(.ant-menu-inline) {
background-color: #1e3a8a !important;
}
:deep(.ant-menu-sub) {
background-color: #1e3a8a !important;
}
:deep(.ant-menu-submenu-popup) {
background-color: #1e3a8a !important;
}
/* 覆盖所有菜单项的样式 */
:deep(.ant-menu-item) {
color: #ffffff !important;
background-color: #1e3a8a !important;
border: none !important;
box-shadow: none !important;
background-image: none !important;
}
:deep(.ant-menu-item-selected) {
background-color: #2563eb !important;
color: #ffffff !important;
border: none !important;
}
:deep(.ant-menu-item:hover) {
background-color: #3b82f6 !important;
color: #ffffff !important;
border: none !important;
}
/* 覆盖所有子菜单的样式 */
:deep(.ant-menu-submenu-title) {
color: #ffffff !important;
background-color: #1e3a8a !important;
border: none !important;
background-image: none !important;
}
:deep(.ant-menu-submenu-title:hover) {
background-color: #3b82f6 !important;
color: #ffffff !important;
border: none !important;
}
:deep(.ant-menu-submenu-arrow) {
color: #ffffff !important;
}
:deep(.ant-menu-submenu-open .ant-menu-submenu-title) {
background-color: #2563eb !important;
color: #ffffff !important;
border: none !important;
}
/* 移除所有分隔线和边框 */
:deep(.ant-menu-item::after) {
display: none !important;
}
:deep(.ant-menu-submenu::after) {
display: none !important;
}
:deep(.ant-menu-item-group-title) {
border-bottom: none !important;
color: #ffffff !important;
}
:deep(.ant-menu-divider) {
background-color: #1e3a8a !important;
}
:deep(.ant-menu-vertical .ant-menu-item::after) {
display: none !important;
}
:deep(.ant-menu-inline .ant-menu-item::after) {
display: none !important;
}
:deep(.ant-menu-submenu-vertical > .ant-menu-submenu-title::after) {
display: none !important;
}
/* 确保菜单内容区域也是公安蓝 */
:deep(.ant-menu-content) {
background-color: #1e3a8a !important;
}
/* 确保菜单列表区域也是公安蓝 */
:deep(.ant-menu-list) {
background-color: #1e3a8a !important;
}
}
</style>

7
src/layout/components/side-menu/sub-menu.vue

@ -1,11 +1,6 @@
<!--
* 传统菜单-递归菜单
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:29:12
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-sub-menu :key="menuInfo.menuId">

2
src/layout/components/smart-footer/index.vue

@ -3,7 +3,7 @@
-->
<template>
<div class="version">
<a target="_blank" class="smart-copyright">{{ currentYear }}@ 律师公益法律服务活动申报子系统</a><a style="margin-left:20px">服务经理:王浩</a><a style="margin-left:10px">联系方式:18226700205</a>
<a target="_blank" class="smart-copyright">{{ currentYear }}@ 安徽三朵云信息科技有限公司</a><a style="margin-left:20px">服务经理:王浩</a><a style="margin-left:10px">联系方式:18226700205</a>
</div>
</template>
<script setup>

2
src/layout/components/top-expand-menu/recursion-menu.vue

@ -173,7 +173,7 @@
justify-content: space-between;
align-items: center;
cursor: pointer;
background-color: #001529;
background-color: #1e3a8a;
.logo-img {
width: 30px;

6
src/layout/components/top-menu/index.vue

@ -82,8 +82,8 @@
const color = computed(() => {
let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
return {
color: isLight ? '#001529' : '#FFFFFF',
background: isLight ? '#FFFFFF' : '#001529',
color: isLight ? '#1e3a8a' : '#FFFFFF',
background: isLight ? '#FFFFFF' : '#1e3a8a',
};
});
@ -127,7 +127,7 @@
margin-left: 8px;
}
.title-light {
color: #001529;
color: #1e3a8a;
}
.title-dark {
color: #ffffff;

4
src/layout/help-doc-layout.vue

@ -256,7 +256,7 @@
font-weight: 600;
margin-left: 10px;
text-align: center;
color: '#001529';
color: '#1e3a8a';
}
.avatar {
position: fixed;
@ -276,7 +276,7 @@
height: 100vh;
overflow: scroll;
.help-doc-tree {
color: #001529;
color: #1e3a8a;
margin-top: 10px;
font-size: 16px;
}

27
src/layout/side-layout.vue

@ -293,6 +293,33 @@
height: 100vh;
overflow-x: hidden;
overflow-y: scroll;
background-color: #1e3a8a !important;
:deep(.ant-layout-sider) {
background-color: #1e3a8a !important;
}
:deep(.ant-layout-sider-children) {
background-color: #1e3a8a !important;
}
:deep(.ant-layout-sider-trigger) {
background-color: #1e3a8a !important;
color: #ffffff !important;
}
:deep(.ant-layout-sider-trigger:hover) {
background-color: #3b82f6 !important;
}
:deep(.ant-layout-sider-zero-width-trigger) {
background-color: #1e3a8a !important;
color: #ffffff !important;
}
:deep(.ant-layout-sider-zero-width-trigger:hover) {
background-color: #3b82f6 !important;
}
&.fixed-side {
position: fixed;

4
src/layout/top-layout.vue

@ -72,8 +72,8 @@
const color = computed(() => {
let isLight = useAppConfigStore().$state.sideMenuTheme === 'light';
return {
color: isLight ? '#001529' : '#FFFFFF',
background: isLight ? '#FFFFFF' : '#001529',
color: isLight ? '#1e3a8a' : '#FFFFFF',
background: isLight ? '#FFFFFF' : '#1e3a8a',
};
});

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

@ -14,11 +14,20 @@
:maskClosable="false"
:destroyOnClose="true"
>
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }" >
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 8 }" >
<a-form-item label="律师事务所">
<a-input v-model:value="departmentName" placeholder="律师事务所" disabled />
</a-form-item>
<a-form-item label="报表年份" name="declareYear">
<a-input-number
style="width: 100%"
v-model:value="form.declareYear"
placeholder="请输入报表年份"
disabled
:min="2000"
:max="2100"
/>
</a-form-item>
<a-form-item label="季度" name="declareQuarter">
<DictSelect
dict-code="QUARTER"
@ -53,18 +62,6 @@
/>
</a-form-item>
<a-form-item label="其他成本(万元)" name="otherCost">
<a-input-number
style="width: 100%"
v-model:value="form.otherCost"
placeholder="请输入其他成本"
:min="0"
:precision="2"
@change="calculateCosts"
addon-after="万元"
/>
</a-form-item>
<a-row>
<a-col :span="12">
<a-form-item label="总成本(万元)" :label-col="{ span: 12 }" :wrapper-col="{ span: 12 }">
@ -88,24 +85,13 @@
</a-form-item>
</a-col>
</a-row>
<a-form-item label="报表年份" name="declareYear">
<a-input-number
style="width: 100%"
v-model:value="form.declareYear"
placeholder="请输入报表年份"
disabled
:min="2000"
:max="2100"
/>
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button @click="onClose">取消</a-button>
<a-button @click="saveAsDraft" type="default" v-if="!form.id">保存草稿</a-button>
<a-button type="primary" @click="submitForReview">提交审核</a-button>
<a-button type="primary" @click="submitForReview">提交</a-button>
</a-space>
</template>
</a-modal>
@ -189,10 +175,9 @@
function calculateCosts() {
const revenue = parseFloat(form.revenue) || 0;
const publicWelfareCost = parseFloat(form.publicWelfareCost) || 0;
const otherCost = parseFloat(form.otherCost) || 0;
//
const totalCost = publicWelfareCost + otherCost;
//
const totalCost = publicWelfareCost;
form.totalCost = totalCost;
// /

8
src/views/business/erp/cost/firm-reports-list.vue

@ -163,7 +163,7 @@
return text ? `${text}%` : '';
},
},
{
/**{
title: '审批状态',
dataIndex: 'approvalStatus',
ellipsis: true,
@ -171,17 +171,17 @@
const status = Object.values(REVIEW_STATUS_ENUM).find(item => item.value === text);
return status ? status.desc : text;
},
},
},**/
{
title: '提交时间',
dataIndex: 'submissionTime',
ellipsis: true,
},
{
/** {
title: '审批人',
dataIndex: 'approverId',
ellipsis: true,
},
},**/
{
title: '操作',
dataIndex: 'action',

26
src/views/business/erp/service/service-applications-count.vue

@ -13,10 +13,18 @@
<div v-if="!showResultView">
<a-card title="机构数据查询" class="admin-excel-card">
<div class="excel-description">
<p>作为协议您可以查看机构级别的统计数据数据以Excel表格样式展示</p>
<p>作为律师协会您可以查看机构级别的统计数据数据以Excel表格样式展示</p>
<p>请选择需要查看的季度和年度然后点击查询按钮</p>
</div>
<a-form-item label="年度" :label-col="{ span: 4 }" :wrapper-col="{ span: 8 }">
<a-select v-model:value="queryForm.year" placeholder="请选择年度" style="width: 200px">
<a-select-option :value="2026">2026</a-select-option>
<a-select-option :value="2027">2027</a-select-option>
<a-select-option :value="2028">2028</a-select-option>
<a-select-option :value="2029">2029</a-select-option>
<a-select-option :value="2030">2030</a-select-option>
</a-select>
</a-form-item>
<a-form :model="queryForm" layout="horizontal" class="query-form">
<a-form-item label="季度" :label-col="{ span: 4 }" :wrapper-col="{ span: 8 }">
<a-select v-model:value="queryForm.quarter" placeholder="请选择季度" style="width: 200px">
@ -27,16 +35,6 @@
</a-select>
</a-form-item>
<a-form-item label="年度" :label-col="{ span: 4 }" :wrapper-col="{ span: 8 }">
<a-select v-model:value="queryForm.year" placeholder="请选择年度" style="width: 200px">
<a-select-option :value="2026">2026</a-select-option>
<a-select-option :value="2027">2027</a-select-option>
<a-select-option :value="2028">2028</a-select-option>
<a-select-option :value="2029">2029</a-select-option>
<a-select-option :value="2030">2030</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="机构名称" :label-col="{ span: 4 }" :wrapper-col="{ span: 8 }">
<!--<a-input v-model:value="queryForm.firmName" placeholder="请输入机构名称(可选)" style="width: 300px; margin-bottom: 8px;" />-->
<div class="department-selector">
@ -400,9 +398,9 @@ function handleBackToQuery() {
}
.excel-header .excel-cell {
background: #1890ff;
background: #1e3a8a;
color: white;
border-right: 1px solid #40a9ff;
border-right: 1px solid #3b82f6;
}
.excel-data .excel-cell {

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

@ -41,7 +41,13 @@
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="8">
<a-form-item label="职务" name="positionId">
<PositionSelect v-model:value="form.positionId" placeholder="请选择职务" width="100%" :disabled="readonlyMode" />
</a-form-item>
</a-col>
</a-row>
<!-- 服务信息 -->
<a-row :gutter="16">
<a-col :span="24">
@ -53,20 +59,21 @@
<!-- 服务时间信息 -->
<a-row :gutter="24">
<a-col :span="8">
<a-form-item label="服务开始时间" name="serviceStart">
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceStart" style="width: 100%" placeholder="服务开始时间" />
<a-col :span="8">
<a-form-item label="服务开始时间" name="serviceStart" label-align="left">
<a-date-picker show-time format="YYYY-MM-DD HH:00:00" valueFormat="YYYY-MM-DD HH:00:00" v-model:value="form.serviceStart" style="width: 100%" placeholder="服务开始时间" :disabled="readonlyMode" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="服务结束时间" name="serviceEnd">
<a-date-picker show-time valueFormat="YYYY-MM-DD HH:mm:ss" v-model:value="form.serviceEnd" style="width: 100%" placeholder="服务结束时间" />
<a-form-item label="服务结束时间" name="serviceEnd" label-align="left">
<a-date-picker show-time format="YYYY-MM-DD HH:00:00" valueFormat="YYYY-MM-DD HH:00:00" v-model:value="form.serviceEnd" style="width: 100%" placeholder="服务结束时间" :disabled="readonlyMode" />
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="服务时长(小时)" name="serviceDuration">
<a-input-number style="width: 100%" v-model:value="form.serviceDuration" placeholder="服务时长(小时)" />
<a-input-number style="width: 100%" v-model:value="form.serviceDuration" placeholder="服务时长(小时)" :disabled="readonlyMode" />
</a-form-item>
<div style="font-size: 12px; color: #999; margin-top: -12px; margin-bottom: 12px;">不足30分钟不含本数不计入时长超过30分钟不足1个小时的含本数按照一个小时填报</div>
</a-col>
</a-row>
@ -74,14 +81,15 @@
<a-row :gutter="16">
<a-col :span="8">
<a-form-item label="活动类型" name="activityCategoryId">
<CategoryTree
v-model:value="form.activityCategoryId"
:category-type="CATEGORY_TYPE_ENUM.GOODS.value"
placeholder="请选择活动类型"
style="width: 100%"
@change="onActivityCategoryChange"
/>
</a-form-item>
<CategoryTree
v-model:value="form.activityCategoryId"
:category-type="CATEGORY_TYPE_ENUM.GOODS.value"
placeholder="请选择活动类型"
style="width: 100%"
:disabled="readonlyMode"
@change="onActivityCategoryChange"
/>
</a-form-item>
</a-col>
<a-col :span="16">
<a-form-item label="活动名称" name="activityNameId">
@ -89,7 +97,7 @@
v-model:value="form.activityNameId"
placeholder="请选择活动名称"
style="width: 100%"
:disabled="!form.activityCategoryId"
:disabled="!form.activityCategoryId || readonlyMode"
:options="activityList"
show-search
:filter-option="filterActivityOption"
@ -102,12 +110,12 @@
<a-row :gutter="16">
<a-col :span="8">
<a-form-item label="受益人数" name="beneficiaryCount">
<a-input-number style="width: 100%" v-model:value="form.beneficiaryCount" placeholder="受益人数" />
<a-input-number style="width: 100%" v-model:value="form.beneficiaryCount" placeholder="受益人数" :disabled="readonlyMode" />
</a-form-item>
</a-col>
<a-col :span="16">
<a-form-item label="组织单位名称" name="organizerName">
<a-input style="width: 100%" v-model:value="form.organizerName" placeholder="组织单位名称" />
<a-input style="width: 100%" v-model:value="form.organizerName" placeholder="组织单位名称" :disabled="readonlyMode" />
</a-form-item>
</a-col>
</a-row>
@ -116,30 +124,43 @@
<a-row :gutter="16">
<a-col :span="8">
<a-form-item label="负责人姓名" name="organizerContact">
<a-input style="width: 100%" v-model:value="form.organizerContact" placeholder="负责人姓名" />
<a-input style="width: 100%" v-model:value="form.organizerContact" placeholder="负责人姓名" :disabled="readonlyMode" />
</a-form-item>
</a-col>
<a-col :span="16">
<a-form-item label="联系方式" name="organizerPhone">
<a-input style="width: 100%" v-model:value="form.organizerPhone" placeholder="联系电话或邮箱" />
<a-input style="width: 100%" v-model:value="form.organizerPhone" placeholder="联系电话或邮箱" :disabled="readonlyMode" />
</a-form-item>
</a-col>
</a-row>
<!-- 详细描述和证明材料 -->
<a-form-item label="服务内容描述" name="serviceContent">
<SmartWangeditor ref="serviceContentRef" v-model="form.serviceContent" :height="200" />
<SmartWangeditor ref="serviceContentRef" v-model="form.serviceContent" :height="200" :readonly="readonlyMode" />
</a-form-item>
<a-form-item label="证明材料" name="proofMaterials">
<a-form-item name="proofMaterials" required>
<template #label>
<span class="ant-form-item-required">证明材料</span>
<span style="font-size: 12px; color: #999;">请上传活动方案活动记录照片新闻报道等材料支持图片(JPG/PNG)文档(PDF/Word/PPT)格式单文件最大10MB最多上传5个文件</span>
</template>
<template v-if="readonlyMode">
<div v-if="defaultFileList.length > 0">
<a-typography-paragraph v-for="file in defaultFileList" :key="file.uid" style="margin: 4px 0;">
<Link :href="file.url || file.fileUrl" target="_blank">{{ file.name || file.fileName }}</Link>
</a-typography-paragraph>
</div>
<div v-else>无证明材料</div>
</template>
<Upload
v-else
:defaultFileList="defaultFileList"
:maxUploadSize="10"
: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"
buttonText="上传证明材料"
listType="text"
extraMsg="支持图片(JPG/PNG)、文档(PDF/Word/PPT)格式,单文件最大10MB,最多上传10个文件"
extraMsg="活动方案、活动记录、照片、新闻报道等,支持图片(JPG/PNG)、文档(PDF/Word/PPT)格式,单文件最大10MB,最多上传5个文件"
@change="changeAttachment"
/>
</a-form-item>
@ -149,8 +170,8 @@
<template #footer>
<a-space>
<a-button @click="onClose">取消</a-button>
<a-button type="primary" @click="onSave">保存</a-button>
<a-button type="primary" @click="onSubmit">提交</a-button>
<a-button v-if="!readonlyMode" type="primary" @click="onSave">保存</a-button>
<a-button v-if="!readonlyMode" type="primary" @click="onSubmit">提交</a-button>
</a-space>
</template>
</a-modal>
@ -174,7 +195,7 @@
import CategoryTree from '/@/components/business/category-tree-select/index.vue';
import { CATEGORY_TYPE_ENUM } from '/@/constants/business/erp/category-const';
import { goodsApi } from '/@/api/business/goods/goods-api';
import PositionSelect from '/@/components/system/position-select/index.vue';
// ------------------------ ------------------------
const emits = defineEmits(['reloadList']);
@ -183,6 +204,9 @@
//
const visibleFlag = ref(false);
//
const readonlyMode = ref(false);
//
let currentUserInfo = ref(null);
@ -246,14 +270,17 @@
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
}
async function show(rowData) {
async function show(rowData, isDetail = false) {
Object.assign(form, formDefault);
//
readonlyMode.value = isDetail;
//
const userInfo = await getCurrentUserInfo();
if (rowData && !_.isEmpty(rowData)) {
//
//
Object.assign(form, rowData);
//
if (userInfo) {
@ -264,7 +291,7 @@
form.departmentName = userInfo.departmentName || form.departmentName;
}
// attachmentIds
// attachmentIds
if (form.attachmentIds && form.attachmentIds.trim()) {
await getFileListByAttachmentIds(form.attachmentIds);
}
@ -362,6 +389,13 @@
}).filter(id => id); //
form.attachmentIds = fileIds.join(',');
//
nextTick(() => {
if (formRef.value) {
formRef.value.validateFields(['proofMaterials']);
}
});
}
function onClose() {
@ -370,6 +404,8 @@
defaultFileList.value = [];
form.proofMaterials = [];
form.attachmentIds = '';
//
readonlyMode.value = false;
visibleFlag.value = false;
}
@ -450,6 +486,17 @@
}
],
serviceContent: [{ required: true, message: '服务内容描述 必填' }],
proofMaterials: [
{
validator: async (rule, value) => {
//
if (!form.proofMaterials || form.proofMaterials.length === 0) {
return Promise.reject('请上传证明材料');
}
return Promise.resolve();
}
}
],
};
//

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

@ -36,8 +36,8 @@
<a-form-item label="组织单位名称" class="smart-query-form-item">
<a-input style="width: 150px" v-model:value="queryForm.organizerName" placeholder="组织单位名称" />
</a-form-item>
<a-form-item label="负责人姓名" class="smart-query-form-item">
<a-input style="width: 150px" v-model:value="queryForm.managerName" placeholder="负责人姓名" />
<a-form-item label="服务对象负责人姓名" class="smart-query-form-item">
<a-input style="width: 150px" v-model:value="queryForm.managerName" placeholder="服务对象负责人姓名" />
</a-form-item>
<a-form-item class="smart-query-form-item smart-margin-left10">
<a-button v-privilege="'serviceApplications:query'" type="primary" @click="onSearch">
@ -79,12 +79,12 @@
</template>
批量删除
</a-button>
<a-button @click="showImportModal" type="primary">
<!--<a-button @click="showImportModal" type="primary">
<template #icon>
<ImportOutlined />
</template>
导入
</a-button>
</a-button>-->
</div>
<div class="smart-table-setting-block">
@ -110,10 +110,11 @@
<template v-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button @click="showDetail(record)" type="link">详情</a-button>
<a-button v-if="(record.firmAuditStatus === 0 || record.firmAuditStatus === 4) && record.userId === loginInfo?.userId" @click="showForm(record)" type="link">编辑</a-button>
<a-button v-if="(record.firmAuditStatus === 0 && record.userId === loginInfo?.userId)" @click="onSubmit(record)" type="link">提交</a-button>
<a-button v-if="(record.firmAuditStatus === 1 || record.firmAuditStatus === 2) && loginInfo?.dataScopeView === 1" @click="showAuditModal(record)" type="link">审核</a-button>
<a-button v-if="record.userId === loginInfo?.userId" @click="onDelete(record)" danger type="link">删除</a-button>
<a-button v-if="record.firmAuditStatus === 0 && record.userId === loginInfo?.userId" @click="onDelete(record)" danger type="link">删除</a-button>
</div>
</template>
</template>
@ -222,6 +223,11 @@
dataIndex: 'userName',
ellipsis: true,
},
{
title: '职务名称',
dataIndex: 'positionName',
ellipsis: true,
},
{
title: '服务开始时间',
dataIndex: 'serviceStart',
@ -248,7 +254,7 @@
ellipsis: true,
},
{
title: '负责人姓名',
title: '服务对象负责人姓名',
dataIndex: 'organizerContact',
ellipsis: true,
},
@ -387,6 +393,22 @@
function showForm(data) {
formRef.value.show(data);
}
// ---------------------------- ----------------------------
async function showDetail(record) {
try {
SmartLoading.show();
const detailResult = await serviceApplicationsApi.queryDetail(record.applicationId);
if (detailResult.data) {
formRef.value.show(detailResult.data, true);
}
} catch (error) {
smartSentry.captureError(error);
message.error('获取详情失败');
} finally {
SmartLoading.hide();
}
}
// ---------------------------- ----------------------------
//
@ -505,6 +527,11 @@ function handleAuditCancel() {
//
function confirmBatchDelete() {
if (selectedRowKeyList.value.length === 0) {
message.warning('请先选择要删除的数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要批量删除这些数据吗?',

26
src/views/system/home/components/agreement-modal.vue

@ -8,7 +8,7 @@
:closable="false"
>
<a-spin :spinning="loading">
<div class="agreement-content">
<div class="agreement-content" @scroll="handleScroll">
<div v-if="noticeDetail.title" class="agreement-text">
<div class="content-header">
<h3>{{ noticeDetail.title }}</h3>
@ -60,7 +60,15 @@
<template #footer>
<a-button @click="handleCancel" size="large">不同意</a-button>
<a-button type="primary" @click="handleConfirm" size="large">同意并继续</a-button>
<a-button
type="primary"
@click="handleConfirm"
size="large"
:disabled="!hasScrolledToBottom"
>
同意并继续
<span v-if="!hasScrolledToBottom">(请阅读完全文后点击)</span>
</a-button>
</template>
</a-modal>
</template>
@ -74,6 +82,9 @@ const emit = defineEmits(['confirm', 'cancel']);
const visible = ref(false);
const loading = ref(false);
//
const hasScrolledToBottom = ref(false);
//
const noticeDetail = reactive({
title: '',
@ -89,6 +100,15 @@ onMounted(() => {
getFirstNoticeDetail();
});
//
function handleScroll(event) {
const element = event.target;
//
if (element.scrollTop + element.clientHeight >= element.scrollHeight - 1) {
hasScrolledToBottom.value = true;
}
}
//
async function getFirstNoticeDetail() {
try {
@ -150,7 +170,7 @@ const handleCancel = () => {
.content-header h3 {
text-align: center;
color: #1890ff;
color: #1e3a8a;
margin-bottom: 10px;
font-size: 18px;
}

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

@ -7,7 +7,7 @@
<div class="box-item desc">
<div class="welcome">
<p>欢迎登录</p>
<p class="sub-welcome"> </p>
<p class="sub-welcome">合肥市律师公益法律服务管理系</p>
</div>
<img class="welcome-img" :src="loginGif" />
</div>

6
src/views/system/position/position-form.vue

@ -14,8 +14,8 @@
>
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }">
<a-form-item label="职级" name="positionLevel">
<a-input style="width: 100%" v-model:value="form.positionLevel" placeholder="职级" />
<a-form-item label="职务名称" name="positionName">
<a-input style="width: 100%" v-model:value="form.positionName" placeholder="职级" />
</a-form-item>
<a-form-item label="排序" name="sort">
<a-input-number :min="0" :step="1" :precision="0" style="width: 100%" v-model:value="form.sort" placeholder="排序" />
@ -87,7 +87,7 @@
const formDefault = {
positionId: undefined,
positionName: undefined, //
positionLevel: undefined, //
// positionLevel: undefined, //
sort: 0,
remark: undefined, //
};

5
src/views/system/position/position-list.vue

@ -112,11 +112,6 @@
dataIndex: 'positionName',
ellipsis: true,
},
{
title: '职级',
dataIndex: 'positionLevel',
ellipsis: true,
},
{
title: '排序',
dataIndex: 'sort',

8
vite.config.js

@ -35,14 +35,14 @@ export default {
proxy: {
// 代理API路径
'/api': {
target: 'http://8.148.67.92:8080/', // 目标服务器地址
//target: 'http://127.0.0.1:8080/',
//target: 'http://8.148.67.92:8080/', // 目标服务器地址
target: 'http://127.0.0.1:8080/',
changeOrigin: true, // 是否修改请求头中的 Origin 字段
rewrite: (path) => path.replace(/^\/api/, ''), // 重写路径
},
'/login': {
target: 'http://8.148.67.92:8080/', // 目标服务器地址
//target: 'http://127.0.0.1:8080/',
//target: 'http://8.148.67.92:8080/', // 目标服务器地址
target: 'http://127.0.0.1:8080/',
changeOrigin: true, // 是否修改请求头中的 Origin 字段
rewrite: (path) => path.replace(/^\/api/, ''), // 重写路径
},

Loading…
Cancel
Save