| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- <template>
- <div class="app-container">
- <el-row :gutter="20">
- <el-col>
- <!-- 查询表单 -->
- <el-form v-show="showSearch" :model="queryParams" ref="queryRef" :inline="true" label-width="80px">
- <el-form-item label="姓名">
- <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" style="width: 200px"/>
- </el-form-item>
- <el-form-item label="手机号">
- <el-input v-model="queryParams.phone" placeholder="请输入手机号" clearable @keyup.enter="handleQuery" style="width: 200px"/>
- </el-form-item>
- <el-form-item label="园所名称">
- <el-select
- v-model="queryParams.school_id"
- placeholder="请选择园所名称"
- clearable
- filterable
- remote
- style="width: 200px"
- >
- <el-option v-for="s in schoolList" :key="s._id" :label="s.name" :value="s._id"/>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
- <el-button icon="Refresh" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-form>
- <!-- 批量操作 -->
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button
- type="primary"
- plain
- icon="Plus"
- @click="handleAdd"
- >新增</el-button
- >
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="info"
- plain
- icon="Upload"
- @click="handleImport"
- >导入</el-button>
- </el-col>
- <right-toolbar
- v-model:showSearch="showSearch"
- @queryTable="getList"
- ></right-toolbar>
- </el-row>
- <!-- 表格 -->
- <el-table v-loading="loading" :data="userList" >
- <el-table-column type="index" label="序号" width="60" align="center"
- :index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1"/>
- <el-table-column label="姓名" prop="name" align="center"/>
- <el-table-column label="用户名" prop="user_name" align="center"/>
- <el-table-column label="性别" align="center">
- <template #default="{ row }">{{ row.gender === 1 ? '男' : row.gender === 0 ? '女' : '未知' }}</template>
- </el-table-column>
- <el-table-column label="手机号" prop="phone" align="center"/>
- <el-table-column label="园所" align="center">
- <template #default="{ row }">{{ getSchoolName(row.school_id) }}</template>
- </el-table-column>
- <el-table-column label="备注" prop="remark" align="center"/>
- <el-table-column label="操作" align="center" width="160">
- <template #default="{ row }">
- <el-button type="primary" link icon="Edit" size="small" @click="handleEdit(row)"></el-button>
- <el-button type="danger" link icon="Delete" size="small" @click="handleDelete(row)"></el-button>
- </template>
- </el-table-column>
- </el-table>
- <!-- 分页 -->
- <pagination v-if="total > 0" :total="total"
- v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
- @pagination="getList"/>
- </el-col>
- </el-row>
- <!-- 新增/编辑弹窗 -->
- <el-dialog :title="title" v-model="open" width="500px">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
- <el-form-item label="姓名" prop="name">
- <el-input v-model="form.name" placeholder="请输入姓名"/>
- </el-form-item>
- <el-form-item label="用户名" prop="user_name">
- <el-input v-model="form.user_name" placeholder="请输入用户名"/>
- </el-form-item>
- <el-form-item label="手机号" prop="phone">
- <el-input v-model="form.phone" placeholder="请输入手机号"/>
- </el-form-item>
- <el-form-item label="性别" prop="gender">
- <el-select v-model="form.gender" placeholder="请选择">
- <el-option label="男" :value="1"/>
- <el-option label="女" :value="0"/>
- </el-select>
- </el-form-item>
- <el-form-item label="园所" prop="school_id">
- <el-select
- v-model="form.school_id"
- placeholder="请选择园所名称"
- clearable
- filterable
- remote
- style="width: 200px"
- >
- <el-option v-for="s in schoolList" :key="s._id" :label="s.name" :value="s._id"/>
- </el-select>
- </el-form-item>
- <el-form-item label="备注" prop="remark">
- <el-input type="textarea" v-model="form.remark" placeholder="请输入备注"/>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button type="primary" @click="submitForm">确 定</el-button>
- <el-button @click="open=false">取 消</el-button>
- </template>
- </el-dialog>
- <!-- 用户导入对话框 -->
- <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
- <el-upload
- ref="uploadRef"
- :limit="1"
- accept=".xlsx, .xls"
- :disabled="upload.isUploading"
- :auto-upload="true"
- :before-upload="beforeUpload"
- :on-remove="handleRemove"
- drag
- >
- <el-icon class="el-icon--upload"><upload-filled /></el-icon>
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
- <template #tip>
- <div class="el-upload__tip text-center">
- <span>仅允许导入xls、xlsx格式文件。</span>
- <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
- </div>
- </template>
- </el-upload>
- </el-dialog>
- </div>
- </template>
- <script setup>
- import { getToken } from "@/utils/auth";
- import { ref, reactive, toRefs, getCurrentInstance } from 'vue';
- const { proxy } = getCurrentInstance();
- const userList = ref([]);
- const schoolList = ref([]);
- const loading = ref(false);
- const open = ref(false);
- const title = ref('');
- const total = ref(0);
- const showSearch = ref(true);
- /*** 用户导入参数 */
- const upload = reactive({
- // 是否显示弹出层(用户导入)
- open: false,
- // 弹出层标题(用户导入)
- title: "",
- // 是否禁用上传
- isUploading: false,
- // 是否更新已经存在的用户数据
- // updateSupport: 0,
- // 设置上传的请求头部
- headers: { Authorization: "Bearer " + getToken() },
- // 上传的地址
- url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData"
- });
- const data = reactive({
- form: {},
- queryParams: { pageNum: 1, pageSize: 10, name: '', user_name:'', phone:'', school_id:'' },
- rules: {
- name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
- user_name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
- phone: [
- { required: true, message: '手机号不能为空', trigger: 'blur' },
- { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
- ],
- // gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
- school_id: [{ required: true, message: '请选择园所', trigger: 'change' }]
- }
- });
- const { queryParams, form, rules } = toRefs(data);
- /** 获取学校名称 */
- function getSchoolName(id) {
- const s = schoolList.value.find(x => x._id === id);
- return s ? s.name : '';
- }
- /** 获取用户列表 */
- async function getList() {
- loading.value = true;
- const filter = { where: { delete: 0 } };
- if(queryParams.value.name) filter.where.name = queryParams.value.name;
- if(queryParams.value.user_name) filter.where.user_name = queryParams.value.user_name;
- if(queryParams.value.phone) filter.where.phone = queryParams.value.phone;
- if(queryParams.value.school_id) filter.where.school_id = queryParams.value.school_id;
- const res = await proxy.$models.wx_teacher_user.list({
- filter,
- pageNumber: queryParams.value.pageNum,
- pageSize: queryParams.value.pageSize,
- getCount: true,
- envType: 'prod'
- });
- userList.value = res.data.records || [];
- total.value = res.data.total || 0;
- loading.value = false;
- }
- /** 获取学校列表 */
- async function getSchoolList() {
- const res = await proxy.$models.wx_school.list({ filter:{}, envType:'prod' });
- schoolList.value = res.data.records || [];
- }
- /** 搜索 */
- function handleQuery() { queryParams.value.pageNum = 1; getList(); }
- /** 重置 */
- function resetQuery() {
- queryParams.value = { pageNum: 1, pageSize: 10, name: '', user_name:'', phone:'', school_id:'' };
- getList();
- }
- /** 新增 */
- function handleAdd() { form.value = {}; open.value = true; title.value = '新增教师'; }
- /** 编辑 */
- function handleEdit(row) { form.value = { ...row }; open.value = true; title.value = '编辑教师'; }
- /** 删除 */
- async function handleDelete(row) {
- try {
- await proxy.$modal.confirm(`是否确认删除 ${row.name} ?`);
- await proxy.$models.wx_teacher_user.update({
- filter: { where: { _id: { $eq: row._id } } },
- data: { delete: 1 },
- envType: 'prod'
- });
- proxy.$modal.msgSuccess('删除成功');
- getList();
- } catch(err) {}
- }
- /** 提交表单 */
- async function submitForm() {
- await proxy.$refs.formRef.validate();
- if(form.value._id){
- await proxy.$models.wx_teacher_user.update({ data: form.value, filter:{ where:{ _id: { $eq: form.value._id } } }, envType:'prod' });
- proxy.$modal.msgSuccess('修改成功');
- } else {
- await proxy.$models.wx_teacher_user.create({ data: form.value, envType:'prod' });
- proxy.$modal.msgSuccess('新增成功');
- }
- open.value = false;
- getList();
- }
- /** 导入按钮操作 */
- function handleImport() {
- upload.title = "用户导入";
- upload.open = true;
- };
- /** 下载模板操作 */
- async function importTemplate() {
- try {
- // 获取存储中的模板文件下载地址
- const res = await proxy.$apps
- // .storage()
- .getTempFileURL({
- fileList: ["cloud://honghgaier-5guiffgcf17a2eea.686f-honghgaier-5guiffgcf17a2eea-1373037829/teachermoban.xlsx"], // 云存储里的路径
- });
- console.log(res.fileList[0].tempFileURL, 'res.fileList[0].tempFileURL');
- const fileUrl = res.fileList[0].tempFileURL;
- // 触发浏览器下载
- const a = document.createElement("a");
- a.href = fileUrl;
- a.download = `system_teacher_${Date.now()}.xlsx`;
- a.click();
- } catch (err) {
- proxy.$modal.msgError("下载失败");
- }
- };
- /** 上传前处理(改用腾讯云存储) */
- async function beforeUpload(file) {
- upload.isUploading = true;
- try {
- // 1. file 就是原生 File 对象
- console.log(file, '上传文件对象');
- if (!(file instanceof File)) {
- throw new Error('请选择本地 Excel 文件上传');
- }
- // 2. 安全文件名
- const safeFileName = file.name.replace(/[^a-zA-Z0-9_.-]/g, '_');
- const cloudPath = `excel/teacher/${Date.now()}_${safeFileName}`;
- // 3. 上传文件
- const res = await proxy.$apps.uploadFile({
- cloudPath,
- filePath: file
- });
- console.log('上传成功 fileID:', res.fileID);
- // 4. 调用云函数解析
- const cloudResult = await proxy.$apps.callFunction({
- name: "teacherexcel",
- data: { fileID: res.fileID }
- });
- console.log('云函数返回:', cloudResult);
- const fnResult = cloudResult.result || cloudResult;
- if (fnResult.code === 0) {
- proxy.$modal.msgSuccess('导入成功');
- upload.open = false;
- getList();
- } else {
- proxy.$modal.msgError('导入失败:' + (fnResult.msg || '未知错误'));
- }
- } catch (err) {
- console.error('上传失败:', err);
- proxy.$modal.msgError('上传失败: ' + err.message);
- } finally {
- upload.isUploading = false;
- }
- return false; // 阻止默认上传
- }
- /** 移除文件 */
- function handleRemove(file) {
- console.log("文件移除:", file);
- }
- // /**文件上传中处理 */
- // const handleFileUploadProgress = (event, file, fileList) => {
- // upload.isUploading = true;
- // };
- // /** 文件上传成功处理 */
- // const handleFileSuccess = (response, file, fileList) => {
- // upload.open = false;
- // upload.isUploading = false;
- // proxy.$refs["uploadRef"].handleRemove(file);
- // proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
- // getList();
- // };
- // /** 提交上传文件 */
- // function submitFileForm() {
- // proxy.$refs["uploadRef"].submit();
- // };
- getSchoolList();
- getList();
- </script>
- <style scoped lang="scss">
- .app-container{ padding: 20px; }
- </style>
|