解决BLOB/TEXT column can't have a default value query问题

本文介绍了在MySQL中遇到BLOB/TEXT类型字段设置默认值时出现的问题及解决方法。主要通过调整MySQL的工作模式来允许这些类型字段使用默认值。

转载自:http://www.sharkuo.com/BLOB-TEXT-column-cannot-have-a-default-value-query

Create table的时候,报错BLOB/TEXT column 'xxxxxx(表名称)' can't have a default value query,意思是TEXT类型的表字段不能够有默认值。

搜索到很多解决方案都是将

description TEXT DEFAULT 'www.sharkuo.com', 改为 description TEXT,

原因在于:

1、  MYSQL5.x是不允许BLOB/TEXT类型的字段拥有默认值的。

2、  由于MYSQL是在‘strict mode’严格模式下工作的,如果改为非严格模式,上面的语句就可以执行成功

3、  MYSQL5.x在windows下是默认以‘strict mode’工作的,当执行上面的语句时,会给你一个错误或者警告信息

解决方法:

1、  找到mysql安装根目录下的my.ini文件

2、  找到这样一行:
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

3、  在其前面加‘#’将其注释掉:

#sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

4、  重启mysql服务

5、  重新执行你的mysql语句

转载于:https://www.cnblogs.com/sharkuo/archive/2011/03/01/1968175.html

