完善代课教师选择,准备封装教师选择器的扩展版本

This commit is contained in:
ywyonui 2025-07-24 19:37:47 +08:00
parent d92ea7b56c
commit 04040c14d2
14 changed files with 1563 additions and 81 deletions

97
pnpm-lock.yaml generated
View File

@ -74,6 +74,9 @@ importers:
pinia-plugin-persist-uni:
specifier: 1.2.0
version: 1.2.0(pinia@2.0.23(typescript@4.8.3)(vue@3.2.45))(vue@3.2.45)
qrcode:
specifier: ^1.5.3
version: 1.5.4
uview-plus:
specifier: 3.1.20
version: 3.1.20
@ -111,6 +114,9 @@ importers:
'@types/node':
specifier: 18.11.15
version: 18.11.15
'@types/qrcode':
specifier: ^1.5.5
version: 1.5.5
'@types/uni-app':
specifier: 1.4.4
version: 1.4.4
@ -1322,6 +1328,9 @@ packages:
'@types/prettier@2.7.3':
resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==}
'@types/qrcode@1.5.5':
resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==}
'@types/stack-utils@2.0.3':
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
@ -1764,6 +1773,9 @@ packages:
clipboard@2.0.11:
resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
cliui@7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
@ -1904,6 +1916,10 @@ packages:
supports-color:
optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
decimal.js@10.5.0:
resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
@ -1944,6 +1960,9 @@ packages:
resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dom-walk@0.1.2:
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
@ -2965,6 +2984,10 @@ packages:
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
engines: {node: '>=4.0.0'}
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
postcss-import@14.1.0:
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
@ -3062,6 +3085,11 @@ packages:
resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==}
hasBin: true
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
qs@6.13.0:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
@ -3126,6 +3154,9 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
@ -3245,6 +3276,9 @@ packages:
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@ -3682,6 +3716,9 @@ packages:
resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==}
engines: {node: '>=10'}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@ -3756,6 +3793,9 @@ packages:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -3767,10 +3807,18 @@ packages:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
yargs-parser@20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
yargs@16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'}
@ -5617,6 +5665,10 @@ snapshots:
'@types/prettier@2.7.3': {}
'@types/qrcode@1.5.5':
dependencies:
'@types/node': 18.11.15
'@types/stack-utils@2.0.3': {}
'@types/uni-app@1.4.4':
@ -6221,6 +6273,12 @@ snapshots:
select: 1.1.2
tiny-emitter: 2.1.0
cliui@6.0.0:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
cliui@7.0.4:
dependencies:
string-width: 4.2.3
@ -6325,6 +6383,8 @@ snapshots:
dependencies:
ms: 2.1.3
decamelize@1.2.0: {}
decimal.js@10.5.0: {}
dedent@0.7.0: {}
@ -6351,6 +6411,8 @@ snapshots:
diff-sequences@27.5.1: {}
dijkstrajs@1.0.3: {}
dom-walk@0.1.2: {}
domexception@2.0.1:
@ -7582,6 +7644,8 @@ snapshots:
pngjs@3.4.0: {}
pngjs@5.0.0: {}
postcss-import@14.1.0(postcss@8.5.5):
dependencies:
postcss: 8.5.5
@ -7678,6 +7742,12 @@ snapshots:
qrcode-terminal@0.12.0: {}
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
qs@6.13.0:
dependencies:
side-channel: 1.1.0
@ -7742,6 +7812,8 @@ snapshots:
require-from-string@2.0.2: {}
require-main-filename@2.0.0: {}
requires-port@1.0.0: {}
resolve-cwd@3.0.0:
@ -7864,6 +7936,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
set-blocking@2.0.0: {}
setprototypeof@1.2.0: {}
shebang-command@2.0.0:
@ -8288,6 +8362,8 @@ snapshots:
tr46: 2.1.0
webidl-conversions: 6.1.0
which-module@2.0.1: {}
which@2.0.2:
dependencies:
isexe: 2.0.0
@ -8343,14 +8419,35 @@ snapshots:
xtend@4.0.2: {}
y18n@4.0.3: {}
y18n@5.0.8: {}
yallist@3.1.1: {}
yaml@1.10.2: {}
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs-parser@20.2.9: {}
yargs@15.4.1:
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3
yargs@16.2.0:
dependencies:
cliui: 7.0.4

27
src/api/base/common.ts Normal file
View File

@ -0,0 +1,27 @@
// 食堂巡查相关API接口
import { get } from "@/utils/request";
// 所有年级
export const njFindAll = async () => {
return await get("/api/nj/findAllNj");
};
// 根据年级查询班级
export const bjFindByNjId = async (params: any) => {
return await get("/api/nj/findByNjId", params);
};
// 所有教师
export const jsFindAll = async () => {
return await get("/api/js/findAll");
};
// 所有职务
export const zwFindAllApi = async () => {
return await get("/api/zw/findAll");
};
// 根据类型查询职务
export const zwGetListByLxApi = async (params: any) => {
return await get("/api/zw/getListByLx", params);
};

