选课调整
This commit is contained in:
parent
1598d8e886
commit
e37bd3e02e
@ -15,6 +15,10 @@ export const xqxjFindAllApi = async () => {
|
|||||||
export const findAllNjBjTreeApi = async () => {
|
export const findAllNjBjTreeApi = async () => {
|
||||||
return await get("/api/nj/findAllNjBjTree");
|
return await get("/api/nj/findAllNjBjTree");
|
||||||
};
|
};
|
||||||
|
export const findAllNjBjKzTreeApi = async () => {
|
||||||
|
return await get("/api/nj/findAllNjBjKzTree");
|
||||||
|
};
|
||||||
|
|
||||||
export const kmFindAllApi = async () => {
|
export const kmFindAllApi = async () => {
|
||||||
return await get("/api/km/findAll");
|
return await get("/api/km/findAll");
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
<FormBasicDateTimes v-bind="attrs" v-if="isShow('BasicDateTimes')" v-model="newValue"/>
|
<FormBasicDateTimes v-bind="attrs" v-if="isShow('BasicDateTimes')" v-model="newValue"/>
|
||||||
<FormBasicTree v-bind="attrs" v-if="isShow('BasicTree')" v-model="newValue"/>
|
<FormBasicTree v-bind="attrs" v-if="isShow('BasicTree')" v-model="newValue"/>
|
||||||
<FormBasicNjBjPicker v-bind="attrs" v-if="isShow('BasicNjBjPicker')" v-model="newValue"/>
|
<FormBasicNjBjPicker v-bind="attrs" v-if="isShow('BasicNjBjPicker')" v-model="newValue"/>
|
||||||
|
<FormBasicNjBjSelect v-bind="attrs" v-if="isShow('BasicNjBjSelect')" v-model="newValue"/>
|
||||||
<FormBasicXsPicker v-bind="attrs" v-if="isShow('BasicXsPicker')" v-model="newValue"/>
|
<FormBasicXsPicker v-bind="attrs" v-if="isShow('BasicXsPicker')" v-model="newValue"/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -24,6 +25,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {useAttrs} from "vue";
|
import {useAttrs} from "vue";
|
||||||
import FormBasicNjBjPicker from "@/components/BasicNjBjPicker/index.vue";
|
import FormBasicNjBjPicker from "@/components/BasicNjBjPicker/index.vue";
|
||||||
|
import FormBasicNjBjSelect from "@/components/BasicNjBjSelect/index.vue";
|
||||||
import FormBasicXsPicker from "@/components/BasicXsPicker/index.vue";
|
import FormBasicXsPicker from "@/components/BasicXsPicker/index.vue";
|
||||||
|
|
||||||
const attrs = useAttrs()
|
const attrs = useAttrs()
|
||||||
|
|||||||
1
src/components/BasicForm/type/useForm.d.ts
vendored
1
src/components/BasicForm/type/useForm.d.ts
vendored
@ -29,6 +29,7 @@ type Component =
|
|||||||
| 'BasicDateTimes'
|
| 'BasicDateTimes'
|
||||||
| 'BasicTree'
|
| 'BasicTree'
|
||||||
| 'BasicNjBjPicker'
|
| 'BasicNjBjPicker'
|
||||||
|
| 'BasicNjBjSelect'
|
||||||
| 'BasicXsPicker'
|
| 'BasicXsPicker'
|
||||||
|
|
||||||
interface FormsSchema {
|
interface FormsSchema {
|
||||||
|
|||||||
264
src/components/BasicNjBjSelect/README.md
Normal file
264
src/components/BasicNjBjSelect/README.md
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
# BasicNjBjSelect 年级班级选择组件
|
||||||
|
|
||||||
|
一个通用的年级班级树形选择组件,支持多选模式,提供友好的用户界面。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- 🌳 **树形结构**:支持年级和班级的层级结构选择
|
||||||
|
- ✅ **多选模式**:支持选择多个年级和班级
|
||||||
|
- 🔄 **双向绑定**:支持 v-model 双向数据绑定
|
||||||
|
- 🎨 **自定义样式**:支持自定义触发按钮样式
|
||||||
|
- 🚫 **权限控制**:支持选择是否使用权限控制接口
|
||||||
|
- 📱 **响应式设计**:适配移动端界面
|
||||||
|
- ⚡ **异步加载**:支持异步加载年级班级数据
|
||||||
|
- 🔍 **展开折叠**:支持年级节点的展开和折叠
|
||||||
|
|
||||||
|
## 基本用法
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<view class="demo">
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedClass"
|
||||||
|
placeholder="请选择年级班级"
|
||||||
|
@change="onClassChange"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import BasicNjBjSelect from '@/components/BasicNjBjSelect/index.vue'
|
||||||
|
|
||||||
|
const selectedClass = ref(null)
|
||||||
|
|
||||||
|
const onClassChange = (result) => {
|
||||||
|
console.log('选择的班级:', result)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Props
|
||||||
|
|
||||||
|
| 参数 | 类型 | 默认值 | 说明 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| modelValue | TreeSelectResult \| null | null | 双向绑定的值 |
|
||||||
|
| defaultValue | TreeSelectResult \| null | null | 默认值 |
|
||||||
|
| customStyle | any | {} | 自定义样式 |
|
||||||
|
| iconArrow | string | 'bottom' | 箭头图标类型 |
|
||||||
|
| iconColor | string | '#666' | 箭头颜色 |
|
||||||
|
| placeholder | string | '选择年级班级' | 占位符文本 |
|
||||||
|
| disabled | boolean | false | 是否禁用 |
|
||||||
|
| title | string | '选择班级' | 弹窗标题 |
|
||||||
|
| useKzTree | boolean | false | 是否使用不受权限控制的接口(true: 调用 findAllNjBjKzTreeApi,false: 调用 findAllNjBjTreeApi) |
|
||||||
|
| multiple | boolean | false | 是否支持多选(true: 多选模式,false: 单选模式) |
|
||||||
|
|
||||||
|
## Events
|
||||||
|
|
||||||
|
| 事件名 | 参数 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| change | (result: TreeSelectResult \| null) | 选择变化时触发 |
|
||||||
|
| update:modelValue | (result: TreeSelectResult \| null) | v-model 更新时触发 |
|
||||||
|
|
||||||
|
## TreeSelectResult 数据结构
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface TreeSelectResult {
|
||||||
|
selectedGrades: NjItem[] // 选中的年级列表
|
||||||
|
selectedClasses: BjItem[] // 选中的班级列表
|
||||||
|
allSelected: (NjItem | BjItem)[] // 所有选中的项目
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NjItem {
|
||||||
|
key: string // 年级ID
|
||||||
|
title: string // 年级名称
|
||||||
|
njmcId: string // 年级名称ID
|
||||||
|
children: BjItem[] // 班级列表
|
||||||
|
expanded?: boolean // 是否展开
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BjItem {
|
||||||
|
key: string // 班级ID
|
||||||
|
title: string // 班级名称
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 权限配置
|
||||||
|
|
||||||
|
组件支持两种权限模式:
|
||||||
|
|
||||||
|
### 权限控制模式(默认)
|
||||||
|
- `useKzTree: false`(默认值)
|
||||||
|
- 调用 `findAllNjBjTreeApi` 接口
|
||||||
|
- 根据用户权限返回可访问的年级班级数据
|
||||||
|
- 适用于需要权限控制的场景
|
||||||
|
|
||||||
|
### 无权限控制模式
|
||||||
|
- `useKzTree: true`
|
||||||
|
- 调用 `findAllNjBjKzTreeApi` 接口
|
||||||
|
- 返回所有年级班级数据,不受权限限制
|
||||||
|
- 适用于管理员或需要查看全部数据的场景
|
||||||
|
|
||||||
|
## 选择模式
|
||||||
|
|
||||||
|
组件支持两种选择模式:
|
||||||
|
|
||||||
|
### 单选模式(默认)
|
||||||
|
- `multiple: false`(默认值)
|
||||||
|
- 使用 radio 按钮进行选择
|
||||||
|
- 只能选择一个年级或一个班级
|
||||||
|
- 选择班级时会自动选择对应的年级
|
||||||
|
- 适用于需要精确选择单个班级的场景
|
||||||
|
|
||||||
|
### 多选模式
|
||||||
|
- `multiple: true`
|
||||||
|
- 使用 checkbox 按钮进行选择
|
||||||
|
- 可以选择多个年级和多个班级
|
||||||
|
- 年级和班级可以独立选择
|
||||||
|
- 适用于需要批量选择的场景
|
||||||
|
|
||||||
|
## 方法
|
||||||
|
|
||||||
|
通过 ref 可以调用以下方法:
|
||||||
|
|
||||||
|
| 方法名 | 参数 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| reset | - | 重置选择 |
|
||||||
|
| setValue | (grades: NjItem[], classes: BjItem[]) | 设置值 |
|
||||||
|
| loadData | - | 重新加载数据 |
|
||||||
|
| openSelector | - | 打开选择器 |
|
||||||
|
| closeSelector | - | 关闭选择器 |
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 单选模式(默认)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:multiple="false"
|
||||||
|
:use-kz-tree="false"
|
||||||
|
placeholder="请选择年级班级"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import BasicNjBjSelect from '@/components/BasicNjBjSelect/index.vue'
|
||||||
|
|
||||||
|
const selectedData = ref(null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 多选模式
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:multiple="true"
|
||||||
|
:use-kz-tree="false"
|
||||||
|
placeholder="请选择年级班级"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import BasicNjBjSelect from '@/components/BasicNjBjSelect/index.vue'
|
||||||
|
|
||||||
|
const selectedData = ref(null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 无权限控制(单选)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:multiple="false"
|
||||||
|
:use-kz-tree="true"
|
||||||
|
title="选择年级班级(全部)"
|
||||||
|
placeholder="选择全部年级班级"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import BasicNjBjSelect from '@/components/BasicNjBjSelect/index.vue'
|
||||||
|
|
||||||
|
const selectedData = ref(null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义样式
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:custom-style="{
|
||||||
|
backgroundColor: '#f0f9ff',
|
||||||
|
borderColor: '#0ea5e9'
|
||||||
|
}"
|
||||||
|
placeholder="请选择年级班级"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用不受权限控制的接口
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:use-kz-tree="true"
|
||||||
|
title="选择年级班级(全部)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 禁用状态
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
:disabled="true"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 监听选择变化
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedData"
|
||||||
|
@change="onSelectionChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const onSelectionChange = (result) => {
|
||||||
|
if (result) {
|
||||||
|
console.log('选中的年级数量:', result.selectedGrades.length)
|
||||||
|
console.log('选中的班级数量:', result.selectedClasses.length)
|
||||||
|
console.log('选中的年级:', result.selectedGrades)
|
||||||
|
console.log('选中的班级:', result.selectedClasses)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 组件会自动加载年级班级数据,无需手动调用
|
||||||
|
2. 如果使用 `useKzTree` 为 true,将调用不受权限控制的接口
|
||||||
|
3. 组件支持 v-model 双向绑定
|
||||||
|
4. 选择结果包含完整的年级班级信息,便于后续处理
|
||||||
|
5. 年级节点支持展开/折叠,点击年级名称可以切换展开状态
|
||||||
|
6. 选择年级时,会自动选择该年级下的所有班级
|
||||||
|
7. 取消选择年级时,会同时取消选择该年级下的所有班级
|
||||||
|
8. 班级可以独立选择,不受年级选择状态影响
|
||||||
149
src/components/BasicNjBjSelect/demo.vue
Normal file
149
src/components/BasicNjBjSelect/demo.vue
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<template>
|
||||||
|
<view class="demo-page">
|
||||||
|
<view class="demo-section">
|
||||||
|
<text class="section-title">基础用法</text>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedClass1"
|
||||||
|
placeholder="请选择年级班级"
|
||||||
|
@change="onClassChange1"
|
||||||
|
/>
|
||||||
|
<view v-if="selectedClass1" class="result-display">
|
||||||
|
<text>已选择:{{ selectedClass1.njmc }} {{ selectedClass1.bjmc }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="demo-section">
|
||||||
|
<text class="section-title">自定义样式</text>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedClass2"
|
||||||
|
:custom-style="{
|
||||||
|
backgroundColor: '#f0f9ff',
|
||||||
|
borderColor: '#0ea5e9',
|
||||||
|
borderRadius: '12px'
|
||||||
|
}"
|
||||||
|
placeholder="自定义样式选择器"
|
||||||
|
icon-color="#0ea5e9"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="demo-section">
|
||||||
|
<text class="section-title">不受权限控制</text>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedClass3"
|
||||||
|
:use-kz-tree="true"
|
||||||
|
title="选择年级班级(全部)"
|
||||||
|
placeholder="选择全部年级班级"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="demo-section">
|
||||||
|
<text class="section-title">禁用状态</text>
|
||||||
|
<BasicNjBjSelect
|
||||||
|
v-model="selectedClass4"
|
||||||
|
:disabled="true"
|
||||||
|
placeholder="禁用状态"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="demo-section">
|
||||||
|
<text class="section-title">操作按钮</text>
|
||||||
|
<view class="button-group">
|
||||||
|
<button @click="resetAll" class="demo-btn">重置所有</button>
|
||||||
|
<button @click="setDefaultValue" class="demo-btn">设置默认值</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import BasicNjBjSelect from './index.vue'
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const selectedClass1 = ref(null)
|
||||||
|
const selectedClass2 = ref(null)
|
||||||
|
const selectedClass3 = ref(null)
|
||||||
|
const selectedClass4 = ref(null)
|
||||||
|
|
||||||
|
// 事件处理
|
||||||
|
const onClassChange1 = (result) => {
|
||||||
|
console.log('选择变化:', result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置所有选择
|
||||||
|
const resetAll = () => {
|
||||||
|
selectedClass1.value = null
|
||||||
|
selectedClass2.value = null
|
||||||
|
selectedClass3.value = null
|
||||||
|
selectedClass4.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
const setDefaultValue = () => {
|
||||||
|
// 这里可以设置一个默认的年级班级
|
||||||
|
// 注意:需要确保数据存在
|
||||||
|
console.log('设置默认值功能需要根据实际数据调整')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.demo-page {
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo-section {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-display {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid #0ea5e9;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #0369a1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 15px;
|
||||||
|
|
||||||
|
.demo-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #1677ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
639
src/components/BasicNjBjSelect/index.vue
Normal file
639
src/components/BasicNjBjSelect/index.vue
Normal file
@ -0,0 +1,639 @@
|
|||||||
|
<template>
|
||||||
|
<view class="basic-nj-bj-select">
|
||||||
|
<!-- 选择器触发按钮 -->
|
||||||
|
<view
|
||||||
|
class="select-trigger"
|
||||||
|
:class="{ disabled: disabled }"
|
||||||
|
:style="customStyle"
|
||||||
|
@click="openSelector"
|
||||||
|
>
|
||||||
|
<text class="select-text">{{ displayText || placeholder }}</text>
|
||||||
|
<uni-icons :type="iconArrow" size="14" :color="iconColor"></uni-icons>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 选择器弹窗 -->
|
||||||
|
<uni-popup ref="popup" type="bottom" :safe-area="false">
|
||||||
|
<view class="selector-popup">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<view class="popup-header">
|
||||||
|
<text class="popup-title">{{ title }}</text>
|
||||||
|
<view class="popup-actions">
|
||||||
|
<text class="action-btn cancel-btn" @click="closeSelector">取消</text>
|
||||||
|
<text class="action-btn confirm-btn" @click="confirmSelection">确定</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 树形选择器内容 -->
|
||||||
|
<view class="popup-content">
|
||||||
|
<scroll-view scroll-y class="tree-scroll">
|
||||||
|
<checkbox-group v-if="multiple" @change="onGradeCheckboxChange">
|
||||||
|
<view class="tree-container">
|
||||||
|
<view
|
||||||
|
v-for="(nj, njIndex) in njList"
|
||||||
|
:key="nj.key"
|
||||||
|
class="tree-node"
|
||||||
|
>
|
||||||
|
<!-- 年级节点 -->
|
||||||
|
<view
|
||||||
|
class="tree-item grade-item"
|
||||||
|
:class="{ expanded: nj.expanded }"
|
||||||
|
@click="toggleGrade(njIndex)"
|
||||||
|
>
|
||||||
|
<view class="tree-item-content">
|
||||||
|
<view class="expand-icon">
|
||||||
|
<uni-icons
|
||||||
|
:type="nj.expanded ? 'arrowdown' : 'arrowright'"
|
||||||
|
size="12"
|
||||||
|
color="#666"
|
||||||
|
></uni-icons>
|
||||||
|
</view>
|
||||||
|
<text class="grade-text">{{ nj.title }}</text>
|
||||||
|
<checkbox
|
||||||
|
v-if="multiple"
|
||||||
|
:value="nj.key"
|
||||||
|
:checked="isGradeSelected(nj)"
|
||||||
|
class="grade-checkbox"
|
||||||
|
/>
|
||||||
|
<radio
|
||||||
|
v-else
|
||||||
|
:value="nj.key"
|
||||||
|
:checked="isGradeSelected(nj)"
|
||||||
|
class="grade-radio"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 班级节点 -->
|
||||||
|
<view
|
||||||
|
v-if="nj.expanded"
|
||||||
|
class="class-children"
|
||||||
|
>
|
||||||
|
<checkbox-group v-if="multiple" @change="(event: any) => onClassCheckboxChange(nj, event)">
|
||||||
|
<view
|
||||||
|
v-for="(bj, bjIndex) in nj.children"
|
||||||
|
:key="bj.key"
|
||||||
|
class="tree-item class-item"
|
||||||
|
>
|
||||||
|
<view class="tree-item-content">
|
||||||
|
<view class="class-indent"></view>
|
||||||
|
<text class="class-text">{{ bj.title }}</text>
|
||||||
|
<checkbox
|
||||||
|
:value="bj.key"
|
||||||
|
:checked="isClassSelected(bj)"
|
||||||
|
class="class-checkbox"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</checkbox-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</checkbox-group>
|
||||||
|
|
||||||
|
<radio-group v-else @change="onGradeRadioChange">
|
||||||
|
<view class="tree-container">
|
||||||
|
<view
|
||||||
|
v-for="(nj, njIndex) in njList"
|
||||||
|
:key="nj.key"
|
||||||
|
class="tree-node"
|
||||||
|
>
|
||||||
|
<!-- 年级节点 -->
|
||||||
|
<view
|
||||||
|
class="tree-item grade-item"
|
||||||
|
:class="{ expanded: nj.expanded }"
|
||||||
|
@click="toggleGrade(njIndex)"
|
||||||
|
>
|
||||||
|
<view class="tree-item-content">
|
||||||
|
<view class="expand-icon">
|
||||||
|
<uni-icons
|
||||||
|
:type="nj.expanded ? 'arrowdown' : 'arrowright'"
|
||||||
|
size="12"
|
||||||
|
color="#666"
|
||||||
|
></uni-icons>
|
||||||
|
</view>
|
||||||
|
<text class="grade-text">{{ nj.title }}</text>
|
||||||
|
<radio
|
||||||
|
:value="nj.key"
|
||||||
|
:checked="isGradeSelected(nj)"
|
||||||
|
class="grade-radio"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 班级节点 -->
|
||||||
|
<view
|
||||||
|
v-if="nj.expanded"
|
||||||
|
class="class-children"
|
||||||
|
>
|
||||||
|
<radio-group @change="onClassRadioChange">
|
||||||
|
<view
|
||||||
|
v-for="(bj, bjIndex) in nj.children"
|
||||||
|
:key="bj.key"
|
||||||
|
class="tree-item class-item"
|
||||||
|
>
|
||||||
|
<view class="tree-item-content">
|
||||||
|
<view class="class-indent"></view>
|
||||||
|
<text class="class-text">{{ bj.title }}</text>
|
||||||
|
<radio
|
||||||
|
:value="bj.key"
|
||||||
|
:checked="isClassSelected(bj)"
|
||||||
|
class="class-radio"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</radio-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</radio-group>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue'
|
||||||
|
import { findAllNjBjTreeApi, findAllNjBjKzTreeApi } from '@/api/base/server'
|
||||||
|
|
||||||
|
// 接口定义
|
||||||
|
interface NjItem {
|
||||||
|
key: string
|
||||||
|
title: string
|
||||||
|
njmcId: string
|
||||||
|
children: BjItem[]
|
||||||
|
expanded?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BjItem {
|
||||||
|
key: string
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SelectResult {
|
||||||
|
nj: NjItem
|
||||||
|
bj: BjItem
|
||||||
|
njId: string
|
||||||
|
bjId: string
|
||||||
|
njmc: string
|
||||||
|
bjmc: string
|
||||||
|
njmcId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TreeSelectResult {
|
||||||
|
selectedGrades: NjItem[]
|
||||||
|
selectedClasses: BjItem[]
|
||||||
|
allSelected: (NjItem | BjItem)[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Props 定义
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
modelValue?: TreeSelectResult | null
|
||||||
|
defaultValue?: TreeSelectResult | null
|
||||||
|
customStyle?: any
|
||||||
|
iconArrow?: string
|
||||||
|
iconColor?: string
|
||||||
|
placeholder?: string
|
||||||
|
disabled?: boolean
|
||||||
|
title?: string
|
||||||
|
useKzTree?: boolean // 是否使用不受权限控制的接口
|
||||||
|
multiple?: boolean // 是否支持多选
|
||||||
|
}>(), {
|
||||||
|
modelValue: null,
|
||||||
|
defaultValue: null,
|
||||||
|
customStyle: {},
|
||||||
|
iconArrow: 'bottom',
|
||||||
|
iconColor: '#666',
|
||||||
|
placeholder: '选择年级班级',
|
||||||
|
disabled: false,
|
||||||
|
title: '选择班级',
|
||||||
|
useKzTree: false,
|
||||||
|
multiple: false
|
||||||
|
})
|
||||||
|
|
||||||
|
// Emits 定义
|
||||||
|
const emit = defineEmits(['change', 'update:modelValue'])
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const popup = ref()
|
||||||
|
const njList = ref<NjItem[]>([])
|
||||||
|
const selectedGrades = ref<NjItem[]>([])
|
||||||
|
const selectedClasses = ref<BjItem[]>([])
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const displayText = computed(() => {
|
||||||
|
if (!props.modelValue) return ''
|
||||||
|
|
||||||
|
const gradeCount = props.modelValue.selectedGrades?.length || 0
|
||||||
|
const classCount = props.modelValue.selectedClasses?.length || 0
|
||||||
|
|
||||||
|
if (props.multiple) {
|
||||||
|
// 多选模式:显示选择数量
|
||||||
|
if (gradeCount > 0 && classCount > 0) {
|
||||||
|
return `已选择 ${gradeCount} 个年级,${classCount} 个班级`
|
||||||
|
} else if (classCount > 0) {
|
||||||
|
return `已选择 ${classCount} 个班级`
|
||||||
|
} else if (gradeCount > 0) {
|
||||||
|
return `已选择 ${gradeCount} 个年级`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 单选模式:显示具体选择的年级班级
|
||||||
|
if (classCount > 0) {
|
||||||
|
const selectedClass = props.modelValue.selectedClasses[0]
|
||||||
|
const selectedGrade = props.modelValue.selectedGrades[0]
|
||||||
|
return `${selectedGrade?.title || ''} ${selectedClass.title}`
|
||||||
|
} else if (gradeCount > 0) {
|
||||||
|
return props.modelValue.selectedGrades[0].title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听 modelValue 变化
|
||||||
|
watch(() => props.modelValue, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
selectedGrades.value = newVal.selectedGrades || []
|
||||||
|
selectedClasses.value = newVal.selectedClasses || []
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 切换年级展开/折叠
|
||||||
|
const toggleGrade = (njIndex: number) => {
|
||||||
|
if (props.disabled) return
|
||||||
|
njList.value[njIndex].expanded = !njList.value[njIndex].expanded
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查年级是否被选中
|
||||||
|
const isGradeSelected = (nj: NjItem) => {
|
||||||
|
return selectedGrades.value.some(grade => grade.key === nj.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查班级是否被选中
|
||||||
|
const isClassSelected = (bj: BjItem) => {
|
||||||
|
return selectedClasses.value.some(cls => cls.key === bj.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 年级选择变化(多选模式)
|
||||||
|
const onGradeCheckboxChange = (event: any) => {
|
||||||
|
if (props.disabled) return
|
||||||
|
|
||||||
|
const selectedValues = event.detail.value || []
|
||||||
|
|
||||||
|
// 更新选中的年级
|
||||||
|
selectedGrades.value = njList.value.filter(nj =>
|
||||||
|
selectedValues.includes(nj.key)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 更新选中的班级(只保留选中年级下的班级)
|
||||||
|
selectedClasses.value = selectedClasses.value.filter(cls =>
|
||||||
|
selectedGrades.value.some(grade =>
|
||||||
|
grade.children.some(child => child.key === cls.key)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
updateModelValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 年级单选变化
|
||||||
|
const onGradeRadioChange = (event: any) => {
|
||||||
|
if (props.disabled) return
|
||||||
|
|
||||||
|
const selectedValue = event.detail.value
|
||||||
|
const selectedGrade = njList.value.find(nj => nj.key === selectedValue)
|
||||||
|
|
||||||
|
if (selectedGrade) {
|
||||||
|
selectedGrades.value = [selectedGrade]
|
||||||
|
selectedClasses.value = []
|
||||||
|
} else {
|
||||||
|
selectedGrades.value = []
|
||||||
|
selectedClasses.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
updateModelValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 班级选择变化(多选模式)
|
||||||
|
const onClassCheckboxChange = (nj: NjItem, event: any) => {
|
||||||
|
if (props.disabled) return
|
||||||
|
|
||||||
|
const selectedValues = event.detail.value || []
|
||||||
|
|
||||||
|
// 更新该年级下的班级选择
|
||||||
|
const currentClassKeys = nj.children.map(bj => bj.key)
|
||||||
|
const selectedClassKeys = selectedValues.filter((key: string) => currentClassKeys.includes(key))
|
||||||
|
|
||||||
|
// 移除该年级下之前选中的班级
|
||||||
|
selectedClasses.value = selectedClasses.value.filter(cls =>
|
||||||
|
!currentClassKeys.includes(cls.key)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 添加新选中的班级
|
||||||
|
selectedClassKeys.forEach((key: string) => {
|
||||||
|
const bj = nj.children.find(bj => bj.key === key)
|
||||||
|
if (bj) {
|
||||||
|
selectedClasses.value.push(bj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateModelValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 班级单选变化
|
||||||
|
const onClassRadioChange = (event: any) => {
|
||||||
|
if (props.disabled) return
|
||||||
|
|
||||||
|
const selectedValue = event.detail.value
|
||||||
|
|
||||||
|
// 查找选中的班级及其所属年级
|
||||||
|
for (const nj of njList.value) {
|
||||||
|
const selectedClass = nj.children.find(bj => bj.key === selectedValue)
|
||||||
|
if (selectedClass) {
|
||||||
|
selectedClasses.value = [selectedClass]
|
||||||
|
selectedGrades.value = [nj]
|
||||||
|
updateModelValue()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到,清空选择
|
||||||
|
selectedClasses.value = []
|
||||||
|
selectedGrades.value = []
|
||||||
|
updateModelValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新模型值
|
||||||
|
const updateModelValue = () => {
|
||||||
|
const result: TreeSelectResult = {
|
||||||
|
selectedGrades: [...selectedGrades.value],
|
||||||
|
selectedClasses: [...selectedClasses.value],
|
||||||
|
allSelected: [...selectedGrades.value, ...selectedClasses.value]
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('BasicNjBjSelect updateModelValue:', result)
|
||||||
|
emit('change', result)
|
||||||
|
emit('update:modelValue', result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开选择器
|
||||||
|
const openSelector = () => {
|
||||||
|
if (props.disabled) return
|
||||||
|
popup.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭选择器
|
||||||
|
const closeSelector = () => {
|
||||||
|
popup.value?.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认选择
|
||||||
|
const confirmSelection = () => {
|
||||||
|
updateModelValue()
|
||||||
|
closeSelector()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据
|
||||||
|
const loadData = async () => {
|
||||||
|
if (isLoading.value) return
|
||||||
|
|
||||||
|
isLoading.value = true
|
||||||
|
try {
|
||||||
|
const api = props.useKzTree ? findAllNjBjKzTreeApi : findAllNjBjTreeApi
|
||||||
|
const res = await api()
|
||||||
|
const data = res.result || []
|
||||||
|
|
||||||
|
// 为每个年级添加展开状态
|
||||||
|
njList.value = data.map((nj: NjItem) => ({
|
||||||
|
...nj,
|
||||||
|
expanded: false
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 如果有默认值,设置默认选择
|
||||||
|
if (props.defaultValue) {
|
||||||
|
selectedGrades.value = props.defaultValue.selectedGrades || []
|
||||||
|
selectedClasses.value = props.defaultValue.selectedClasses || []
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载年级班级数据失败:', error)
|
||||||
|
uni.showToast({
|
||||||
|
title: '加载数据失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
selectedGrades.value = []
|
||||||
|
selectedClasses.value = []
|
||||||
|
emit('change', null)
|
||||||
|
emit('update:modelValue', null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置值
|
||||||
|
const setValue = (grades: NjItem[], classes: BjItem[]) => {
|
||||||
|
selectedGrades.value = [...grades]
|
||||||
|
selectedClasses.value = [...classes]
|
||||||
|
updateModelValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
reset,
|
||||||
|
setValue,
|
||||||
|
loadData,
|
||||||
|
openSelector,
|
||||||
|
closeSelector
|
||||||
|
})
|
||||||
|
|
||||||
|
// 组件挂载时加载数据
|
||||||
|
onMounted(() => {
|
||||||
|
loadData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.basic-nj-bj-select {
|
||||||
|
.select-trigger {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 15px;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
min-height: 44px;
|
||||||
|
|
||||||
|
&:active:not(.disabled) {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-text {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.selector-popup {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16px 16px 0 0;
|
||||||
|
max-height: 60vh;
|
||||||
|
|
||||||
|
.popup-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
|
.popup-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
|
||||||
|
&.cancel-btn {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.confirm-btn {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-content {
|
||||||
|
.tree-scroll {
|
||||||
|
height: 600px;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.tree-container {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.tree-node {
|
||||||
|
.tree-item {
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.grade-item {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
|
||||||
|
.tree-item-content {
|
||||||
|
padding: 5px 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 30px;
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grade-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grade-checkbox {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.class-item {
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.tree-item-content {
|
||||||
|
padding: 3px 12px 3px 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 26px;
|
||||||
|
|
||||||
|
.class-indent {
|
||||||
|
width: 10px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-checkbox {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-children {
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.tree-item {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-bottom: 1px solid #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-item-content {
|
||||||
|
padding: 2px 12px 2px 26px;
|
||||||
|
min-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -105,7 +105,7 @@ import {onShow} from "@dcloudio/uni-app";
|
|||||||
import {deptFindByPidApi, dicApi} from "@/api/system/dic";
|
import {deptFindByPidApi, dicApi} from "@/api/system/dic";
|
||||||
import {useForm} from "@/components/BasicForm/hooks/useForm";
|
import {useForm} from "@/components/BasicForm/hooks/useForm";
|
||||||
import {getUserViewApi} from "@/api/system/login";
|
import {getUserViewApi} from "@/api/system/login";
|
||||||
import {BasicNjBjPicker} from "@/components/BasicNjBjPicker";
|
import BasicNjBjSelect from "@/components/BasicNjBjSelect/index.vue";
|
||||||
|
|
||||||
function setItemValue() {
|
function setItemValue() {
|
||||||
console.log(444,value.value)
|
console.log(444,value.value)
|
||||||
@ -125,14 +125,18 @@ const [register, {getValue, setSchema, setValue}] = useForm({
|
|||||||
{
|
{
|
||||||
field: "classInfo",
|
field: "classInfo",
|
||||||
label: "年级班级",
|
label: "年级班级",
|
||||||
component: "BasicNjBjPicker",
|
component: "BasicNjBjSelect",
|
||||||
required: true,
|
required: true,
|
||||||
|
defaultValue: null,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: "请选择年级班级",
|
placeholder: "请选择年级班级",
|
||||||
|
useKzTree: true, // 使用权限控制的接口
|
||||||
|
multiple: false, // 单选模式
|
||||||
customStyle: {
|
customStyle: {
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
padding: '12px 15px'
|
padding: '8px 12px',
|
||||||
|
minHeight: '36px'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,14 +171,14 @@ function radioChange() {
|
|||||||
console.log(222, value.value)
|
console.log(222, value.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeRuleItem(e) {
|
function changeRuleItem(e: any) {
|
||||||
value.value = e.detail.value;
|
value.value = e.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getInspectItemData() {
|
async function getInspectItemData() {
|
||||||
let res = await inspectItemFindAllsApi();
|
let res = await inspectItemFindAllsApi();
|
||||||
if (res && res.result && res.result.length > 0) {
|
if (res && res.result && res.result.length > 0) {
|
||||||
inspectItemData.value = res.result.filter(item => authItemIds.value.includes(item.id));
|
inspectItemData.value = res.result.filter((item: any) => authItemIds.value.includes(item.id));
|
||||||
avtion.value = 0;
|
avtion.value = 0;
|
||||||
getFractionRuleData();
|
getFractionRuleData();
|
||||||
} else {
|
} else {
|
||||||
@ -182,7 +186,7 @@ async function getInspectItemData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onavtion(item, index) {
|
function onavtion(item: any, index: number) {
|
||||||
avtion.value = index;
|
avtion.value = index;
|
||||||
console.log(111, fractionRuleData.value)
|
console.log(111, fractionRuleData.value)
|
||||||
getFractionRuleData();
|
getFractionRuleData();
|
||||||
@ -223,7 +227,7 @@ async function onavtionList(item: any, index: any) {
|
|||||||
showpopup.value = true;
|
showpopup.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inspectItemData.value[avtion.value]._rulenum = fractionRuleData.value[avtion.value].filter(item => item.isSelect).length;
|
inspectItemData.value[avtion.value]._rulenum = fractionRuleData.value[avtion.value].filter((item: any) => item.isSelect).length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,16 +258,21 @@ async function submit() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let values = await getValue();
|
let values = await getValue();
|
||||||
|
console.log('assessment.vue getValue:', values);
|
||||||
|
|
||||||
// 处理 classInfo 数据,提取 bjId
|
// 处理 classInfo 数据,提取 bjId
|
||||||
if (values.classInfo && values.classInfo.bjId) {
|
if (values.classInfo && values.classInfo.selectedClasses && values.classInfo.selectedClasses.length > 0) {
|
||||||
|
// 单选模式:取第一个选中的班级
|
||||||
|
const selectedClass = values.classInfo.selectedClasses[0];
|
||||||
|
console.log('selectedClass:', selectedClass);
|
||||||
await evaluationSaveApi({
|
await evaluationSaveApi({
|
||||||
itemList: itemList,
|
itemList: itemList,
|
||||||
bjId: values.classInfo.bjId
|
bjId: selectedClass.key
|
||||||
});
|
});
|
||||||
showToast({title: "操作成功"});
|
showToast({title: "操作成功"});
|
||||||
navigateBack({delta: 1})
|
navigateBack({delta: 1})
|
||||||
} else {
|
} else {
|
||||||
|
console.log('classInfo:', values.classInfo);
|
||||||
showToast({title: "请选择班级"});
|
showToast({title: "请选择班级"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
<view class="font-w-500 flex-row">
|
<view class="font-w-500 flex-row">
|
||||||
<view class="mr-5">{{ data.fullName }}</view>
|
<view class="mr-5">{{ data.fullName }}</view>
|
||||||
<view class="mr-5">{{ data.score }}分</view>
|
<view class="mr-5">{{ data.score }}分</view>
|
||||||
本周得分{{ data.score ? (100 + parseFloat(data.score)) : 100 }}
|
本周得分{{ data.score ? (300 + parseFloat(data.score)) : 300 }}
|
||||||
</view>
|
</view>
|
||||||
<view class="grid gridCols-4 mt-15 gapY-15">
|
<view class="grid gridCols-4 mt-15 gapY-15">
|
||||||
<template v-for="(item,key) in inspectItems">
|
<template v-for="(item,key) in inspectItems">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user