<template> <a-card :bordered="false" :class="{isShowStyle: indirectFlag}"> <!-- 查询区域 --> <div class="table-page-search-wrapper" v-if="!indirectFlag"> <a-form layout="inline" @keyup.enter.native="searchQuery"> <a-row :gutter='24'> <a-col :span='8'> <a-form-item label='主机厂'> <a-input v-model.trim='queryParam.oems' placeholder='请输入主机厂名称'></a-input> </a-form-item> </a-col> <a-col :span='8'> <a-form-item label='客户名称'> <a-input v-model.trim='queryParam.endUser' placeholder='请输入客户名称'></a-input> </a-form-item> </a-col> <a-col :span='8'> <span style='float: left;overflow: hidden;' class='table-page-search-submitButtons'> <a-button type='primary' @click='searchQuery' icon='search'>查询</a-button> <a-button type='primary' @click='reset' icon='reload' style='margin-left: 8px'>重置</a-button> </span> </a-col> </a-row> </a-form> </div> <!-- 查询区域-END --> <!-- 操作按钮区域 --> <div class="table-operator"> <!-- <a-button @click="handleAdd" type="primary" icon="plus" v-if="indirectModal" :disabled="hiddenFlag">新增--> <!-- </a-button>--> <a-upload v-if="!hiddenFlag" name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel"> <a-button type="primary" icon="import" :disabled="hiddenFlag">导入</a-button> </a-upload> <!-- <a-button icon='link' type='primary' @click='outmb' v-if="indirectModal" :disabled="hiddenFlag">--> <!-- 导入模板--> <!-- </a-button>--> <a-button icon='link' type='primary' @click='outmb1' :disabled="hiddenFlag"> 导入模板 </a-button> <a-button type="primary" @click="bacthSave" v-if="indirectModal" :disabled="hiddenFlag">保存</a-button> <a-button type="primary" @click="subStatus" v-if="indirectModal" :disabled="hiddenFlag">提交</a-button> <a-dropdown v-if='selectedRowKeys.length > 0'> <a-menu slot='overlay'> <a-menu-item key='1' @click='batchDelete'> <a-icon type='delete' /> 删除 </a-menu-item> </a-menu> <a-button style='margin-left: 8px'> 批量操作 <a-icon type='down' /> </a-button> </a-dropdown> </div> <!-- table区域-begin --> <div> <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">--> <!-- <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a--> <!-- style="font-weight: 600">{{ selectedRowKeys.length }}</a>项--> <!-- <a style="margin-left: 24px" @click="onClearSelected">清空</a>--> <!-- </div>--> <j-editable-table v-if="indirectModal" ref="editableTable" size="middle" bordered rowKey="id" :columns="dynamicColumns" :dataSource="dataSource" :rowNumber="true" :pagination="ipagination" :loading="loading" :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" class="j-table-force-nowrap" :actionButton="true" :disabledRows="{ status:1}" @change="handleTableChange"> <template v-slot:oemsSlot="props"> <a-input v-model='props.text' placeholder='请输入主机厂' :disabled="isDisabled(props)" @input="oemsInput(props)"> <a-icon slot='prefix' type='cluster' @click.stop='handleOemsClick(props)'/> </a-input> </template> <template v-slot:productSearchSlot="props"> <a-select v-model="props.text" show-search placeholder="请选择产品名称" :default-active-first-option="false" :show-arrow="false" :filter-option="false" :not-found-content="null" style="width: 100%" @search="handleProductSearch" @change="handleProductChange(props)" > <a-select-option v-for="item in productList" :key="item.value" :value="item.value"> {{ item.text }} </a-select-option> </a-select> </template> <template v-slot:productSlot="props"> <j-search-select-tag v-model="props.text" placeholder="请选择产品名称" dict="bs_inventory GROUP BY cInvName, cInvName, cInvName" /> </template> <template v-slot:publishSlot="props"> <div> <a-input-search v-model="props.text" placeholder="请先选择用户" readOnly unselectable="on" @search="onSearchDepUser(props)"> <a-button slot="enterButton" :disabled="false">选择用户</a-button> </a-input-search> <j-select-user-by-dep-modal ref="selectModal" modal-width="80%" :multi="false" @ok="selectOK" :user-ids="props.value" @initComp="initComp"/> </div> </template> <span slot='titleSlot' slot-scope='text'> <j-ellipsis :value='text' :length='40'/> </span> </j-editable-table> <a-table v-else ref="table" size="middle" bordered rowKey="id" :columns="columns" :dataSource="dataSource" :pagination="ipagination" :loading="loading" :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" class="j-table-force-nowrap" @change="handleTableChange"> <span slot='titleSlot' slot-scope='text'> <j-ellipsis :value='text' :length='40'/> </span> <span slot="action" slot-scope="text, record"> <a @click="handleEdit(record)" :disabled="!record.editBtn">编辑</a> <a-divider type="vertical"/> <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)"> <a :disabled="!record.editBtn">删除</a> </a-popconfirm> </span> </a-table> </div> <indirectBusinessProducts-modal ref="modalForm" :indirectModal="indirectModal" @ok="modalFormOk"></indirectBusinessProducts-modal> <indirectBusinessProducts-item-modal ref="modalItemForm" @ok="modalFormOk"></indirectBusinessProducts-item-modal> <a-modal title='客户名称(主机厂)' :width='1000' :visible='cusVisible' @ok='handleCusSubmit' @cancel='closeCusModal' cancelText='关闭'> <cus-component ref='cusComponent'></cus-component> </a-modal> </a-card> </template> <script> import '@/assets/less/TableExpand.less' import {mixinDevice} from '@/utils/mixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin' import IndirectBusinessProductsModal from './modules/IndirectBusinessProductsModal' import JEllipsis from "../../../components/jeecg/JEllipsis.vue"; import IndirectBusinessProductsItemModal from "./modules/IndirectBusinessProductsItemModal.vue"; import {deleteAction, downFile, getAction, postAction, putAction} from "../../../api/manage"; import {filterDictText, initDictOptions} from '@/components/dict/JDictSelectUtil' import {FormTypes} from '@/utils/JEditableTableUtil' import JEditableTable from "@comp/jeecg/JEditableTable.vue"; import CusComponent from "@views/modules/eoa/plan/components/CusComponent.vue"; import JSelectUserByDep from "@comp/jeecgbiz/JSelectUserByDep.vue"; import JSelectUserByDepModal from "@comp/jeecgbiz/modal/JSelectUserByDepModal.vue"; import JSearchSelectTag from "@comp/dict/JSearchSelectTag.vue"; export default { name: "IndirectBusinessProductsList", mixins: [JeecgListMixin, mixinDevice], components: { JSearchSelectTag, JSelectUserByDepModal, JSelectUserByDep, CusComponent, JEditableTable, IndirectBusinessProductsItemModal, JEllipsis, IndirectBusinessProductsModal }, props: { indirectFlag: { type: Boolean, default: false }, indirectModal: { type: Object, default: () => { } }, hiddenFlag: { type: Boolean, default: false }, }, data() { return { usernames: null, value: null, userIds: null, description: 'indirect_business_products管理页面', statusDictOptions: [], busType: 'my', cusVisible: false, // 表头 columns: [ { title: '#', dataIndex: '', key: 'rowIndex', width: 60, align: "center", customRender: function (t, r, index) { return parseInt(index) + 1; } }, // { // title: '客户名称(主机厂)', // align: "center", // dataIndex: 'oems' // }, { title: '客户名称', align: "center", dataIndex: 'endUser' }, { title: '终端用户', align: "center", dataIndex: 'oems', scopedSlots: {customRender: 'titleSlot'}, width: 100 }, { title: '车型(米)', align: "center", dataIndex: 'carType', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.vehicleModelOptions, text); } }, { title: '产品明细', align: "center", scopedSlots: {customRender: 'titleSlot'}, dataIndex: 'productDetails' }, { title: '发布数量', align: "center", dataIndex: 'number' }, { title: '预测金额', align: "center", dataIndex: 'redictedAmount' }, { title: '发布人', align: "center", dataIndex: 'publishName' }, { title: '发布时间', align: "center", dataIndex: 'publishTime', customRender: function (text) { return !text ? "" : (text.length > 10 ? text.substr(0, 10) : text) } }, { title: '产品类型', align: "center", dataIndex: 'productType', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.productTypeOptions, text); } }, // { // title: '产品大类', // align: "center", // dataIndex: 'productCategories' // }, { title: '提交状态', align: "center", dataIndex: 'status', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.statusDictOptions, text); } }, { title: '操作', dataIndex: 'action', align: "center", // fixed:"right", width: 147, scopedSlots: {customRender: 'action'} } ], url: { list: "/indirect_business/products/list", delete: "/indirect_business/products/delete", deleteBatch: "/indirect_business/products/deleteBatch", setStatus: "/indirect_business/products/setStatus", batchAdd: "/indirect_business/products/batchAdd", teamExcelTemplate: "indirect_business/indirectBusiness/teamExcelTemplate", teamExcelTemplateProduct: "indirect_business/indirectBusiness/teamExcelTemplateProduct", importExcelUrl: "indirect_business/products/importExcel", }, dictOptions: {}, queryParam:{ status:'1' }, productList: [],//储存产品信息列表 currentClickRowId: null, // 存储当前点击的行ID } }, computed: { importExcelUrl: function () { if (!this.indirectModal) { return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`; } else { return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}?busId=${this.indirectModal.busId}&endUser=${this.indirectModal.endCustomer}`; } }, getLoginUsername() { return this.$store.getters.userInfo.username; }, loginPermissions() { return this.indirectModal.helpPerson.includes(this.$store.getters.userInfo.username); }, rowSelection() { return { onChange: (selectedRowKeys, selectedRows) => { this.onSelectChange(selectedRowKeys, selectedRows); }, getCheckboxProps: record => ({ props: { disabled: record.status === 1 || record.status === null }, }), }; }, dynamicColumns() { const baseColumns = [ { title: "busId", align: "center", key: "busId", type: FormTypes.hidden, defaultValue: this.indirectModal.busId }, // 动态客户名称列 { title: this.indirectModal.category === '1' ? '客户名称' : '终端客户名称', align: "center", key: 'endUser', type: FormTypes.input, placeholder: '请输入客户名称', disabled: true, defaultValue: this.indirectModal.endCustomer, width: '220px' } ]; if (this.indirectModal.category === '2'){ baseColumns.push({ title: '主机厂', align: "center", key: 'oems', placeholder: "请选择主机厂", type: FormTypes.slot, slotName: 'oemsSlot', validateRules: this.indirectModal.category === '2' ? [ { required: true, message: '主机厂不能为空' }, { validator: (rule, value, callback) => { if (value === '' || value === null || value === undefined) { callback(new Error('请选择主机厂')); // 配合 required 使用 } } } ] : [], width: '220px', }); } baseColumns.push({ title: '车型(米)', align: "center", key: 'carType', type: FormTypes.select, dictCode: 'vehicle_model', placeholder: '请选择车型', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.vehicleModelOptions, text); }, width: '150px' }) baseColumns.push({ title: '产品名称', align: "center", key: 'productDetails', placeholder: "请选择产品名称", type: FormTypes.slot, slotName: 'productSearchSlot', width: '240px' }) baseColumns.push({ title: '发布数量', align: "center", key: 'number', type: FormTypes.input, inputType: 'number', placeholder: "请输入发布数量", validateRules: [ { pattern: /^[1-9]\d*$/, // 正整数正则 message: '发布数量必须是正整数' } ], width: '150px' }) baseColumns.push({ title: '预测金额', align: "center", key: 'redictedAmount', type: FormTypes.input, inputType: 'number', placeholder: "请输入预测金额", // 动态校验规则(category == '2' 时必填且必须为正数) validateRules: this.indirectModal.category === '2' ? [ { required: true, message: '预测金额不能为空', trigger: ['blur', 'change'] // 触发校验的时机 }, { pattern: /^(0|[1-9]\d*)(\.\d+)?$/, // 正整数正则 message: '发布数量必须是正数' } ] : [], width: '150px' }) if (this.indirectModal.category === '2'){ baseColumns.push({ title: '主机厂负责人', align: "center", key: 'oemResponsiblePerson', type: FormTypes.hidden, }); } // if (this.indirectModal.category === '2'){ // baseColumns.push({ // title: '主机厂负责人', // align: "center", // key: 'oemResponsiblePersonName', // type: FormTypes.input, // disabled: true, // width: '200px' // }); // } baseColumns.push({ title: '发布人', align: "center", key: 'publishBy', type: FormTypes.hidden, defaultValue: this.$store.getters.userInfo.username, placeholder: "请选择发布人", width: '240px' }) baseColumns.push({ title: '发布人', align: "center", key: 'publishName', type: FormTypes.slot, slotName: 'publishSlot', defaultValue: this.$store.getters.userInfo.realname, placeholder: "请选择发布人", width: '240px' }) baseColumns.push({ title: '发布时间', align: "center", key: 'publishTime', type: FormTypes.date, customRender: function (text) { return !text ? "" : (text.length > 10 ? text.substr(0, 10) : text) }, defaultValue: this.formatDate(new Date()), width: '170px' }) baseColumns.push({ title: '产品类型', align: "center", key: 'productType', placeholder: "请选择产品类型", type: FormTypes.select, dictCode: 'product_type', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.productTypeOptions, text); }, defaultValue: '0', width: '130px' }) baseColumns.push({ title: '提交状态', align: "center", key: 'status', type: FormTypes.select, dictCode: 'public_status', customRender: (text, record, index) => { //字典值替换通用方法 return filterDictText(this.statusDictOptions, text); }, defaultValue: '0', disabled: true, width: '130px' }) return baseColumns; }, }, methods: { initDictConfig() { getAction('/base/bsInventory/distinctAllList',null).then((res) => { if (res.success) { this.productList = res.result.map(item => ({ text: item.cinvname, value: item.cinvname })) } }) //判断查询条件 if (!this.indirectModal){ this.queryParam.status = 1 this.loadData(1) }else{ this.queryParam.busId = this.indirectModal.busId this.queryParam.status = '' this.loadData(1) } console.log('this.queryParam.status',this.queryParam.status) initDictOptions('public_status').then((res) => { if (res.success) { this.statusDictOptions = res.result } }) initDictOptions('vehicle_model').then((res) => { if (res.success) { this.vehicleModelOptions = res.result } }) initDictOptions('product_type').then((res) => { if (res.success) { this.productTypeOptions = res.result } }) }, // 产品名称远程搜索 handleProductSearch(value) { if (!value) return; // 空输入不查询 // 调用接口查询匹配的产品 getAction('/base/bsInventory/distinctAllList', { 'cinvname': value }).then(res => { if (res.success) { this.productList = res.result.map(item => ({ text: item.cinvname, value: item.cinvname })); } }); }, handleProductChange(props) { // 存储当前点击的行记录和ID this.currentClickRowId = props.rowId; this.$refs.editableTable.setValues([{ rowKey: this.currentClickRowId, values: { 'productDetails': props.text } }]); }, outmb() { downFile(this.url.teamExcelTemplate, '').then((res) => { if (!res) { this.$message.warning('文件下载失败') return } let blob = new Blob([res], {type: 'application/vnd.ms-excel'}) let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob) // 创建下载的链接 downloadElement.href = href downloadElement.download = '间接销售登记表导入模板.xls' // 下载后文件名 document.body.appendChild(downloadElement) downloadElement.click() // 点击下载 document.body.removeChild(downloadElement) // 下载完成移除元素 window.URL.revokeObjectURL(href) // 释放掉blob对象 }) }, outmb1() { downFile(this.url.teamExcelTemplateProduct, '').then((res) => { if (!res) { this.$message.warning('文件下载失败') return } let blob = new Blob([res], {type: 'application/vnd.ms-excel'}) let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob) // 创建下载的链接 downloadElement.href = href downloadElement.download = '间接销售登记导入模板.xlsx' // 下载后文件名 document.body.appendChild(downloadElement) downloadElement.click() // 点击下载 document.body.removeChild(downloadElement) // 下载完成移除元素 window.URL.revokeObjectURL(href) // 释放掉blob对象 }) }, subStatus(){ const ids = this.$refs.editableTable.getSelection() if (ids.length==0){ this.$message.warn("请选择一条记录") return; } const selectedRow = this.$refs.editableTable.getValuesSync({rowIds: ids}).values selectedRow.forEach(item => { if (item.status == "1"){ this.$message.warn("请选择未提交的数据") return; } }) let that = this that.$confirm({ title: '提示', content: '确认提交吗?', onOk: function() { putAction(that.url.setStatus, selectedRow).then((res) => { if (res.success) { that.$message.success(res.message); that.loadData(); that.onClearSelected(); } else { that.$message.warning(res.message); that.loadData(); } }) } }) }, bacthSave() { this.$refs.editableTable.getValues(error => { if (error === 0) { let that = this postAction(that.url.batchAdd, this.$refs.editableTable.getValuesSync().values).then((res) => { if (res.success) { that.$message.success(res.message); that.loadData(); } else { that.$message.warning(res.message); that.loadData(); } }) } else { this.$message.error('验证未通过') } }) }, reset(){ this.queryParam = {status:'1'} this.loadData() }, batchDelete: function () { if(!this.url.deleteBatch){ this.$message.error("请设置url.deleteBatch属性!") return } if (this.selectedRowKeys.length <= 0) { this.$message.warning('请选择一条记录!'); return; } else if (this.selectionRows.some(item => item.status != 0)) { this.$message.warning('请选择未提交记录!') return; } else { var ids = ""; for (var a = 0; a < this.selectedRowKeys.length; a++) { ids += this.selectedRowKeys[a] + ","; } var that = this; this.$confirm({ title: "确认删除", content: "是否删除选中数据?", onOk: function () { that.loading = true; deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => { if (res.success) { that.$message.success(res.message); that.loadData(); that.onClearSelected(); } else { that.$message.warning(res.message); } }).finally(() => { that.loading = false; }); } }); } }, handleCusSubmit() { if (!this.$refs.cusComponent.selectionRows || this.$refs.cusComponent.selectionRows.length === 0) { this.$message.warning('请选择一条记录') return false } var customerNames = ""; var oemResponsiblePerson = ""; var oemResponsiblePersonName = ""; for (var a = 0; a < this.$refs.cusComponent.selectedRowRecords.length; a++) { customerNames += this.$refs.cusComponent.selectedRowRecords[a].customerName + ","; if (this.$refs.cusComponent.selectedRowRecords[a].responsiblePerson !== null) { oemResponsiblePerson += this.$refs.cusComponent.selectedRowRecords[a].responsiblePerson + ","; } if (this.$refs.cusComponent.selectedRowRecords[a].responsiblePersonName!==null){ oemResponsiblePersonName += this.$refs.cusComponent.selectedRowRecords[a].responsiblePersonName + ","; } } const oems = customerNames.substr(0,customerNames.length-1) const oemResponsiblePersons = oemResponsiblePerson.substr(0,oemResponsiblePerson.length-1) const oemResponsiblePersonNames = oemResponsiblePersonName.substr(0,oemResponsiblePersonName.length-1) // 找到当前点击的行并更新数据 this.$refs.editableTable.setValues( [{ rowKey: this.currentClickRowId, values: { 'oems': oems, 'oemResponsiblePerson': oemResponsiblePersons, 'oemResponsiblePersonName': oemResponsiblePersonNames, } }] ) this.closeCusModal() }, oemsInput(props) { // 存储当前点击的行记录和ID this.currentClickRowId = props.rowId; // 找到当前点击的行并更新数据 this.$refs.editableTable.setValues( [{ rowKey: this.currentClickRowId, values: { 'oems': props.text } }] ) }, handleOemsClick(props) { console.log("主机厂",this.$refs.editableTable.getValues({rowIds: props.rowId})) // 存储当前点击的行记录和ID this.currentClickRowId = props.rowId; this.openCusModal(); // 直接打开弹窗 }, openCusModal() { this.cusVisible = true }, closeCusModal() { this.$refs.cusComponent.selectionRows = [] this.$refs.cusComponent.selectedRowKeys = [] this.$refs.cusComponent.queryParam = {} this.cusVisible = false }, formatDate(date) { const year = date.getFullYear() const month = (date.getMonth() + 1).toString().padStart(2, '0') const day = date.getDate().toString().padStart(2, '0') return `${year}-${month}-${day}` }, initComp(userNames) { this.userNames = userNames }, onSearchDepUser(props) { this.currentClickRowId = props.rowId if (this.isSelectUser) this.$refs.selectModal.queryParam.username = this.value; this.$refs.selectModal.showModal() this.$refs.selectModal.queryParam.username = ""; }, selectOK(rows, idstr) { if (!rows) { this.userNames = '' this.userIds = '' } else { let temp = '' for (let item of rows) { temp += ',' + item.realname } this.userNames = temp.substring(1) this.userIds = idstr // 找到当前点击的行并更新数据 this.$refs.editableTable.setValues( [{ rowKey: this.currentClickRowId, values: { 'publishBy': this.userIds, 'publishName': this.userNames, } }] ) } }, // 判断是否禁用 isDisabled(props){ const item = this.$refs.editableTable.getValuesSync({rowIds: [props.rowId]}) return item.values[0].status === '1' } } } </script> <style scoped> @import '~@assets/less/common.less'; .isShowStyle /deep/ .ant-card-body { padding: unset; } </style>中<template v-slot:oemsSlot="props"> <a-input v-model='props.text' placeholder='请输入主机厂' :disabled="isDisabled(props)" @input="oemsInput(props)"> <a-icon slot='prefix' type='cluster' @click.stop='handleOemsClick(props)'/> </a-input> </template>插槽的:disabled怎么使用,我想根据本条记录的status判断是否禁用
07-23
无法找到模块“file-saver”的声明文件。“G:/git/frontend/node_modules/.pnpm/file-saver@2.0.5/node_modules/file-saver/dist/FileSaver.min.js”隐式拥有 "any" 类型。 尝试使用 `npm i --save-dev @types/file-saver` (如果存在),或者添加一个包含 `declare module 'file-saver';` 的新声明(.d.ts)文件ts-plugin(7016) <!-- 班级课消 --> <template> <div class="page-content" v-loading="loading"> <el-card class="search-card"> <el-form-item label="上课日期:"> <el-radio-group class="custom-radio-group" v-model="query.timeType" @change="getData"> <el-radio-button label="本周" :value="1" /> <el-radio-button label="本月" :value="2" /> <el-radio-button label="上月" :value="3" /> <el-radio-button label="自定义" :value="4" /> <div class="w220px ml3"> <el-date-picker v-if="query.timeType == 4" type="daterange" placeholder="会议日期" value-format="YYYY-MM-DD" style="width: 100%" v-model="query.timeRange" @change="getData" /> </div> </el-radio-group> </el-form-item> <el-divider border-style="dashed" class="query-split-line" /> <el-form-item label="课程科目:"> <SubjectRadioGroup v-model="query.subject" @change="getData" /> </el-form-item> <el-divider border-style="dashed" v-if="showMore" class="query-split-line" /> <el-form-item label="更多筛选:" class="more-filter" v-show="showMore"> <el-select v-model="query.employeeType" clearable placeholder="员工类型" @change="getData" class="w-100px!"> <el-option label="全职" :value="1" /> <el-option label="兼职" :value="2" /> </el-select> <CampusSelect class="w160px!" clearable v-model="query.campusIds" multiple placeholder="上课校区" collapse-tags collapse-tags-tooltip @change="getData" /> <SemesterSelect v-model="query.semsterIds" multiple clearable placeholder="学期" @change="getData" /> <GradeSelect placeholder="年级" class="w90px!" clearable multiple v-model="query.classGrades" collapse-tags collapse-tags-tooltip @change="getData" /> <el-select placeholder="授课模式" clearable multiple v-model="query.teachType" collapse-tags collapse-tags-tooltip @change="getData"> <el-option label="班课" :value="1" /> <el-option label="1对1" :value="2" /> </el-select> <CourseTypeSelect placeholder="课程类型" clearable multiple v-model="query.teachType" collapse-tags collapse-tags-tooltip @change="getData" /> <TeacherSelect v-model="query.teacherId" placeholder="老师" clearable @change="getData" /> <el-select placeholder="课时费" clearable v-model="query.courseSalary" @change="getData"> <el-option label="有" :value="1" /> <el-option label="无" :value="0" /> </el-select> </el-form-item> <el-divider border-style="dashed" class="cursor-pointer query-split-line" @click="showMore = !showMore"> {{ showMore ? "收起" : "更多筛选" }} <el-icon> <ArrowUp v-if="showMore" /> <ArrowDown v-else /> </el-icon> </el-divider> </el-card> <CustTable v-model="fields"> <template #header> <div class="flex items-center justify-between"> <div> 共 <strong>{{ total }}</strong> 条记录 </div> <div class="flex"> <el-input v-model="query.name" placeholder="输入班级名称查询" @keyup.enter="getData"> <template #suffix> <el-icon @click="getData" class="cursor-pointer"><Search /></el-icon> </template> </el-input> <el-button class="ml-3" type="primary" @click="exportData">导出</el-button> </div> </div> </template> <el-table :data="tableData" header-cell-class-name="table-header" border> <template v-for="item in fields"> <template v-if="item.show"> <el-table-column v-if="item.label == '班级ID'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '上课日期'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '上课时间'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '教室'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '班级'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '科目'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '年级'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '授课模式'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '课程类型'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '班型'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '老师'" :key="item.label" :label="item.label" width="120"> <template #default="scope"> {{ getNames(scope.row[item.prop]).join(",") }} </template> </el-table-column> <el-table-column v-if="item.label == '教务'" :key="item.label" :label="item.label" width="120"> <template #default="scope"> {{ getNames(scope.row[item.prop]).join(",") }} </template> </el-table-column> <el-table-column v-if="item.label == '校区'" :key="item.label" :label="item.label" width="120"> <template #default="scope"> {{ getNames(scope.row[item.prop]).join(",") }} </template> </el-table-column> <el-table-column v-if="item.label == '上课方式'" :key="item.label" :label="item.label" width="120"> <template #default="scope"> <span v-if="scope.row[item.prop] === 1">线下课</span> <span v-else-if="scope.row[item.prop] === 2">录播课</span> <span v-else-if="scope.row[item.prop] === 3">直播课</span> <span v-else>未知</span> </template> </el-table-column> <el-table-column v-if="item.label == '满班数'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '应出勤·'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '实际出勤'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '计算出勤'" :key="item.label" :label="item.label" width="120"> <template #default="scope"> {{ scope.row.attendNum && scope.row.totalNum ? ((scope.row.attendNum / scope.row.totalNum) * 100).toFixed(2) + "%" : "" }} </template> </el-table-column> <el-table-column v-if="item.label == '课消金额'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '出勤课消金额'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <el-table-column v-if="item.label == '课时费'" :key="item.label" :label="item.label" :prop="item.prop" width="120" /> <!-- <el-table-column v-for="item in fields" :key="item.id" :label="item.label" :prop="item.prop" /> --> </template> </template> </el-table> <template #footer> <el-pagination v-model:current-page="query.index" v-model:page-size="query.size" :page-sizes="[5, 10, 20, 50, 100]" background layout="total, sizes, prev, pager, next, jumper" :total="total" hide-on-single-page @size-change="getData" @current-change="getData" /> </template> </CustTable> </div> </template> <script setup lang="ts"> import { WorkAPI } from "@/api/WorkAPI"; import { BaseModel, TableFields } from "@/models/Common"; import { ClassItem } from "@/models/routine/ClassGroup"; import { ClassConsumeQuery } from "@/models/work/Query"; import { useUserStore } from "@/store"; const exportLoading = ref(false); const userStore = useUserStore(); const loading = ref(false); const tableData = ref<ClassItem[]>([]); const total = ref(0); const query = ref(new ClassConsumeQuery()); const showMore = ref(true); const fields = ref([ new TableFields("班级ID", "classGroupId", true, true, true), new TableFields("上课日期", "date", true), new TableFields("上课时间", "startTime", true), new TableFields("教室", "classRoomName", true), new TableFields("班级", "classGroupName", true), new TableFields("科目", "subjectName", false), new TableFields("年级", "classGroup.grade", false), new TableFields("授课模式", "classGroup.teachType", false), new TableFields("课程类型", "", false), new TableFields("班型", "", false), new TableFields("老师", "teachers", true), new TableFields("教务", "assistants", true), new TableFields("校区", "classGroup.campusIds", true), new TableFields("上课方式", "classGroup.teachMethod", false), new TableFields("满班数", "fullCount", false), new TableFields("应出勤", "totalNum", true), new TableFields("实际出勤", "attendNum", true), new TableFields("计算出勤", "", true), new TableFields("课消金额", "", true, true, true), new TableFields("出勤课消金额", "", true, true, true), new TableFields("课时费", "", true, true, true), ]); async function getData() { loading.value = true; // const res = await WorkAPI.getData(); loading.value = false; // tableData.value = Array.isArray(res.records) ? res.records : []; // total.value = res.totalRecords || 0; } const exportData = async () => { exportLoading.value = true; // 确保有数据可导出 if (tableData.value.length === 0) { ElMessage.warning("没有数据可导出"); return; } // 动态导入xlsx和file-saver库 const XLSX = await import("xlsx"); const { saveAs } = await import("file-saver"); // 准备导出数据 const exportData = tableData.value.map((item) => { const row: any = {}; // 只处理显示的字段 fields.value .filter((field) => field.show) .forEach((field) => { if (!field.prop) return; // 处理嵌套属性 let value = field.prop.includes(".") ? field.prop.split(".").reduce((obj: any, key) => obj?.[key], item) : item[field.prop as keyof ClassItem]; // 特殊字段处理 switch (field.label) { case "老师": case "教务": case "校区": value = Array.isArray(value) ? getNames(value as string[]).join(", ") : value; break; case "上课方式": value = value === 1 ? "线下课" : value === 2 ? "录播课" : value === 3 ? "直播课" : "未知"; break; case "计算出勤": value = item.attendNum && item.totalNum ? ((item.attendNum / item.totalNum) * 100).toFixed(2) + "%" : "0%"; break; case "课消金额": case "出勤课消金额": case "课时费": if (typeof value === "number") { value = `¥${value.toLocaleString()}`; } break; } row[field.label] = value; }); return row; }); // 创建工作簿和工作表 const wb = XLSX.utils.book_new(); const ws = XLSX.utils.json_to_sheet(exportData); // 添加工作表到工作簿 XLSX.utils.book_append_sheet(wb, ws, "课消数据"); // 生成Excel文件 const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" }); // 创建Blob并下载 const blob = new Blob([wbout], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); // 生成文件名(包含日期时间) const now = new Date(); const dateStr = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, "0")}${now.getDate().toString().padStart(2, "0")}`; const timeStr = `${now.getHours().toString().padStart(2, "0")}${now.getMinutes().toString().padStart(2, "0")}`; saveAs(blob, `课消数据_${dateStr}_${timeStr}.xlsx`); ElMessage.success(`已成功导出${tableData.value.length}条数据`); exportLoading.value = false; }; function getNames(row: string[]) { return row?.map((r) => userStore.userNameMap.get(parseInt(r))) ?? []; } onMounted(() => { getData(); }); </script> <style lang="scss" scoped></style>
08-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值