View File

@ -0,0 +1,217 @@
<template>
<view class="js-picker">
<view class="js-selected" @click="showPicker">
<view class="js-selected-name">
<text class="data" v-if="selectedList && selectedList.length">{{ getShowSelectedName() }}</text>
<text class="data" style="color: #999;" v-else>请选择老师</text>
</view>
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
</view>
<u-popup :show="showPopup" @close="showPopup=false">
<view class="js-picker-popup">
<view class="js-picker-header">
<view class="js-cancel-btn" @click="handleCancel">取消</view>
<view class="js-picker-title">请选择教师</view>
<view class="js-ok-btn" @click="handleOk">确定</view>
</view>
<view class="js-picker-search">
<BasicSearch @change="handleSearch" :showAction="false" height="36" :placeholder="'输入教师名称查询'"/>
</view>
<view class="js-list">
<scroll-view scroll-y style="max-height: 60vh" :scroll-top="targetScrollTop">
<view class="js-item" v-for="(item, index) in jsList" :key="index"
:class="{ selected: item.selected }" @click="handleSelect(item)">
<view class="js-name">{{ item.label }}</view>
<BasicIcon type="checkmarkempty" v-if="item.selected" color="#333" />
</view>
</scroll-view>
</view>
</view>
</u-popup>
</view>
</template>
<script lang="ts" setup>
import { useCommonStore } from "@/store/modules/common";
const { getAllJs } = useCommonStore();
//
const props = withDefaults(defineProps<{
defualtValue: any,
parentData: any,
multiple: boolean,
// id
excludeIds: any
}>(), {
defualtValue: null,
parentData: null,
multiple: false,
excludeIds: []
});
// emit
const emit = defineEmits(['change'])
const targetScrollTop = ref(0); // scroll-top
const showPopup = ref(false);
const jsListAll = ref<any>([]);
const jsList = ref<any>([]);
let searchKey = "";
const selectedList = ref<any>([]);
const getShowSelectedName = () => {
return selectedList.value.map((item: any) => item.label).join(",");
};
const handleSearch = (value: any) => {
searchKey = value;
rebuildJsList();
return
};
const handleSelect = (item: any) => {
if (props.multiple) {
selectedList.value.push(item);
} else {
jsList.value.map((item: any) => item.selected = false);
selectedList.value = [item];
}
item.selected = true;
}
const handleCancel = () => {
showPopup.value = false;
}
const handleOk = () => {
showPopup.value = false;
if (props.multiple) {
emit("change", selectedList.value, props.parentData);
} else {
emit("change", selectedList.value[0], props.parentData);
}
}
const showPicker = () => {
showPopup.value = true;
};
const rebuildJsList = () => {
jsList.value = [];
jsListAll.value.map((item: any) => {
if (props.excludeIds && props.excludeIds.length && props.excludeIds.includes(item.id)) {
return;
}
// jsxm
if ( !searchKey || item.jsxm.includes(searchKey)) {
jsList.value.push({
label: item.jsxm,
value: item.id,
});
}
});
};
//
defineExpose({
showPicker
});
onMounted(async () => {
console.log("排除列表:", props.excludeIds);
const res = await getAllJs()
jsListAll.value = res.result || [];
rebuildJsList();
if (!props.defualtValue) {
return;
}
if (props.multiple) {
if (!props.defualtValue.length) {
return;
}
selectedList.value = [];
for (let i = 0; i < jsListAll.value.length; i++) {
const item = jsListAll.value[i];
if (props.defualtValue.indexOf(item.value) > -1) {
item.selected = true;
selectedList.value.push(item);
} else {
item.selected = false;
}
}
} else {
for (let i = 0; i < jsList.value.length; i++) {
const item = jsList.value[i];
if (item.value === props.defualtValue) {
item.selected = true;
selectedList.value.push(item);
} else {
item.selected = false;
}
}
}
});
</script>
<style lang="scss" scoped>
.js-picker {
flex: 1;
.js-selected {
display: flex;
align-items: center;
justify-content: center;
.js-selected-name {
flex: 1;
}
}
.js-picker-popup {
min-height: 50vh;
max-height: 90vh;
padding: 10px;
display: flex;
flex-direction: column;
.js-picker-header {
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
.js-cancel-btn {
flex: 0 0 50;
padding: 5px 10px;
}
.js-ok-btn {
flex: 0 0 50;
padding: 5px 10px;
color: #3c9cff;
}
.js-picker-title {
flex: 1 0 1px;
text-align: center;
font-size: 20px;
}
}
.js-picker-search {
margin: 10px 0;
}
.js-list {
flex: 1 0 1px;
.js-item {
display: flex;
padding: 10px 15px;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
&.selected {
background-color: beige;
}
.js-name {
flex: 1;
}
}
}
}
}
</style>

View File

@ -0,0 +1,76 @@
<template>
<!-- 选择类别 -->
<view class="filter-row">
<view class="filter-label">选择类别</view>
<picker
mode="selector"
:range="optionList"
range-key="label"
@change="handleChange"
class="filter-picker"
>
<view class="picker-display">
<text :style="{ color: cur && cur.label ? '#333' : '#999' }">
{{ cur.label || '请选择类别' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</picker>
</view>
</template>
<script lang="ts" setup>
//
const props = withDefaults(defineProps<{
defaultValue: any,
}>(), {
defaultValue: 0,
});
// emit
const emit = defineEmits(['change'])
//
const optionList = [
{ value: 1, label: '所有老师' },
{ value: 2, label: '科目' },
{ value: 3, label: '班主任' },
{ value: 4, label: '职务' }
];
const cur = ref<any>({});
const handleChange = (e:any) => {
cur.value = optionList.find((item:any) => item.value = e.detail.value);
emit('change', cur);
};
</script>
<style lang="scss" scoped>
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
}
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<!-- 选择类别 -->
<view class="filter-row">
<view class="filter-label">职务类别</view>
<picker
mode="selector"
:range="optionList"
range-key="label"
@change="handleChange"
class="filter-picker"
>
<view class="picker-display">
<text :style="{ color: cur && cur.label ? '#333' : '#999' }">
{{ cur.label || '请选择职务类别' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</picker>
</view>
</template>
<script lang="ts" setup>
//
const props = withDefaults(defineProps<{
defaultValue: any,
}>(), {
defaultValue: 0,
});
// emit
const emit = defineEmits(['change'])
//
const optionList = [
{ value: 1, label: '党政职务' },
{ value: 2, label: '其他职务' }
];
const cur = ref<any>({});
const handleChange = (e:any) => {
cur.value = optionList.find((item:any) => item.value = e.detail.value);
emit('change', cur);
};
</script>
<style lang="scss" scoped>
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
}
}
</style>

View File

@ -0,0 +1,652 @@
<template>
<u-popup :show="showPopup" @close="showPopup=false">
<view class="teacher-picker-container">
<!-- 筛选条件区域 -->
<view class="filter-section">
<!-- 选择类别 -->
<TopTypePicker @change="onSelectTypeChange" />
<!-- 职务类型选择器 -->
<ZwTypePicker @change="onZwTypeChange" v-if="selectType === 4" />
<!-- 具体选择 -->
<view class="filter-row" v-if="selectType && datas.length > 0">
<view class="filter-label">{{ getSecondSelectLabel() }}</view>
<view class="multi-select-container">
<view class="selected-items-display" @click="showMultiSelectModal">
<text :class="{ placeholder: !selectTwoType.length }">
{{ getSecondSelectText() || '请选择' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</view>
</view>
</view>
<!-- 选择结果区域 -->
<view class="result-section">
<view class="result-title">
👥 选择结果
<text v-if="selectedTeachers.length > 0" class="result-count">
({{ selectedTeachers.length }})
</text>
</view>
<!-- 已选教师标签 -->
<view class="name-tags" v-if="selectedTeachers.length > 0">
<view
v-for="teacher in selectedTeachers"
:key="teacher.id"
class="name-tag"
@click="toggleTeacherSelection(teacher)"
>
<text>{{ teacher.jsxm }}</text>
</view>
</view>
<!-- 空状态 -->
<view v-if="selectedTeachers.length === 0 && !isLoading" class="empty-state">
<uni-icons type="info" size="60" color="#ccc"></uni-icons>
<text class="empty-text">
{{ selectType ? '请先选择条件,加载教师列表' : '请选择筛选条件' }}
</text>
</view>
</view>
<!-- 底部操作 -->
<view class="popup-bottom-actions">
<button class="action-btn cancel-btn" @click="handleCancel">
取消
</button>
<button class="action-btn confirm-btn" @click="handleConfirm">
确定 ({{ selectedTeachers.length }})
</button>
</view>
</view>
</u-popup>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted } from "vue";
import {
jsdfindJsByPhoneApi,
jsFindByNjIdOrBjIdApi,
jsFindByKmIdApi,
jsFindByBzrNjIdApi,
jsFindByZwIdApi,
findAllNj,
kmFindAllApi,
zwFindAllApi
} from "@/api/base/server";
import TopTypePicker from "./TopTypePicker.vue";
import ZwTypePicker from "./ZwTypePicker.vue";
interface TeacherInfo {
id: string;
jsxm: string;
jsId: string;
dzzw: string;
qtzw: string;
}
//
const props = withDefaults(defineProps<{
defaultValue: any,
customStyle: any,
iconArrow: string,
isMultiple: boolean //
}>(), {
defaultValue: [],
customStyle: {},
iconArrow: "bottom",
isMultiple: true //
});
// emit
const emit = defineEmits(['change'])
const showPopup = ref(false);
const selectType = ref<number | null>(null);
const selectTwoType = ref<string[]>([]);
const zwType = ref<number>(1);
const datas = ref<any[]>([]);
const selectedTeachers = ref<TeacherInfo[]>([]);
const isLoading = ref(false);
const showModal = ref(false); //
//
const selectTypeOptions = [
{ value: 1, label: '所有老师' },
{ value: 2, label: '科目' },
{ value: 3, label: '班主任' },
{ value: 4, label: '职务' }
];
//
const zwTypeOptions = [
{ value: 1, label: '党政职务' },
{ value: 2, label: '其他职务' }
];
//
const getSelectTypeText = () => {
const option = selectTypeOptions.find(item => item.value === selectType.value);
return option ? option.label : '';
};
//
const getZwTypeText = () => {
const option = zwTypeOptions.find(item => item.value === zwType.value);
return option ? option.label : '';
};
//
const getSecondSelectLabel = () => {
switch (selectType.value) {
case 1:
return '年级/班级';
case 2:
return '科目';
case 3:
return '年级';
case 4:
return '具体职务';
default:
return '请选择';
}
};
//
const getSecondSelectText = () => {
if (!selectTwoType.value.length) return '';
const selectedItems = datas.value.filter(item =>
selectTwoType.value.includes(item.value)
);
if (selectedItems.length === 1) {
return selectedItems[0].label;
} else if (selectedItems.length > 1) {
return `已选择${selectedItems.length}`;
}
return '';
};
//
const onSelectTypeChange = async (type: any) => {
selectType.value = selectTypeOptions[type.value].value;
selectTwoType.value = [];
selectedTeachers.value = [];
if (selectType.value === 1 || selectType.value === 3) {
await loadNjData();
} else if (selectType.value === 2) {
await loadKmData();
} else if (selectType.value === 4) {
await loadZwData();
}
};
//
const onZwTypeChange = async (type: any) => {
zwType.value = zwTypeOptions[type.value].value;
selectTwoType.value = [];
selectedTeachers.value = [];
await loadZwData();
};
//
const showMultiSelectModal = () => {
showModal.value = true;
};
const hideMultiSelectModal = () => {
showModal.value = false;
};
const toggleItemSelection = (value: string) => {
const index = selectTwoType.value.indexOf(value);
if (index > -1) {
if (props.isMultiple) {
selectTwoType.value.splice(index, 1);
} else {
selectTwoType.value = [value];
hideMultiSelectModal();
loadTeachers();
}
} else {
if (props.isMultiple) {
selectTwoType.value.push(value);
} else {
selectTwoType.value = [value];
hideMultiSelectModal();
loadTeachers();
}
}
};
//
const toggleTeacherSelection = (teacher: TeacherInfo) => {
if (!props.isMultiple) {
const index = selectedTeachers.value.findIndex(t => t.id === teacher.id);
if (index > -1) {
selectedTeachers.value = [];
} else {
selectedTeachers.value = [teacher];
}
}
};
//
const loadNjData = async () => {
try {
const result:any = await findAllNj();
let njData = [];
if (Array.isArray(result)) {
njData = result;
} else if (result && typeof result === 'object') {
if (Array.isArray(result.result)) {
njData = result.result;
} else if (result.resultCode === 1 && Array.isArray(result.result)) {
njData = result.result;
} else if (Array.isArray(result.data)) {
njData = result.data;
} else {
console.warn('年级数据格式异常:', result);
njData = [];
}
} else {
console.warn('年级数据格式异常:', result);
njData = [];
}
datas.value = njData.map((item: any) => ({
label: item.njmc || item.name || item.label,
value: item.id || item.value
}));
} catch (error) {
console.error('加载年级数据失败:', error);
uni.showToast({ title: '加载年级数据失败', icon: 'none' });
}
};
//
const loadKmData = async () => {
try {
const result:any = await kmFindAllApi();
let kmData = [];
if (Array.isArray(result)) {
kmData = result;
} else if (result && typeof result === 'object') {
if (Array.isArray(result.result)) {
kmData = result.result;
} else if (result.resultCode === 1 && Array.isArray(result.result)) {
kmData = result.result;
} else if (Array.isArray(result.data)) {
kmData = result.data;
} else {
console.warn('科目数据格式异常:', result);
kmData = [];
}
} else {
console.warn('科目数据格式异常:', result);
kmData = [];
}
const sortedData = kmData.sort((a: any, b: any) => {
const sortA = a.sort || 0;
const sortB = b.sort || 0;
if (sortA !== sortB) {
return sortA - sortB;
} else {
return (a.kmmc || a.name || '').localeCompare(b.kmmc || b.name || '');
}
});
datas.value = sortedData.map((item: any) => ({
label: item.kmmc || item.name || item.label,
value: item.id || item.value
}));
} catch (error) {
console.error('加载科目数据失败:', error);
uni.showToast({ title: '加载科目数据失败', icon: 'none' });
}
};
//
const loadZwData = async () => {
try {
const result:any = await zwFindAllApi();
let allZwData = [];
if (Array.isArray(result)) {
allZwData = result;
} else if (result && typeof result === 'object') {
if (Array.isArray(result.result)) {
allZwData = result.result;
} else if (result.resultCode === 1 && Array.isArray(result.result)) {
allZwData = result.result;
} else if (Array.isArray(result.data)) {
allZwData = result.data;
} else {
console.warn('职务数据格式异常:', result);
allZwData = [];
}
} else {
console.warn('职务数据格式异常:', result);
allZwData = [];
}
//
const filteredData = allZwData.filter((item: any) => {
if (zwType.value === 1) {
return item.zwlx === '1' || item.zwlx === '党政职务' || item.zwlx === 'A' || item.zwlx === 'dzzw';
} else if (zwType.value === 2) {
return item.zwlx === '2' || item.zwlx === '其他职务' || item.zwlx === 'B' || item.zwlx === 'qtzw';
}
return true;
});
//
const sortedData = filteredData.sort((a: any, b: any) => {
const sortA = a.sort || 0;
const sortB = b.sort || 0;
if (sortA !== sortB) {
return sortA - sortB;
} else {
return (a.zwmc || a.name || '').localeCompare(b.zwmc || b.name || '');
}
});
datas.value = sortedData.map((item: any) => ({
label: item.zwmc || item.name || item.label,
value: item.id || item.value
}));
} catch (error) {
console.error('加载职务数据失败:', error);
uni.showToast({ title: '加载职务数据失败', icon: 'none' });
}
};
//
const loadTeachers = async () => {
if (!selectType.value || !selectTwoType.value.length) return;
isLoading.value = true;
try {
let allTeacherData: any[] = [];
// API
for (const selectedValue of selectTwoType.value) {
let result:any;
if (selectType.value === 1) {
result = await jsFindByNjIdOrBjIdApi({
njOrBjId: selectedValue
});
} else if (selectType.value === 2) {
result = await jsFindByKmIdApi({
kmId: selectedValue
});
} else if (selectType.value === 3) {
result = await jsFindByBzrNjIdApi({
njId: selectedValue
});
} else if (selectType.value === 4) {
result = await jsFindByZwIdApi({
zwId: selectedValue,
zwType: zwType.value.toString()
});
}
let teacherData = [];
if (Array.isArray(result)) {
teacherData = result;
} else if (result && typeof result === 'object') {
if (Array.isArray(result.result)) {
teacherData = result.result;
} else if (result.resultCode === 1 && Array.isArray(result.result)) {
teacherData = result.result;
} else if (Array.isArray(result.data)) {
teacherData = result.data;
} else {
console.warn('教师数据格式异常:', result);
teacherData = [];
}
} else {
console.warn('教师数据格式异常:', result);
teacherData = [];
}
//
allTeacherData = allTeacherData.concat(teacherData);
}
// ID
const uniqueTeachers = allTeacherData.filter((teacher, index, self) =>
index === self.findIndex(t => (t.id || t.jsId) === (teacher.id || teacher.jsId))
);
// 使
selectedTeachers.value = uniqueTeachers.map((item: any) => ({
id: item.id || item.jsId,
jsxm: item.jsxm || item.name || item.label,
jsId: item.id || item.jsId,
dzzw: item.dzzw || '',
qtzw: item.qtzw || ''
}));
} catch (error) {
console.error('加载教师列表失败:', error);
uni.showToast({ title: '加载教师列表失败', icon: 'none' });
} finally {
isLoading.value = false;
}
};
//
const handleCancel = () => {
showPopup.value = false;
};
//
const handleConfirm = () => {
// ID
const teacherIds = selectedTeachers.value.map(t => t.id);
const uniqueIds = [...new Set(teacherIds)];
if (teacherIds.length !== uniqueIds.length) {
//
const uniqueTeachers = selectedTeachers.value.filter((teacher, index, self) =>
index === self.findIndex(t => t.id === teacher.id)
);
selectedTeachers.value = uniqueTeachers;
}
// change
emit('change', selectedTeachers.value);
//
showPopup.value = false;
};
//
const showPicker = () => {
showPopup.value = true;
};
//
defineExpose({
showPicker
});
</script>
<style lang="scss" scoped>
.teacher-picker-container {
padding: 15px;
max-height: 80vh;
}
.filter-section {
background: white;
border-radius: 12px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.filter-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 15px;
}
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
}
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
.placeholder {
color: #999;
}
.multi-select-container {
flex: 1;
position: relative;
}
.selected-items-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
cursor: pointer;
}
.result-section {
background: white;
border-radius: 12px;
padding: 15px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.result-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
}
.result-count {
color: #007aff;
font-size: 14px;
margin-left: 8px;
}
.name-tags {
display: flex;
flex-wrap: wrap;
gap: 8px 10px;
margin-bottom: 15px;
}
.name-tag {
position: relative;
font-size: 13px;
padding: 5px 8px;
border-radius: 4px;
text-align: center;
flex-grow: 0;
flex-shrink: 0;
box-sizing: border-box;
flex-basis: calc((100% - 30px) / 4);
height: 30px;
line-height: 20px;
border: 1px solid #f4f4f5;
white-space: normal;
word-break: break-all;
background-color: #f4f4f5;
color: #909399;
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
&.selected {
background-color: #007aff;
color: white;
border-color: #007aff;
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #999;
}
.empty-text {
margin-top: 15px;
font-size: 16px;
}
.popup-bottom-actions {
display: flex;
gap: 15px;
padding: 15px;
background: white;
border-top: 1px solid #f0f0f0;
position: sticky;
bottom: 0;
z-index: 100;
}
.action-btn {
flex: 1;
padding: 12px;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
border: none;
}
.cancel-btn {
background: #f5f5f5;
color: #666;
}
.confirm-btn {
background: linear-gradient(135deg, #007aff 0%, #0056cc 100%);
color: white;
box-shadow: 0 2px 8px rgba(0, 122, 255, 0.3);
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<!-- 选择类别 -->
<view class="filter-row">
<view class="filter-label">职务类别</view>
<picker
mode="selector"
:range="optionList"
range-key="label"
@change="handleChange"
class="filter-picker"
>
<view class="picker-display">
<text :style="{ color: cur && cur.label ? '#333' : '#999' }">
{{ cur.label || '请选择职务类别' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</picker>
</view>
</template>
<script lang="ts" setup>
//
const props = withDefaults(defineProps<{
defaultValue: any,
}>(), {
defaultValue: 0,
});
// emit
const emit = defineEmits(['change'])
//
const optionList = [
{ value: 1, label: '党政职务' },
{ value: 2, label: '其他职务' }
];
const cur = ref<any>({});
const handleChange = (e:any) => {
cur.value = optionList.find((item:any) => item.value = e.detail.value);
emit('change', cur);
};
</script>
<style lang="scss" scoped>
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
}
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<!-- 选择类别 -->
<view class="filter-row">
<view class="filter-label">职务类别</view>
<picker
mode="selector"
:range="optionList"
range-key="label"
@change="handleChange"
class="filter-picker"
>
<view class="picker-display">
<text :style="{ color: cur && cur.label ? '#333' : '#999' }">
{{ cur.label || '请选择职务类别' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</picker>
</view>
</template>
<script lang="ts" setup>
//
const props = withDefaults(defineProps<{
defaultValue: any,
}>(), {
defaultValue: 0,
});
// emit
const emit = defineEmits(['change'])
//
const optionList = [
{ value: 1, label: '党政职务' },
{ value: 2, label: '其他职务' }
];
const cur = ref<any>({});
const handleChange = (e:any) => {
cur.value = optionList.find((item:any) => item.value = e.detail.value);
emit('change', cur);
};
</script>
<style lang="scss" scoped>
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
}
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<!-- 选择类别 -->
<view class="filter-row">
<view class="filter-label">职务类别</view>
<picker
mode="selector"
:range="optionList"
range-key="label"
@change="handleChange"
class="filter-picker"
>
<view class="picker-display">
<text :style="{ color: cur && cur.label ? '#333' : '#999' }">
{{ cur.label || '请选择职务类别' }}
</text>
<uni-icons type="right" size="16" color="#999"></uni-icons>
</view>
</picker>
</view>
</template>
<script lang="ts" setup>
//
const props = withDefaults(defineProps<{
defaultValue: any,
}>(), {
defaultValue: 0,
});
// emit
const emit = defineEmits(['change'])
//
const optionList = [
{ value: 1, label: '党政职务' },
{ value: 2, label: '其他职务' }
];
const cur = ref<any>({});
const handleChange = (e:any) => {
cur.value = optionList.find((item:any) => item.value = e.detail.value);
emit('change', cur);
};
</script>
<style lang="scss" scoped>
.filter-row {
display: flex;
align-items: center;
margin-bottom: 12px;
.filter-label {
width: 80px;
font-size: 14px;
color: #666;
margin-right: 10px;
}
.filter-picker {
flex: 1;
.picker-display {
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 10px 12px;
font-size: 14px;
color: #333;
}
}
}
</style>

View File

@ -1,15 +1,49 @@
<template>
<view class="back-f8f8f8">
<view class="flex-row items-center justify-between py-15 global-bg-color">
<view>
<view class="dk-title">
<BasicTitle line title="代课明细" :isBorder="false" />
</view>
<view @click="getPkkbList">
<BasicIcon type="refreshempty" size="25" />
</view>
</view>
<view v-if="dkList.xl.length > 0">
<template v-for="(item, index) in dkList.xl" :key="index">
<view class="dk-tabs mb-10">
<BasicTabs class="type-tabs"
ref="tabsRef" :list="tabList" bar-width="60px" scroll-count="4"
:current="curTabIndex" @change="switchTab"
/>
<view class="dk-card" v-if="curTabIndex === 0">
<view class="card-body">
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value">
<JsPicker @change="changeJsByTy" :parent-data="tyDk" :defualtValue="tyDk.dkJsId" :multiple="false" :excludeIds="excludeIds" />
</view>
</view>
</view>
</view>
<view v-if="curTabIndex === 1">
<view v-for="(item, index) in kmDkList" :key="index">
<view class="dk-card" style="margin: 0;">
<view class="card-body">
<view class="info-row">
<text class="label">排课名称:</text>
<text class="value">{{ item.pkName }}</text>
</view>
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value">
<JsPicker @change="changeJsByKm" :parent-data="item" :defualtValue="item.dkJsId" :multiple="false" :excludeIds="excludeIds" />
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="dkList.length > 0">
<view v-for="(item, index) in dkList" :key="index">
<view class="dk-card">
<view class="card-header">
<text class="applicant-name">{{ item.dktime }}{{ item.jcmc }}</text>
@ -23,24 +57,26 @@
<text class="label">上课时间:</text>
<text class="value">{{ item.startTime }}-{{ item.endTime }}</text>
</view>
<view class="info-row" @click="clickChangeJs">
<view class="info-row">
<text class="label">代课老师:</text>
<view class="value">
<text class="data" v-if="item.dkJsId">{{ item.dkJsName }}</text>
<text class="data" style="color: #999;" v-else>请选择代课老师</text>
<view class="value" v-if="curTabIndex === 2">
<JsPicker @change="changeJs" :parent-data="item" :defualtValue="item.dkJsId" :multiple="false" :excludeIds="excludeIds" />
</view>
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
<view v-else>{{ item.dkJsName }}</view>
</view>
</view>
</view>
</template>
</view>
</view>
<view v-else class="p-15 flex-row-center color-9 font-13 white-bg-color">暂无数据</view>
</view>
</template>
<script setup lang="ts">
import JsPicker from "@/pages/components/JsPicker/index.vue";
import { getPkkbByJsRangeTimeApi } from "@/api/base/qjApi";
import { useUserStore } from "@/store/modules/user";
const { getJs } = useUserStore();
//
const props = withDefaults(defineProps<{
@ -53,67 +89,26 @@ const props = withDefaults(defineProps<{
})
});
// const schema = reactive<FormsSchema[]>([
// {
// field: "dktime", // pktime
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "pkmc",
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "jcmc", // (jcType)+jc
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "njbjmx", // bc + bjmc
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "startTime", // startTime
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "endTime", // endTime
// label: "",
// component: "BasicInput",
// componentProps: {
// readonly: true,
// },
// },
// {
// field: "jsId",
// label: "",
// component: "BasicInput",
// required: true,
// componentProps: {},
// },
// ]);
//
const excludeIds = ref<any>([getJs.id]);
const dkList = reactive<any>({
xl: [],
});
const tyDk = ref<any>({});
const dkList = ref<any>([]);
const kmDkList = ref<any>([]);
const tabList = ref([
{ name: "统一代课", id: "tab-ty" },
{ name: "按排课", id: "tab-pk" },
{ name: "按节次", id: "tab-jc" },
]);
const curTabIndex = ref(0);
const switchTab = (index : number) => {
curTabIndex.value = index;
}
const jsTypeMc: any = {
"ZAM": '早自习',
@ -129,14 +124,15 @@ const getPkkbList = async () => {
});
//
const srcData: any = {};
dkList.xl.map((item: any) => {
dkList.value.map((item: any) => {
const key = item.dktime + item.jcType + item.jc;
srcData[key] = {
dkJsId: item.dkJsId,
dkJsName: item.dkJsName
};
});
dkList.xl = res.result.map((item: any) => {
const kmMap:any = {};
dkList.value = res.result.map((item: any) => {
item.dktime = item.kbtime.split(" ")[0];
item.njbjmx = item.bc + item.bjmc;
item.jcmc = jsTypeMc[item.jcType] + "第" + item.jc + "节";
@ -149,17 +145,60 @@ const getPkkbList = async () => {
item.dkJsId = "";
item.dkJsName = "";
}
kmMap[item.pkId] = kmMap[item.pkId] || {
pkName: item.pkName,
pkId: item.pkId,
};
return item;
});
// kmMapvalue
kmDkList.value = Object.values(kmMap);
console.log(kmDkList.value);
}
const clickChangeJs = () => {
const changeJsByTy = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
const newList = dkList.value.map((dk: any) => {
return {
...dk,
dkJsId: item.dkJsId,
dkJsName: item.dkJsName
};
});
dkList.value = newList;
const newKmList = kmDkList.value.map((km: any) => {
return {
...km,
dkJsId: item.dkJsId,
dkJsName: item.dkJsName
};
});
kmDkList.value = newKmList;
}
const changeJsByKm = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
//
const newList = dkList.value.map((dk: any) => {
if (dk.pkId === item.pkId) {
return { ...dk, dkJsId: item.dkJsId, dkJsName: item.dkJsName };
}
return dk;
});
dkList.value = newList;
}
const changeJs = (selected: any, item: any) => {
item.dkJsId = selected.value;
item.dkJsName = selected.label;
}
// ref
function getDkList() {
return dkList;
return dkList.value;
}
//
@ -170,6 +209,10 @@ defineExpose({
</script>
<style lang="scss" scoped>
.dk-tabs {
flex: 1 0 1px;
}
.dk-card {
background-color: #ffffff;
border-radius: 8px;

View File

@ -39,8 +39,10 @@
<script lang="ts" setup>
import { ref } from "vue";
import { useUserStore } from "@/store/modules/user";
import { useCommonStore } from "@/store/modules/common";
const { getJs } = useUserStore();
import { zwGetListByLxApi, getRzRjApi } from "@/api/base/server";
const { getZwListByLx } = useCommonStore();
import { getRzRjApi } from "@/api/base/server";
const dzZwList = ref<any[]>([]);
const qtZwList = ref<any[]>([]);
@ -108,7 +110,7 @@ onMounted(async () => {
qtZw = getJs.qtzw.split(",");
}
{
const res = await zwGetListByLxApi({ zwlx: '党政职务' });
const res = await getZwListByLx({ zwlx: '党政职务' });
res.result.map((item: any) => {
const zw = dzZw.find((zw: any) => zw == item.id);
if (zw) {
@ -118,7 +120,7 @@ onMounted(async () => {
});
};
{
const res = await zwGetListByLxApi({ zwlx: '其他职务' });
const res = await getZwListByLx({ zwlx: '其他职务' });
res.result.map((item: any) => {
const zw = dzZw.find((zw: any) => zw == item.id);
if (zw) {

View File

@ -277,7 +277,7 @@ const confirmMultiSelect = () => {
//
const loadNjData = async () => {
try {
const result = await findAllNj();
const result:any = await findAllNj();
console.log('年级API返回结果:', result);
//
@ -317,7 +317,7 @@ const loadNjData = async () => {
//
const loadKmData = async () => {
try {
const result = await kmFindAllApi();
const result:any = await kmFindAllApi();
console.log('科目API返回结果:', result);
//
@ -367,7 +367,7 @@ const loadKmData = async () => {
//
const loadZwData = async () => {
try {
const result = await zwFindAllApi();
const result:any = await zwFindAllApi();
console.log('职务API返回结果:', result);
//
@ -434,7 +434,7 @@ const loadTeachers = async () => {
// API
for (const selectedValue of selectTwoType.value) {
let result;
let result:any;
if (selectType.value === 1) {
result = await jsFindByNjIdOrBjIdApi({

View File

@ -0,0 +1,70 @@
import { defineStore } from "pinia";
import {
njFindAll,
bjFindByNjId,
jsFindAll,
zwFindAllApi,
zwGetListByLxApi,
} from "@/api/base/common";
interface CommonState {
data: any;
}
export const useCommonStore = defineStore({
id: "app-common",
state: (): CommonState => ({
// 字典数据
data: {}
}),
getters: {
getData(): any {
return this.data;
}
},
actions: {
setData(data: any) {
this.data = data;
},
// 所有年级
async getAllNj(): Promise<any> {
if (!this.data.allNj) {
this.data.allNj = await njFindAll();
}
return Promise.resolve(this.data.allNj);
},
// 根据年级查询班级
async getBjListByNj(params: any): Promise<any> {
if (!this.data.bj || !this.data.bj[params.njId]) {
this.data.bj[params.njId] = await bjFindByNjId(params);
}
return Promise.resolve(this.data.bj[params.njId]);
},
// 所有教师
async getAllJs(): Promise<any> {
if (!this.data.allJs) {
this.data.allJs = await jsFindAll();
}
return Promise.resolve(this.data.allJs);
},
// 所有职务
async getAllZw(): Promise<any> {
if (!this.data.allZw) {
this.data.allZw = await zwFindAllApi();
}
return Promise.resolve(this.data.allZw);
},
// 根据职务类型获取职务列表
async getZwListByLx(params: any): Promise<any> {
if (!this.data.zw || !this.data.zw[params.zwlx]) {
this.data.zw[params.zwlx] = await zwGetListByLxApi(params);
}
return Promise.resolve(this.data.zw[params.zwlx]);
},
},
persist: {
enabled: true,
detached: true,
H5Storage: localStorage
},
});

View File

@ -2,6 +2,7 @@ import {defineStore} from "pinia";
import {authenticationApi, loginCode, loginPass, weChatLogin} from "@/api/system/login";
import {AUTH_KEY} from "@/config";
import { useDicStore } from "@/store/modules/dic";
import { useCommonStore } from "@/store/modules/common";
interface UserState {
userdata: any;
@ -106,6 +107,7 @@ export const useUserStore = defineStore({
this.setJs({})
this.setAuth([])
useDicStore().setData({});
useCommonStore().setData({});
},
},
persist: {