同步 ruoyi-vue-pro 差异代码
parent
16c303bc28
commit
f8991ba134
|
@ -0,0 +1,598 @@
|
||||||
|
package liquibase.database.core;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import liquibase.CatalogAndSchema;
|
||||||
|
import liquibase.Scope;
|
||||||
|
import liquibase.database.AbstractJdbcDatabase;
|
||||||
|
import liquibase.database.DatabaseConnection;
|
||||||
|
import liquibase.database.OfflineConnection;
|
||||||
|
import liquibase.database.jvm.JdbcConnection;
|
||||||
|
import liquibase.exception.DatabaseException;
|
||||||
|
import liquibase.exception.UnexpectedLiquibaseException;
|
||||||
|
import liquibase.exception.ValidationErrors;
|
||||||
|
import liquibase.executor.ExecutorService;
|
||||||
|
import liquibase.statement.DatabaseFunction;
|
||||||
|
import liquibase.statement.SequenceCurrentValueFunction;
|
||||||
|
import liquibase.statement.SequenceNextValueFunction;
|
||||||
|
import liquibase.statement.core.RawCallStatement;
|
||||||
|
import liquibase.statement.core.RawSqlStatement;
|
||||||
|
import liquibase.structure.DatabaseObject;
|
||||||
|
import liquibase.structure.core.Catalog;
|
||||||
|
import liquibase.structure.core.Index;
|
||||||
|
import liquibase.structure.core.PrimaryKey;
|
||||||
|
import liquibase.structure.core.Schema;
|
||||||
|
import liquibase.util.JdbcUtils;
|
||||||
|
import liquibase.util.StringUtil;
|
||||||
|
|
||||||
|
public class DmDatabase extends AbstractJdbcDatabase {
|
||||||
|
private static final String PRODUCT_NAME = "DM DBMS";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDefaultDatabaseProductName() {
|
||||||
|
return PRODUCT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this AbstractDatabase subclass the correct one to use for the given connection.
|
||||||
|
*
|
||||||
|
* @param conn
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
|
||||||
|
return PRODUCT_NAME.equalsIgnoreCase(conn.getDatabaseProductName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this database understands the given url, return the default driver class name. Otherwise return null.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getDefaultDriver(String url) {
|
||||||
|
if(url.startsWith("jdbc:dm")) {
|
||||||
|
return "dm.jdbc.driver.DmDriver";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an all-lower-case short name of the product. Used for end-user selecting of database type
|
||||||
|
* such as the DBMS precondition.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getShortName() {
|
||||||
|
return "dm";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getDefaultPort() {
|
||||||
|
return 5236;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this database support initially deferrable columns.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsInitiallyDeferrableColumns() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsTablespaces() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return PRIORITY_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern PROXY_USER = Pattern.compile(".*(?:thin|oci)\\:(.+)/@.*");
|
||||||
|
|
||||||
|
protected final int SHORT_IDENTIFIERS_LENGTH = 30;
|
||||||
|
protected final int LONG_IDENTIFIERS_LEGNTH = 128;
|
||||||
|
public static final int ORACLE_12C_MAJOR_VERSION = 12;
|
||||||
|
|
||||||
|
private Set<String> reservedWords = new HashSet<>();
|
||||||
|
private Set<String> userDefinedTypes;
|
||||||
|
private Map<String, String> savedSessionNlsSettings;
|
||||||
|
|
||||||
|
private Boolean canAccessDbaRecycleBin;
|
||||||
|
private Integer databaseMajorVersion;
|
||||||
|
private Integer databaseMinorVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for an object that represents the Oracle Database DBMS.
|
||||||
|
*/
|
||||||
|
public DmDatabase() {
|
||||||
|
super.unquotedObjectsAreUppercased = true;
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
super.setCurrentDateTimeFunction("SYSTIMESTAMP");
|
||||||
|
// Setting list of Oracle's native functions
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
dateFunctions.add(new DatabaseFunction("SYSDATE"));
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
dateFunctions.add(new DatabaseFunction("SYSTIMESTAMP"));
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
dateFunctions.add(new DatabaseFunction("CURRENT_TIMESTAMP"));
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
super.sequenceNextValueFunction = "%s.nextval";
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
super.sequenceCurrentValueFunction = "%s.currval";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tryProxySession(final String url, final Connection con) {
|
||||||
|
Matcher m = PROXY_USER.matcher(url);
|
||||||
|
if (m.matches()) {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put("PROXY_USER_NAME", m.group(1));
|
||||||
|
try {
|
||||||
|
Method method = con.getClass().getMethod("openProxySession", int.class, Properties.class);
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(con, 1, props);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Scope.getCurrentScope().getLog(getClass()).info("Could not open proxy session on OracleDatabase: " + e.getCause().getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDatabaseMajorVersion() throws DatabaseException {
|
||||||
|
if (databaseMajorVersion == null) {
|
||||||
|
return super.getDatabaseMajorVersion();
|
||||||
|
} else {
|
||||||
|
return databaseMajorVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDatabaseMinorVersion() throws DatabaseException {
|
||||||
|
if (databaseMinorVersion == null) {
|
||||||
|
return super.getDatabaseMinorVersion();
|
||||||
|
} else {
|
||||||
|
return databaseMinorVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcCatalogName(CatalogAndSchema schema) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcSchemaName(CatalogAndSchema schema) {
|
||||||
|
return correctObjectName((schema.getCatalogName() == null) ? schema.getSchemaName() : schema.getCatalogName(), Schema.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getAutoIncrementClause(final String generationType, final Boolean defaultOnNull) {
|
||||||
|
if (StringUtil.isEmpty(generationType)) {
|
||||||
|
return super.getAutoIncrementClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
String autoIncrementClause = "GENERATED %s AS IDENTITY"; // %s -- [ ALWAYS | BY DEFAULT [ ON NULL ] ]
|
||||||
|
String generationStrategy = generationType;
|
||||||
|
if (Boolean.TRUE.equals(defaultOnNull) && generationType.toUpperCase().equals("BY DEFAULT")) {
|
||||||
|
generationStrategy += " ON NULL";
|
||||||
|
}
|
||||||
|
return String.format(autoIncrementClause, generationStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generatePrimaryKeyName(String tableName) {
|
||||||
|
if (tableName.length() > 27) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
return "PK_" + tableName.toUpperCase(Locale.US).substring(0, 27);
|
||||||
|
} else {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
return "PK_" + tableName.toUpperCase(Locale.US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReservedWord(String objectName) {
|
||||||
|
return reservedWords.contains(objectName.toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSequences() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oracle supports catalogs in liquibase terms
|
||||||
|
*
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportsSchemas() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getConnectionCatalogName() throws DatabaseException {
|
||||||
|
if (getConnection() instanceof OfflineConnection) {
|
||||||
|
return getConnection().getCatalog();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
return Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForObject(new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"), String.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
Scope.getCurrentScope().getLog(getClass()).info("Error getting default schema", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDefaultCatalogName() {//NOPMD
|
||||||
|
return (super.getDefaultCatalogName() == null) ? null : super.getDefaultCatalogName().toUpperCase(Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Returns an Oracle date literal with the same value as a string formatted using ISO 8601.</p>
|
||||||
|
*
|
||||||
|
* <p>Convert an ISO8601 date string to one of the following results:
|
||||||
|
* to_date('1995-05-23', 'YYYY-MM-DD')
|
||||||
|
* to_date('1995-05-23 09:23:59', 'YYYY-MM-DD HH24:MI:SS')</p>
|
||||||
|
* <p>
|
||||||
|
* Implementation restriction:<br>
|
||||||
|
* Currently, only the following subsets of ISO8601 are supported:<br>
|
||||||
|
* <ul>
|
||||||
|
* <li>YYYY-MM-DD</li>
|
||||||
|
* <li>YYYY-MM-DDThh:mm:ss</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getDateLiteral(String isoDate) {
|
||||||
|
String normalLiteral = super.getDateLiteral(isoDate);
|
||||||
|
|
||||||
|
if (isDateOnly(isoDate)) {
|
||||||
|
return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD')";
|
||||||
|
} else if (isTimeOnly(isoDate)) {
|
||||||
|
return "TO_DATE(" + normalLiteral + ", 'HH24:MI:SS')";
|
||||||
|
} else if (isTimestamp(isoDate)) {
|
||||||
|
return "TO_TIMESTAMP(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS.FF')";
|
||||||
|
} else if (isDateTime(isoDate)) {
|
||||||
|
int seppos = normalLiteral.lastIndexOf('.');
|
||||||
|
if (seppos != -1) {
|
||||||
|
normalLiteral = normalLiteral.substring(0, seppos) + "'";
|
||||||
|
}
|
||||||
|
return "TO_DATE(" + normalLiteral + ", 'YYYY-MM-DD HH24:MI:SS')";
|
||||||
|
}
|
||||||
|
return "UNSUPPORTED:" + isoDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSystemObject(DatabaseObject example) {
|
||||||
|
if (example == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isLiquibaseObject(example)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (example instanceof Schema) {
|
||||||
|
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
|
||||||
|
if ("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
|
||||||
|
if ("SYSTEM".equals(example.getSchema().getCatalogName()) || "SYS".equals(example.getSchema().getCatalogName()) || "CTXSYS".equals(example.getSchema().getCatalogName()) || "XDB".equals(example.getSchema().getCatalogName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (isSystemObject(example.getSchema())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (example instanceof Catalog) {
|
||||||
|
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
|
||||||
|
if (("SYSTEM".equals(example.getName()) || "SYS".equals(example.getName()) || "CTXSYS".equals(example.getName()) || "XDB".equals(example.getName()))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (example.getName() != null) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("BIN$")) { //oracle deleted table
|
||||||
|
boolean filteredInOriginalQuery = this.canAccessDbaRecycleBin();
|
||||||
|
if (!filteredInOriginalQuery) {
|
||||||
|
filteredInOriginalQuery = StringUtil.trimToEmpty(example.getSchema().getName()).equalsIgnoreCase(this.getConnection().getConnectionUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filteredInOriginalQuery) {
|
||||||
|
return !((example instanceof PrimaryKey) || (example instanceof Index) || (example instanceof
|
||||||
|
liquibase.statement.UniqueConstraint));
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("AQ$")) { //oracle AQ tables
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("DR$")) { //oracle index tables
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("SYS_IOT_OVER")) { //oracle system table
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral,HardCodedStringLiteral
|
||||||
|
if ((example.getName().startsWith("MDRT_") || example.getName().startsWith("MDRS_")) && example.getName().endsWith("$")) {
|
||||||
|
// CORE-1768 - Oracle creates these for spatial indices and will remove them when the index is removed.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("MLOG$_")) { //Created by materliaized view logs for every table that is part of a materialized view. Not available for DDL operations.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("RUPD$_")) { //Created by materialized view log tables using primary keys. Not available for DDL operations.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("WM$_")) { //Workspace Manager backup tables.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if ("CREATE$JAVA$LOB$TABLE".equals(example.getName())) { //This table contains the name of the Java object, the date it was loaded, and has a BLOB column to store the Java object.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if ("JAVA$CLASS$MD5$TABLE".equals(example.getName())) { //This is a hash table that tracks the loading of Java objects into a schema.
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("ISEQ$$_")) { //System-generated sequence
|
||||||
|
return true;
|
||||||
|
} else //noinspection HardCodedStringLiteral
|
||||||
|
if (example.getName().startsWith("USLOG$")) { //for update materialized view
|
||||||
|
return true;
|
||||||
|
} else if (example.getName().startsWith("SYS_FBA")) { //for Flashback tables
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.isSystemObject(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsAutoIncrement() {
|
||||||
|
// Oracle supports Identity beginning with version 12c
|
||||||
|
boolean isAutoIncrementSupported = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getDatabaseMajorVersion() >= 12) {
|
||||||
|
isAutoIncrementSupported = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returning true will generate create table command with 'IDENTITY' clause, example:
|
||||||
|
// CREATE TABLE AutoIncTest (IDPrimaryKey NUMBER(19) GENERATED BY DEFAULT AS IDENTITY NOT NULL, TypeID NUMBER(3) NOT NULL, Description NVARCHAR2(50), CONSTRAINT PK_AutoIncTest PRIMARY KEY (IDPrimaryKey));
|
||||||
|
|
||||||
|
// While returning false will continue to generate create table command without 'IDENTITY' clause, example:
|
||||||
|
// CREATE TABLE AutoIncTest (IDPrimaryKey NUMBER(19) NOT NULL, TypeID NUMBER(3) NOT NULL, Description NVARCHAR2(50), CONSTRAINT PK_AutoIncTest PRIMARY KEY (IDPrimaryKey));
|
||||||
|
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
isAutoIncrementSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAutoIncrementSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public Set<UniqueConstraint> findUniqueConstraints(String schema) throws DatabaseException {
|
||||||
|
// Set<UniqueConstraint> returnSet = new HashSet<UniqueConstraint>();
|
||||||
|
//
|
||||||
|
// List<Map> maps = new Executor(this).queryForList(new RawSqlStatement("SELECT UC.CONSTRAINT_NAME, UCC.TABLE_NAME, UCC.COLUMN_NAME FROM USER_CONSTRAINTS UC, USER_CONS_COLUMNS UCC WHERE UC.CONSTRAINT_NAME=UCC.CONSTRAINT_NAME AND CONSTRAINT_TYPE='U' ORDER BY UC.CONSTRAINT_NAME"));
|
||||||
|
//
|
||||||
|
// UniqueConstraint constraint = null;
|
||||||
|
// for (Map map : maps) {
|
||||||
|
// if (constraint == null || !constraint.getName().equals(constraint.getName())) {
|
||||||
|
// returnSet.add(constraint);
|
||||||
|
// Table table = new Table((String) map.get("TABLE_NAME"));
|
||||||
|
// constraint = new UniqueConstraint(map.get("CONSTRAINT_NAME").toString(), table);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (constraint != null) {
|
||||||
|
// returnSet.add(constraint);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return returnSet;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsRestrictForeignKeys() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDataTypeMaxParameters(String dataTypeName) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
if ("BINARY_FLOAT".equals(dataTypeName.toUpperCase())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
if ("BINARY_DOUBLE".equals(dataTypeName.toUpperCase())) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return super.getDataTypeMaxParameters(dataTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSystemTableWhereClause(String tableNameColumn) {
|
||||||
|
List<String> clauses = new ArrayList<String>(Arrays.asList("BIN$",
|
||||||
|
"AQ$",
|
||||||
|
"DR$",
|
||||||
|
"SYS_IOT_OVER",
|
||||||
|
"MLOG$_",
|
||||||
|
"RUPD$_",
|
||||||
|
"WM$_",
|
||||||
|
"ISEQ$$_",
|
||||||
|
"USLOG$",
|
||||||
|
"SYS_FBA"));
|
||||||
|
|
||||||
|
for (int i = 0;i<clauses.size(); i++) {
|
||||||
|
clauses.set(i, tableNameColumn+" NOT LIKE '"+clauses.get(i)+"%'");
|
||||||
|
}
|
||||||
|
return "("+ StringUtil.join(clauses, " AND ") + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean jdbcCallsCatalogsSchemas() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getUserDefinedTypes() {
|
||||||
|
if (userDefinedTypes == null) {
|
||||||
|
userDefinedTypes = new HashSet<>();
|
||||||
|
if ((getConnection() != null) && !(getConnection() instanceof OfflineConnection)) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT DISTINCT TYPE_NAME FROM ALL_TYPES"), String.class));
|
||||||
|
} catch (DatabaseException e) { //fall back to USER_TYPES if the user cannot see ALL_TYPES
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
userDefinedTypes.addAll(Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", this).queryForList(new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class));
|
||||||
|
}
|
||||||
|
} catch (DatabaseException e) {
|
||||||
|
//ignore error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userDefinedTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateDatabaseFunctionValue(DatabaseFunction databaseFunction) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
if ((databaseFunction != null) && "current_timestamp".equalsIgnoreCase(databaseFunction.toString())) {
|
||||||
|
return databaseFunction.toString();
|
||||||
|
}
|
||||||
|
if ((databaseFunction instanceof SequenceNextValueFunction) || (databaseFunction instanceof
|
||||||
|
SequenceCurrentValueFunction)) {
|
||||||
|
String quotedSeq = super.generateDatabaseFunctionValue(databaseFunction);
|
||||||
|
// replace "myschema.my_seq".nextval with "myschema"."my_seq".nextval
|
||||||
|
return quotedSeq.replaceFirst("\"([^\\.\"]+)\\.([^\\.\"]+)\"", "\"$1\".\"$2\"");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.generateDatabaseFunctionValue(databaseFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValidationErrors validate() {
|
||||||
|
ValidationErrors errors = super.validate();
|
||||||
|
DatabaseConnection connection = getConnection();
|
||||||
|
if ((connection == null) || (connection instanceof OfflineConnection)) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
Scope.getCurrentScope().getLog(getClass()).info("Cannot validate offline database");
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canAccessDbaRecycleBin()) {
|
||||||
|
errors.addWarning(getDbaRecycleBinWarning());
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDbaRecycleBinWarning() {
|
||||||
|
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral,
|
||||||
|
// HardCodedStringLiteral
|
||||||
|
//noinspection HardCodedStringLiteral,HardCodedStringLiteral,HardCodedStringLiteral
|
||||||
|
return "Liquibase needs to access the DBA_RECYCLEBIN table so we can automatically handle the case where " +
|
||||||
|
"constraints are deleted and restored. Since Oracle doesn't properly restore the original table names " +
|
||||||
|
"referenced in the constraint, we use the information from the DBA_RECYCLEBIN to automatically correct this" +
|
||||||
|
" issue.\n" +
|
||||||
|
"\n" +
|
||||||
|
"The user you used to connect to the database (" + getConnection().getConnectionUserName() +
|
||||||
|
") needs to have \"SELECT ON SYS.DBA_RECYCLEBIN\" permissions set before we can perform this operation. " +
|
||||||
|
"Please run the following SQL to set the appropriate permissions, and try running the command again.\n" +
|
||||||
|
"\n" +
|
||||||
|
" GRANT SELECT ON SYS.DBA_RECYCLEBIN TO " + getConnection().getConnectionUserName() + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canAccessDbaRecycleBin() {
|
||||||
|
if (canAccessDbaRecycleBin == null) {
|
||||||
|
DatabaseConnection connection = getConnection();
|
||||||
|
if ((connection == null) || (connection instanceof OfflineConnection)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement statement = null;
|
||||||
|
try {
|
||||||
|
statement = ((JdbcConnection) connection).createStatement();
|
||||||
|
@SuppressWarnings("HardCodedStringLiteral") ResultSet resultSet = statement.executeQuery("select 1 from dba_recyclebin where 0=1");
|
||||||
|
resultSet.close(); //don't need to do anything with the result set, just make sure statement ran.
|
||||||
|
this.canAccessDbaRecycleBin = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
if ((e instanceof SQLException) && e.getMessage().startsWith("ORA-00942")) { //ORA-00942: table or view does not exist
|
||||||
|
this.canAccessDbaRecycleBin = false;
|
||||||
|
} else {
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
Scope.getCurrentScope().getLog(getClass()).warning("Cannot check dba_recyclebin access", e);
|
||||||
|
this.canAccessDbaRecycleBin = false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
JdbcUtils.close(null, statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return canAccessDbaRecycleBin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsNotNullConstraintNames() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the given String would be a valid identifier in Oracle DBMS. In Oracle, a valid identifier has
|
||||||
|
* the following form (case-insensitive comparison):
|
||||||
|
* 1st character: A-Z
|
||||||
|
* 2..n characters: A-Z0-9$_#
|
||||||
|
* The maximum length of an identifier differs by Oracle version and object type.
|
||||||
|
*/
|
||||||
|
public boolean isValidOracleIdentifier(String identifier, Class<? extends DatabaseObject> type) {
|
||||||
|
if ((identifier == null) || (identifier.length() < 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!identifier.matches("^(i?)[A-Z][A-Z0-9\\$\\_\\#]*$"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @todo It seems we currently do not have a class for tablespace identifiers, and all other classes
|
||||||
|
* we do know seem to be supported as 12cR2 long identifiers, so:
|
||||||
|
*/
|
||||||
|
return (identifier.length() <= LONG_IDENTIFIERS_LEGNTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of bytes (NOT: characters) for an identifier. For Oracle <=12c Release 20, this
|
||||||
|
* is 30 bytes, and starting from 12cR2, up to 128 (except for tablespaces, PDB names and some other rather rare
|
||||||
|
* object types).
|
||||||
|
*
|
||||||
|
* @return the maximum length of an object identifier, in bytes
|
||||||
|
*/
|
||||||
|
public int getIdentifierMaximumLength() {
|
||||||
|
try {
|
||||||
|
if (getDatabaseMajorVersion() < ORACLE_12C_MAJOR_VERSION) {
|
||||||
|
return SHORT_IDENTIFIERS_LENGTH;
|
||||||
|
} else if ((getDatabaseMajorVersion() == ORACLE_12C_MAJOR_VERSION) && (getDatabaseMinorVersion() <= 1)) {
|
||||||
|
return SHORT_IDENTIFIERS_LENGTH;
|
||||||
|
} else {
|
||||||
|
return LONG_IDENTIFIERS_LEGNTH;
|
||||||
|
}
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
throw new UnexpectedLiquibaseException("Cannot determine the Oracle database version number", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
package liquibase.datatype.core;
|
||||||
|
|
||||||
|
import liquibase.change.core.LoadDataChange;
|
||||||
|
import liquibase.database.Database;
|
||||||
|
import liquibase.database.core.*;
|
||||||
|
import liquibase.datatype.DataTypeInfo;
|
||||||
|
import liquibase.datatype.DatabaseDataType;
|
||||||
|
import liquibase.datatype.LiquibaseDataType;
|
||||||
|
import liquibase.exception.UnexpectedLiquibaseException;
|
||||||
|
import liquibase.statement.DatabaseFunction;
|
||||||
|
import liquibase.util.StringUtil;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@DataTypeInfo(name = "boolean", aliases = {"java.sql.Types.BOOLEAN", "java.lang.Boolean", "bit", "bool"}, minParameters = 0, maxParameters = 0, priority = LiquibaseDataType.PRIORITY_DEFAULT)
|
||||||
|
public class BooleanType extends LiquibaseDataType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseDataType toDatabaseDataType(Database database) {
|
||||||
|
String originalDefinition = StringUtil.trimToEmpty(getRawDefinition());
|
||||||
|
if ((database instanceof Firebird3Database)) {
|
||||||
|
return new DatabaseDataType("BOOLEAN");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((database instanceof Db2zDatabase) || (database instanceof FirebirdDatabase)) {
|
||||||
|
return new DatabaseDataType("SMALLINT");
|
||||||
|
} else if (database instanceof MSSQLDatabase) {
|
||||||
|
return new DatabaseDataType(database.escapeDataTypeName("bit"));
|
||||||
|
} else if (database instanceof MySQLDatabase) {
|
||||||
|
if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) {
|
||||||
|
return new DatabaseDataType("BIT", getParameters());
|
||||||
|
}
|
||||||
|
return new DatabaseDataType("BIT", 1);
|
||||||
|
} else if (database instanceof OracleDatabase) {
|
||||||
|
return new DatabaseDataType("NUMBER", 1);
|
||||||
|
} else if ((database instanceof SybaseASADatabase) || (database instanceof SybaseDatabase)) {
|
||||||
|
return new DatabaseDataType("BIT");
|
||||||
|
} else if (database instanceof DerbyDatabase) {
|
||||||
|
if (((DerbyDatabase) database).supportsBooleanDataType()) {
|
||||||
|
return new DatabaseDataType("BOOLEAN");
|
||||||
|
} else {
|
||||||
|
return new DatabaseDataType("SMALLINT");
|
||||||
|
}
|
||||||
|
} else if (database instanceof DB2Database) {
|
||||||
|
if (((DB2Database) database).supportsBooleanDataType())
|
||||||
|
return new DatabaseDataType("BOOLEAN");
|
||||||
|
else
|
||||||
|
return new DatabaseDataType("SMALLINT");
|
||||||
|
} else if (database instanceof HsqlDatabase) {
|
||||||
|
return new DatabaseDataType("BOOLEAN");
|
||||||
|
} else if (database instanceof PostgresDatabase) {
|
||||||
|
if (originalDefinition.toLowerCase(Locale.US).startsWith("bit")) {
|
||||||
|
return new DatabaseDataType("BIT", getParameters());
|
||||||
|
}
|
||||||
|
} else if (database instanceof DmDatabase) { // dhb52: DM Support
|
||||||
|
return new DatabaseDataType("bit");
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.toDatabaseDataType(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String objectToSql(Object value, Database database) {
|
||||||
|
if ((value == null) || "null".equals(value.toString().toLowerCase(Locale.US))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String returnValue;
|
||||||
|
if (value instanceof String) {
|
||||||
|
value = ((String) value).replaceAll("'", "");
|
||||||
|
if ("true".equals(((String) value).toLowerCase(Locale.US)) || "1".equals(value) || "b'1'".equals(((String) value).toLowerCase(Locale.US)) || "t".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getTrueBooleanValue(database).toLowerCase(Locale.US))) {
|
||||||
|
returnValue = this.getTrueBooleanValue(database);
|
||||||
|
} else if ("false".equals(((String) value).toLowerCase(Locale.US)) || "0".equals(value) || "b'0'".equals(
|
||||||
|
((String) value).toLowerCase(Locale.US)) || "f".equals(((String) value).toLowerCase(Locale.US)) || ((String) value).toLowerCase(Locale.US).equals(this.getFalseBooleanValue(database).toLowerCase(Locale.US))) {
|
||||||
|
returnValue = this.getFalseBooleanValue(database);
|
||||||
|
} else if (database instanceof PostgresDatabase && Pattern.matches("b?([01])\\1*(::bit|::\"bit\")?", (String) value)) {
|
||||||
|
returnValue = "b'"
|
||||||
|
+ value.toString()
|
||||||
|
.replace("b", "")
|
||||||
|
.replace("\"", "")
|
||||||
|
.replace("::it", "")
|
||||||
|
+ "'::\"bit\"";
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedLiquibaseException("Unknown boolean value: " + value);
|
||||||
|
}
|
||||||
|
} else if (value instanceof Long) {
|
||||||
|
if (Long.valueOf(1).equals(value)) {
|
||||||
|
returnValue = this.getTrueBooleanValue(database);
|
||||||
|
} else {
|
||||||
|
returnValue = this.getFalseBooleanValue(database);
|
||||||
|
}
|
||||||
|
} else if (value instanceof Number) {
|
||||||
|
if (value.equals(1) || "1".equals(value.toString()) || "1.0".equals(value.toString())) {
|
||||||
|
returnValue = this.getTrueBooleanValue(database);
|
||||||
|
} else {
|
||||||
|
returnValue = this.getFalseBooleanValue(database);
|
||||||
|
}
|
||||||
|
} else if (value instanceof DatabaseFunction) {
|
||||||
|
return value.toString();
|
||||||
|
} else if (value instanceof Boolean) {
|
||||||
|
if (((Boolean) value)) {
|
||||||
|
returnValue = this.getTrueBooleanValue(database);
|
||||||
|
} else {
|
||||||
|
returnValue = this.getFalseBooleanValue(database);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedLiquibaseException("Cannot convert type " + value.getClass() + " to a boolean value");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isNumericBoolean(Database database) {
|
||||||
|
if (database instanceof Firebird3Database) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (database instanceof DerbyDatabase) {
|
||||||
|
return !((DerbyDatabase) database).supportsBooleanDataType();
|
||||||
|
} else if (database instanceof DB2Database) {
|
||||||
|
return !((DB2Database) database).supportsBooleanDataType();
|
||||||
|
}
|
||||||
|
return (database instanceof Db2zDatabase)
|
||||||
|
|| (database instanceof FirebirdDatabase)
|
||||||
|
|| (database instanceof MSSQLDatabase)
|
||||||
|
|| (database instanceof MySQLDatabase)
|
||||||
|
|| (database instanceof OracleDatabase)
|
||||||
|
|| (database instanceof SQLiteDatabase)
|
||||||
|
|| (database instanceof SybaseASADatabase)
|
||||||
|
|| (database instanceof SybaseDatabase)
|
||||||
|
|| (database instanceof DmDatabase); // dhb52: DM Support
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database-specific value to use for "false" "boolean" columns.
|
||||||
|
*/
|
||||||
|
public String getFalseBooleanValue(Database database) {
|
||||||
|
if (isNumericBoolean(database)) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
if (database instanceof InformixDatabase) {
|
||||||
|
return "'f'";
|
||||||
|
}
|
||||||
|
return "FALSE";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database-specific value to use for "true" "boolean" columns.
|
||||||
|
*/
|
||||||
|
public String getTrueBooleanValue(Database database) {
|
||||||
|
if (isNumericBoolean(database)) {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
if (database instanceof InformixDatabase) {
|
||||||
|
return "'t'";
|
||||||
|
}
|
||||||
|
return "TRUE";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoadDataChange.LOAD_DATA_TYPE getLoadTypeName() {
|
||||||
|
return LoadDataChange.LOAD_DATA_TYPE.BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
防止IDEA将`.`和`/`混为一谈
|
|
@ -0,0 +1,21 @@
|
||||||
|
liquibase.database.core.CockroachDatabase
|
||||||
|
liquibase.database.core.DB2Database
|
||||||
|
liquibase.database.core.Db2zDatabase
|
||||||
|
liquibase.database.core.DerbyDatabase
|
||||||
|
liquibase.database.core.Firebird3Database
|
||||||
|
liquibase.database.core.FirebirdDatabase
|
||||||
|
liquibase.database.core.H2Database
|
||||||
|
liquibase.database.core.HsqlDatabase
|
||||||
|
liquibase.database.core.InformixDatabase
|
||||||
|
liquibase.database.core.Ingres9Database
|
||||||
|
liquibase.database.core.MSSQLDatabase
|
||||||
|
liquibase.database.core.MariaDBDatabase
|
||||||
|
liquibase.database.core.MockDatabase
|
||||||
|
liquibase.database.core.MySQLDatabase
|
||||||
|
liquibase.database.core.OracleDatabase
|
||||||
|
liquibase.database.core.PostgresDatabase
|
||||||
|
liquibase.database.core.SQLiteDatabase
|
||||||
|
liquibase.database.core.SybaseASADatabase
|
||||||
|
liquibase.database.core.SybaseDatabase
|
||||||
|
liquibase.database.core.DmDatabase
|
||||||
|
liquibase.database.core.UnsupportedDatabase
|
|
@ -0,0 +1,3 @@
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
-- `ruoyi-vue-pro`.crm_contact definition
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (184, '回款管理审批状态', 'crm_receivable_check_status', 0, '回款管理审批状态(0 未审核 1 审核通过 2 审核拒绝 3 审核中 4 已撤回)', '1', '2023-10-18 21:44:24', '1', '2023-10-18 21:44:24', b'0', '1970-01-01 00:00:00');
|
||||||
|
|
||||||
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (185, '回款管理-回款方式', 'crm_return_type', 0, '回款管理-回款方式', '1', '2023-10-18 21:54:10', '1', '2023-10-18 21:54:10', b'0', '1970-01-01 00:00:00');
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1389, 0, '未审核', '0', 'crm_receivable_check_status', 0, 'default', '', '0 未审核 ', '1', '2023-10-18 21:46:00', '1', '2023-10-18 21:47:16', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1390, 1, '审核通过', '1', 'crm_receivable_check_status', 0, 'default', '', '1 审核通过', '1', '2023-10-18 21:46:18', '1', '2023-10-18 21:47:08', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1391, 2, '审核拒绝', '2', 'crm_receivable_check_status', 0, 'default', '', ' 2 审核拒绝', '1', '2023-10-18 21:46:58', '1', '2023-10-18 21:47:21', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1392, 3, '审核中', '3', 'crm_receivable_check_status', 0, 'default', '', ' 3 审核中', '1', '2023-10-18 21:47:35', '1', '2023-10-18 21:47:35', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1393, 4, '已撤回', '4', 'crm_receivable_check_status', 0, 'default', '', ' 4 已撤回', '1', '2023-10-18 21:47:46', '1', '2023-10-18 21:47:46', b'0');
|
||||||
|
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1394, 1, '支票', '1', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:29', '1', '2023-10-18 21:54:29', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1395, 2, '现金', '2', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:41', '1', '2023-10-18 21:54:41', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1396, 3, '邮政汇款', '3', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:54:53', '1', '2023-10-18 21:54:53', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1397, 4, '电汇', '4', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:07', '1', '2023-10-18 21:55:07', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1398, 5, '网上转账', '5', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:24', '1', '2023-10-18 21:55:24', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1399, 6, '支付宝', '6', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:38', '1', '2023-10-18 21:55:38', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1400, 7, '微信支付', '7', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:55:53', '1', '2023-10-18 21:55:53', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1401, 8, '其他', '8', 'crm_return_type', 0, 'default', '', '', '1', '2023-10-18 21:56:06', '1', '2023-10-18 21:56:06', b'0');
|
|
@ -246,3 +246,11 @@ VALUES (
|
||||||
'转账订单', '', 2, 3, 1117,
|
'转账订单', '', 2, 3, 1117,
|
||||||
'transfer', 'ep:credit-card', 'pay/transfer/index', 0, 'PayTransfer'
|
'transfer', 'ep:credit-card', 'pay/transfer/index', 0, 'PayTransfer'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- 转账通知脚本
|
||||||
|
|
||||||
|
ALTER TABLE `pay_app`
|
||||||
|
ADD COLUMN `transfer_notify_url` varchar(1024) NOT NULL COMMENT '转账结果的回调地址' AFTER `refund_notify_url`;
|
||||||
|
ALTER TABLE `pay_notify_task`
|
||||||
|
MODIFY COLUMN `merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '商户订单编号' AFTER `status`,
|
||||||
|
ADD COLUMN `merchant_transfer_id` varchar(64) COMMENT '商户转账单编号' AFTER `merchant_order_id`;
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
Source Server : 127.0.0.1 MySQL
|
Source Server : 127.0.0.1 MySQL
|
||||||
Source Server Type : MySQL
|
Source Server Type : MySQL
|
||||||
Source Server Version : 80034
|
Source Server Version : 80200 (8.2.0)
|
||||||
Source Host : localhost:3306
|
Source Host : 127.0.0.1:3306
|
||||||
Source Schema : ruoyi-vue-pro
|
Source Schema : ruoyi-vue-pro
|
||||||
|
|
||||||
Target Server Type : MySQL
|
Target Server Type : MySQL
|
||||||
Target Server Version : 80034
|
Target Server Version : 80200 (8.2.0)
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 18/11/2023 17:48:18
|
Date: 30/11/2023 21:13:06
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
|
@ -385,7 +385,7 @@ CREATE TABLE `infra_api_error_log` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1964 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2018 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_api_error_log
|
-- Records of infra_api_error_log
|
||||||
|
@ -423,7 +423,7 @@ CREATE TABLE `infra_codegen_column` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1905 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_codegen_column
|
-- Records of infra_codegen_column
|
||||||
|
@ -461,7 +461,7 @@ CREATE TABLE `infra_codegen_table` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 146 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
|
) ENGINE = InnoDB AUTO_INCREMENT = 155 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_codegen_table
|
-- Records of infra_codegen_table
|
||||||
|
@ -568,7 +568,7 @@ CREATE TABLE `infra_demo02_category` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '示例分类表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '示例分类表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_demo02_category
|
-- Records of infra_demo02_category
|
||||||
|
@ -579,6 +579,7 @@ INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `crea
|
||||||
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, '怪怪', 0, '1', '2023-11-16 20:24:32', '1', '2023-11-16 20:24:32', b'0', 1);
|
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (3, '怪怪', 0, '1', '2023-11-16 20:24:32', '1', '2023-11-16 20:24:32', b'0', 1);
|
||||||
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '小番茄', 2, '1', '2023-11-16 20:24:39', '1', '2023-11-16 20:24:39', b'0', 1);
|
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '小番茄', 2, '1', '2023-11-16 20:24:39', '1', '2023-11-16 20:24:39', b'0', 1);
|
||||||
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大番茄', 2, '1', '2023-11-16 20:24:46', '1', '2023-11-16 20:24:46', b'0', 1);
|
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, '大番茄', 2, '1', '2023-11-16 20:24:46', '1', '2023-11-16 20:24:46', b'0', 1);
|
||||||
|
INSERT INTO `infra_demo02_category` (`id`, `name`, `parent_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, '11', 3, '1', '2023-11-24 19:29:34', '1', '2023-11-24 19:29:34', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -651,7 +652,7 @@ CREATE TABLE `infra_demo03_student` (
|
||||||
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
|
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名字',
|
||||||
`sex` tinyint NOT NULL COMMENT '性别',
|
`sex` tinyint NOT NULL COMMENT '性别',
|
||||||
`birthday` datetime NOT NULL COMMENT '出生日期',
|
`birthday` datetime NOT NULL COMMENT '出生日期',
|
||||||
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '简介',
|
`description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '简介',
|
||||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||||
|
@ -765,7 +766,7 @@ CREATE TABLE `infra_job` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_job
|
-- Records of infra_job
|
||||||
|
@ -806,7 +807,7 @@ CREATE TABLE `infra_job_log` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_job_log
|
-- Records of infra_job_log
|
||||||
|
@ -834,7 +835,7 @@ CREATE TABLE `member_address` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_userId`(`user_id` ASC) USING BTREE
|
INDEX `idx_userId`(`user_id` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
|
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_address
|
-- Records of member_address
|
||||||
|
@ -893,7 +894,7 @@ CREATE TABLE `member_experience_record` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
|
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
|
||||||
INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
|
INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_experience_record
|
-- Records of member_experience_record
|
||||||
|
@ -951,7 +952,7 @@ CREATE TABLE `member_group` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户分组';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户分组';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_group
|
-- Records of member_group
|
||||||
|
@ -979,7 +980,7 @@ CREATE TABLE `member_level` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级';
|
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_level
|
-- Records of member_level
|
||||||
|
@ -1009,7 +1010,7 @@ CREATE TABLE `member_level_record` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
|
INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_level_record
|
-- Records of member_level_record
|
||||||
|
@ -1039,7 +1040,7 @@ CREATE TABLE `member_point_record` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `index_userId`(`user_id` ASC) USING BTREE,
|
INDEX `index_userId`(`user_id` ASC) USING BTREE,
|
||||||
INDEX `index_title`(`title` ASC) USING BTREE
|
INDEX `index_title`(`title` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 60 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 61 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_point_record
|
-- Records of member_point_record
|
||||||
|
@ -1179,7 +1180,7 @@ CREATE TABLE `member_tag` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签';
|
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_tag
|
-- Records of member_tag
|
||||||
|
@ -1221,7 +1222,7 @@ CREATE TABLE `member_user` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 249 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员用户';
|
) ENGINE = InnoDB AUTO_INCREMENT = 250 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员用户';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of member_user
|
-- Records of member_user
|
||||||
|
@ -1289,7 +1290,7 @@ CREATE TABLE `system_dict_data` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1447 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 1455 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_dict_data
|
-- Records of system_dict_data
|
||||||
|
@ -1604,6 +1605,14 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1444, 10, '主表(标准模式)', '10', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:32:49', '1', '2023-11-14 12:32:49', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1444, 10, '主表(标准模式)', '10', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:32:49', '1', '2023-11-14 12:32:49', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1445, 11, '主表(ERP 模式)', '11', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:33:05', '1', '2023-11-14 12:33:05', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1445, 11, '主表(ERP 模式)', '11', 'infra_codegen_template_type', 0, 'default', '', '', '1', '2023-11-14 12:33:05', '1', '2023-11-14 12:33:05', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1446, 12, '主表(内嵌模式)', '12', 'infra_codegen_template_type', 0, '', '', '', '1', '2023-11-14 12:33:31', '1', '2023-11-14 12:33:31', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1446, 12, '主表(内嵌模式)', '12', 'infra_codegen_template_type', 0, '', '', '', '1', '2023-11-14 12:33:31', '1', '2023-11-14 12:33:31', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1447, 1, '负责人', '1', 'crm_permission_level', 0, 'default', '', '', '1', '2023-11-30 09:53:12', '1', '2023-11-30 09:53:12', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1448, 2, '只读', '2', 'crm_permission_level', 0, '', '', '', '1', '2023-11-30 09:53:29', '1', '2023-11-30 09:53:29', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1449, 3, '读写', '3', 'crm_permission_level', 0, '', '', '', '1', '2023-11-30 09:53:36', '1', '2023-11-30 09:53:36', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1450, 0, '未提交', '0', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:56:59', '1', '2023-11-30 18:56:59', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1451, 10, '审批中', '10', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:10', '1', '2023-11-30 18:57:10', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1452, 20, '审核通过', '20', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:24', '1', '2023-11-30 18:57:24', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1453, 30, '审核不通过', '30', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:32', '1', '2023-11-30 18:57:32', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1454, 40, '已取消', '40', 'crm_audit_status', 0, '', '', '', '1', '2023-11-30 18:57:42', '1', '2023-11-30 18:57:42', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -1624,7 +1633,7 @@ CREATE TABLE `system_dict_type` (
|
||||||
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
|
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
|
UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 605 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 607 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_dict_type
|
-- Records of system_dict_type
|
||||||
|
@ -1704,6 +1713,8 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (600, 'Banner 位置', 'promotion_banner_position', 0, '', '1', '2023-10-08 07:24:25', '1', '2023-11-04 13:04:02', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (600, 'Banner 位置', 'promotion_banner_position', 0, '', '1', '2023-10-08 07:24:25', '1', '2023-11-04 13:04:02', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (601, '社交类型', 'system_social_type', 0, '', '1', '2023-11-04 13:03:54', '1', '2023-11-04 13:03:54', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (601, '社交类型', 'system_social_type', 0, '', '1', '2023-11-04 13:03:54', '1', '2023-11-04 13:03:54', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (604, '产品状态', 'crm_product_status', 0, '', '1', '2023-10-30 21:47:59', '1', '2023-10-30 21:48:45', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (604, '产品状态', 'crm_product_status', 0, '', '1', '2023-10-30 21:47:59', '1', '2023-10-30 21:48:45', b'0', '1970-01-01 00:00:00');
|
||||||
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (605, 'CRM 数据权限的级别', 'crm_permission_level', 0, '', '1', '2023-11-30 09:51:59', '1', '2023-11-30 09:51:59', b'0', '1970-01-01 00:00:00');
|
||||||
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (606, 'CRM 审批状态', 'crm_audit_status', 0, '', '1', '2023-11-30 18:56:23', '1', '2023-11-30 18:56:23', b'0', '1970-01-01 00:00:00');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -1723,7 +1734,7 @@ CREATE TABLE `system_error_code` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 5932 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 6039 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_error_code
|
-- Records of system_error_code
|
||||||
|
@ -1752,7 +1763,7 @@ CREATE TABLE `system_login_log` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 2647 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2667 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_login_log
|
-- Records of system_login_log
|
||||||
|
@ -1817,7 +1828,7 @@ CREATE TABLE `system_mail_log` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 355 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 356 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_mail_log
|
-- Records of system_mail_log
|
||||||
|
@ -1882,7 +1893,7 @@ CREATE TABLE `system_menu` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 2504 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2526 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_menu
|
-- Records of system_menu
|
||||||
|
@ -2292,7 +2303,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2302, '支付通知查询', 'pay:notify:query', 3, 1, 2301, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '', '2023-07-20 04:41:32', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2302, '支付通知查询', 'pay:notify:query', 3, 1, 2301, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-07-20 04:41:32', '', '2023-07-20 04:41:32', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2303, '拼团活动', '', 2, 3, 2030, 'combination', 'fa:group', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:19:54', '1', '2023-08-12 17:20:05', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2303, '拼团活动', '', 2, 3, 2030, 'combination', 'fa:group', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:19:54', '1', '2023-08-12 17:20:05', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2304, '拼团商品', '', 2, 1, 2303, 'acitivity', 'ep:apple', 'mall/promotion/combination/activity/index', 'PromotionCombinationActivity', 0, b'1', b'1', b'1', '1', '2023-08-12 17:22:03', '1', '2023-08-12 17:22:29', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2304, '拼团商品', '', 2, 1, 2303, 'acitivity', 'ep:apple', 'mall/promotion/combination/activity/index', 'PromotionCombinationActivity', 0, b'1', b'1', b'1', '1', '2023-08-12 17:22:03', '1', '2023-08-12 17:22:29', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2305, '拼团活动查询', 'promotion:combination-activity:query', 3, 1, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:32', '1', '2023-08-12 17:54:32', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2305, '拼团活动查询', 'promotion:combination-activity:query', 3, 1, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:32', '1', '2023-11-24 11:57:40', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2306, '拼团活动创建', 'promotion:combination-activity:create', 3, 2, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:49', '1', '2023-08-12 17:54:49', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2306, '拼团活动创建', 'promotion:combination-activity:create', 3, 2, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:49', '1', '2023-08-12 17:54:49', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2307, '拼团活动更新', 'promotion:combination-activity:update', 3, 3, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:04', '1', '2023-08-12 17:55:04', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2307, '拼团活动更新', 'promotion:combination-activity:update', 3, 3, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:04', '1', '2023-08-12 17:55:04', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2308, '拼团活动删除', 'promotion:combination-activity:delete', 3, 4, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:23', '1', '2023-08-12 17:55:23', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2308, '拼团活动删除', 'promotion:combination-activity:delete', 3, 4, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:23', '1', '2023-08-12 17:55:23', b'0');
|
||||||
|
@ -2457,6 +2468,16 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2494, '学生删除', 'infra:demo03-student:delete', 3, 4, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2494, '学生删除', 'infra:demo03-student:delete', 3, 4, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2495, '学生导出', 'infra:demo03-student:export', 3, 5, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2495, '学生导出', 'infra:demo03-student:export', 3, 5, 2490, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-16 12:53:37', '', '2023-11-16 12:53:37', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2497, '主子表(ERP)', '', 2, 11, 1070, 'demo03-erp', 'ep:calendar', 'infra/demo/demo03/erp/index', 'Demo03StudentERP', 0, b'1', b'1', b'1', '', '2023-11-16 15:50:59', '1', '2023-11-17 13:19:56', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2497, '主子表(ERP)', '', 2, 11, 1070, 'demo03-erp', 'ep:calendar', 'infra/demo/demo03/erp/index', 'Demo03StudentERP', 0, b'1', b'1', b'1', '', '2023-11-16 15:50:59', '1', '2023-11-17 13:19:56', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2516, '客户公海配置', '', 2, 0, 2524, 'customer-pool-config', 'ep:data-analysis', 'crm/config/customerPoolConfig/index', 'CrmCustomerPoolConfig', 0, b'1', b'1', b'1', '', '2023-11-18 13:33:31', '1', '2023-11-26 20:08:14', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2517, '客户公海配置保存', 'crm:customer-pool-config:update', 3, 1, 2516, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:31', '', '2023-11-18 13:33:31', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2518, '客户限制配置', '', 2, 0, 2524, 'customer-limit-config', 'ep:avatar', 'crm/config/customerLimitConfig/index', 'CrmCustomerLimitConfig', 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '1', '2023-11-26 20:07:04', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2519, '客户限制配置查询', 'crm:customer-limit-config:query', 3, 1, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2520, '客户限制配置创建', 'crm:customer-limit-config:create', 3, 2, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2521, '客户限制配置更新', 'crm:customer-limit-config:update', 3, 3, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2522, '客户限制配置删除', 'crm:customer-limit-config:delete', 3, 4, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 99, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2023-11-18 21:58:00', b'0');
|
||||||
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -2483,7 +2504,7 @@ CREATE TABLE `system_notice` (
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '1', '2022-05-04 21:00:20', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '1', '2022-05-04 21:00:20', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 若依系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\" style=\"\"/>1111</p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2023-11-11 12:51:11', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\" style=\"\"/>1111</p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2023-11-23 23:37:41', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
@ -2547,7 +2568,7 @@ CREATE TABLE `system_notify_template` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_notify_template
|
-- Records of system_notify_template
|
||||||
|
@ -2577,7 +2598,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
||||||
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 3467 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 3587 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_access_token
|
-- Records of system_oauth2_access_token
|
||||||
|
@ -2699,7 +2720,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1115 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 1132 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_refresh_token
|
-- Records of system_oauth2_refresh_token
|
||||||
|
@ -2739,7 +2760,7 @@ CREATE TABLE `system_operate_log` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 9090 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 9175 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_operate_log
|
-- Records of system_operate_log
|
||||||
|
@ -2765,7 +2786,7 @@ CREATE TABLE `system_post` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '岗位信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_post
|
-- Records of system_post
|
||||||
|
@ -3739,7 +3760,7 @@ CREATE TABLE `system_sms_code` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
|
INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 535 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
) ENGINE = InnoDB AUTO_INCREMENT = 536 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_code
|
-- Records of system_sms_code
|
||||||
|
@ -3766,8 +3787,6 @@ CREATE TABLE `system_sms_log` (
|
||||||
`user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型',
|
`user_type` tinyint NULL DEFAULT NULL COMMENT '用户类型',
|
||||||
`send_status` tinyint NOT NULL DEFAULT 0 COMMENT '发送状态',
|
`send_status` tinyint NOT NULL DEFAULT 0 COMMENT '发送状态',
|
||||||
`send_time` datetime NULL DEFAULT NULL COMMENT '发送时间',
|
`send_time` datetime NULL DEFAULT NULL COMMENT '发送时间',
|
||||||
`send_code` int NULL DEFAULT NULL COMMENT '发送结果的编码',
|
|
||||||
`send_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '发送结果的提示',
|
|
||||||
`api_send_code` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送结果的编码',
|
`api_send_code` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送结果的编码',
|
||||||
`api_send_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送失败的提示',
|
`api_send_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送失败的提示',
|
||||||
`api_request_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送返回的唯一请求 ID',
|
`api_request_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '短信 API 发送返回的唯一请求 ID',
|
||||||
|
@ -3782,7 +3801,7 @@ CREATE TABLE `system_sms_log` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 502 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 503 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_log
|
-- Records of system_sms_log
|
||||||
|
@ -3812,7 +3831,7 @@ CREATE TABLE `system_sms_template` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信模板';
|
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信模板';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_template
|
-- Records of system_sms_template
|
||||||
|
@ -3882,7 +3901,7 @@ CREATE TABLE `system_social_user` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_social_user
|
-- Records of system_social_user
|
||||||
|
@ -3907,7 +3926,7 @@ CREATE TABLE `system_social_user_bind` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 80 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 81 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_social_user_bind
|
-- Records of system_social_user_bind
|
||||||
|
@ -4077,13 +4096,13 @@ CREATE TABLE `system_users` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
UNIQUE INDEX `idx_username`(`username` ASC, `update_time` ASC, `tenant_id` ASC) USING BTREE
|
UNIQUE INDEX `idx_username`(`username` ASC, `update_time` ASC, `tenant_id` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 127 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 126 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_users
|
-- Records of system_users
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/4/get/37e56010ecbee472cdd821ac4b608e151e62a74d9633f15d085aee026eedeb60.png', 0, '0:0:0:0:0:0:0:1', '2023-11-18 17:19:30', 'admin', '2021-01-05 17:03:47', NULL, '2023-11-18 17:19:30', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/4/get/37e56010ecbee472cdd821ac4b608e151e62a74d9633f15d085aee026eedeb60.png', 0, '127.0.0.1', '2023-11-30 09:16:00', 'admin', '2021-01-05 17:03:47', NULL, '2023-11-30 09:16:00', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1);
|
||||||
|
@ -4098,7 +4117,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 101, '[]', '', '', 1, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2022-06-22 13:34:58', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (115, 'aotemane', '$2a$10$/WCwGHu1eq0wOVDd/u8HweJ0gJCHyLS6T7ndCqI8UXZAQom1etk2e', '1', '11', 101, '[]', '', '', 1, '', 0, '', NULL, '1', '2022-04-30 02:55:43', '1', '2022-06-22 13:34:58', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, '15601691302', '$2a$10$L5C4S0U6adBWMvFv1Wwl4.DI/NwYS3WIfLj5Q.Naqr5II8CmqsDZ6', '小豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (116, '15601691302', '$2a$10$L5C4S0U6adBWMvFv1Wwl4.DI/NwYS3WIfLj5Q.Naqr5II8CmqsDZ6', '小豆', NULL, NULL, NULL, '', '', 0, '', 0, '', NULL, '1', '2022-05-17 10:07:10', '1', '2022-05-17 10:07:10', b'0', 124);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$10$WI8Gg/lpZQIrOEZMHqka7OdFaD4Nx.B/qY8ZGTTUKrOJwaHFqibaC', '测试号', '1111', 100, '[2]', '', '15601691234', 1, '', 0, '', NULL, '1', '2022-07-09 17:40:26', '1', '2022-07-09 17:40:26', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (117, 'admin123', '$2a$10$WI8Gg/lpZQIrOEZMHqka7OdFaD4Nx.B/qY8ZGTTUKrOJwaHFqibaC', '测试号', '1111', 100, '[2]', '', '15601691234', 1, '', 0, '', NULL, '1', '2022-07-09 17:40:26', '1', '2022-07-09 17:40:26', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$10$Lrb71muL.s5/AFjQ2IHkzOFlAFwUToH.zQL7bnghvTDt/QptjGgF6', '狗蛋', NULL, 103, '[1]', '', '', 2, '', 0, '', NULL, '1', '2022-07-09 17:44:43', '1', '2022-12-31 17:29:13', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (118, 'goudan', '$2a$10$Lrb71muL.s5/AFjQ2IHkzOFlAFwUToH.zQL7bnghvTDt/QptjGgF6', '狗蛋', NULL, 103, '[1]', '', '', 2, '', 0, '', NULL, '1', '2022-07-09 17:44:43', '1', '2023-11-18 19:02:13', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
|
|
@ -103,7 +103,19 @@ public class CodegenEngine {
|
||||||
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/index.vue"),
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/index.vue"),
|
||||||
vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
vueFilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||||
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"),
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"),
|
||||||
vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
|
vueFilePath("api/${table.moduleName}/${table.businessName}/index.js"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/form.vue"),
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/${simpleClassName}Form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_normal.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/form_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}Form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/list_sub_inner.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/components/list_sub_erp.vue"), // 特殊:主子表专属逻辑
|
||||||
|
vueFilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||||
// Vue3 标准模版
|
// Vue3 标准模版
|
||||||
.put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"),
|
.put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"),
|
||||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/index.vue"))
|
||||||
|
@ -285,6 +297,10 @@ public class CodegenEngine {
|
||||||
if (StrUtil.count(content, "dateFormatter") == 1) {
|
if (StrUtil.count(content, "dateFormatter") == 1) {
|
||||||
content = StrUtils.removeLineContains(content, "dateFormatter");
|
content = StrUtils.removeLineContains(content, "dateFormatter");
|
||||||
}
|
}
|
||||||
|
// Vue2 界面:修正 $refs
|
||||||
|
if (StrUtil.count(content, "this.refs") >= 1) {
|
||||||
|
content = content.replace("this.refs", "this.$refs");
|
||||||
|
}
|
||||||
// Vue 界面:去除多的 dict 相关,只有一个的情况下,说明没使用到
|
// Vue 界面:去除多的 dict 相关,只有一个的情况下,说明没使用到
|
||||||
if (StrUtil.count(content, "getIntDictOptions") == 1) {
|
if (StrUtil.count(content, "getIntDictOptions") == 1) {
|
||||||
content = content.replace("getIntDictOptions, ", "");
|
content = content.replace("getIntDictOptions, ", "");
|
||||||
|
@ -452,7 +468,7 @@ public class CodegenEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String vueFilePath(String path) {
|
private static String vueFilePath(String path) {
|
||||||
return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
|
return "yudao-ui-${sceneEnum.basePackage}-vue2/" + // 顶级目录
|
||||||
"src/" + path;
|
"src/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,21 +35,113 @@ export function get${simpleClassName}(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
// 获得${table.classComment}分页
|
// 获得${table.classComment}分页
|
||||||
export function get${simpleClassName}Page(query) {
|
export function get${simpleClassName}Page(params) {
|
||||||
return request({
|
return request({
|
||||||
url: '${baseURL}/page',
|
url: '${baseURL}/page',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// 获得${table.classComment}列表
|
||||||
|
export function get${simpleClassName}List(params) {
|
||||||
|
return request({
|
||||||
|
url: '${baseURL}/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#end
|
||||||
// 导出${table.classComment} Excel
|
// 导出${table.classComment} Excel
|
||||||
export function export${simpleClassName}Excel(query) {
|
export function export${simpleClassName}Excel(params) {
|
||||||
return request({
|
return request({
|
||||||
url: '${baseURL}/export-excel',
|
url: '${baseURL}/export-excel',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query,
|
params,
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
## 特殊:主子表专属逻辑 TODO @puhui999:下面方法的【空格】不太对
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subPrimaryColumn = $subPrimaryColumns.get($index))##当前 primary 字段
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($index))##当前 join 字段
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
#set ($subSimpleClassName_strikeCase = $subSimpleClassName_strikeCases.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
|
||||||
|
// ==================== 子表($subTable.classComment) ====================
|
||||||
|
## 情况一:MASTER_ERP 时,需要分查询页子表
|
||||||
|
#if ( $table.templateType == 11 )
|
||||||
|
|
||||||
|
// 获得${subTable.classComment}分页
|
||||||
|
export function get${subSimpleClassName}Page(params) {
|
||||||
|
return request({
|
||||||
|
url: '${baseURL}/${subSimpleClassName_strikeCase}/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
## 情况二:非 MASTER_ERP 时,需要列表查询子表
|
||||||
|
#else
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
|
||||||
|
// 获得${subTable.classComment}列表
|
||||||
|
export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField},
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
// 获得${subTable.classComment}
|
||||||
|
export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField},
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作
|
||||||
|
#if ( $table.templateType == 11 )
|
||||||
|
// 新增${subTable.classComment}
|
||||||
|
export function create${subSimpleClassName}(data) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/create`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改${subTable.classComment}
|
||||||
|
export function update${subSimpleClassName}(data) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/update`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除${subTable.classComment}
|
||||||
|
export function delete${subSimpleClassName}(id) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得${subTable.classComment}
|
||||||
|
export function get${subSimpleClassName}(id) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
|
@ -0,0 +1,205 @@
|
||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
#set ($hasImageUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<ImageUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
#set ($hasFileUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<FileUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
#set ($hasEditorColumn = true)
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<editor v-model="formData.${javaField}" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-checkbox-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-radio-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||||
|
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
#end
|
||||||
|
export default {
|
||||||
|
name: "${subSimpleClassName}Form",
|
||||||
|
components: {
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
ImageUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
FileUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
Editor,
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id, ${subJoinColumn.javaField}) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
this.formData.${subJoinColumn.javaField} = ${subJoinColumn.javaField};
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await ${simpleClassName}Api.get${subSimpleClassName}(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.dialogTitle = "修改${subTable.classComment}";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dialogTitle = "新增${subTable.classComment}";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
await this.#[[$]]#refs["formRef"].validate();
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 修改的提交
|
||||||
|
if (data.${primaryColumn.javaField}) {
|
||||||
|
await ${simpleClassName}Api.update${subSimpleClassName}(data);
|
||||||
|
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.#[[$]]#emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await ${simpleClassName}Api.create${subSimpleClassName}(data);
|
||||||
|
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.#[[$]]#emit('success');
|
||||||
|
}finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,2 @@
|
||||||
|
## 主表的 normal 和 inner 使用相同的 form 表单
|
||||||
|
#parse("codegen/vue/views/components/form_sub_normal.vue.vm")
|
|
@ -0,0 +1,347 @@
|
||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
#if ( $subTable.subJoinMany )## 情况一:一对多,table + form
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
v-loading="formLoading"
|
||||||
|
label-width="0px"
|
||||||
|
:inline-message="true"
|
||||||
|
>
|
||||||
|
<el-table :data="formData" class="-mt-10px">
|
||||||
|
<el-table-column label="序号" type="index" width="100" />
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<el-table-column label="${comment}" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-input v-model="row.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
#set ($hasImageUploadColumn = true)
|
||||||
|
<el-table-column label="${comment}" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<ImageUpload v-model="row.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
#set ($hasFileUploadColumn = true)
|
||||||
|
<el-table-column label="${comment}" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<FileUpload v-model="row.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
#set ($hasEditorColumn = true)
|
||||||
|
<el-table-column label="${comment}" min-width="400">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<Editor v-model="row.${javaField}" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-table-column label="${comment}" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-select v-model="row.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-table-column label="${comment}" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-checkbox-group v-model="row.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-table-column label="${comment}" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-radio-group v-model="row.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||||
|
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-table-column label="${comment}" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-date-picker clearable v-model="row.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-table-column label="${comment}" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.${javaField}`" :rules="formRules.${javaField}" class="mb-0px!">
|
||||||
|
<el-input v-model="row.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||||
|
<template v-slot="{ $index }">
|
||||||
|
<el-link @click="handleDelete($index)">—</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<el-row justify="center" class="mt-3">
|
||||||
|
<el-button @click="handleAdd" round>+ 添加${subTable.classComment}</el-button>
|
||||||
|
</el-row>
|
||||||
|
#else## 情况二:一对一,form
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
#set ($hasImageUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<ImageUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
#set ($hasFileUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<FileUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
#set ($hasEditorColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-checkbox-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-radio-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||||
|
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</el-form>
|
||||||
|
#end
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
#end
|
||||||
|
export default {
|
||||||
|
name: "${subSimpleClassName}Form",
|
||||||
|
components: {
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
ImageUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
FileUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
Editor,
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'${subJoinColumn.javaField}'
|
||||||
|
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: [],
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
${subJoinColumn.javaField}:{
|
||||||
|
handler(val) {
|
||||||
|
// 1. 重置表单
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
this.formData = []
|
||||||
|
#else
|
||||||
|
this.formData = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.formLoading = true;
|
||||||
|
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||||
|
const that = this;
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(val).then(function (res){
|
||||||
|
that.formData = res.data;
|
||||||
|
})
|
||||||
|
#else
|
||||||
|
${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(val).then(function (res){
|
||||||
|
const data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.formData = data;
|
||||||
|
})
|
||||||
|
#end
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
const row = {
|
||||||
|
#foreach ($column in $subColumns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
row.${subJoinColumn.javaField} = this.${subJoinColumn.javaField};
|
||||||
|
this.formData.push(row);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(index) {
|
||||||
|
this.formData.splice(index, 1);
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
/** 表单校验 */
|
||||||
|
validate(){
|
||||||
|
return this.#[[$]]#refs["formRef"].validate();
|
||||||
|
},
|
||||||
|
/** 表单值 */
|
||||||
|
getData(){
|
||||||
|
return this.formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,165 @@
|
||||||
|
#set ($subTable = $subTables.get($subIndex))##当前表
|
||||||
|
#set ($subColumns = $subColumnsList.get($subIndex))##当前字段数组
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($subIndex))
|
||||||
|
#set ($subJoinColumn = $subJoinColumns.get($subIndex))##当前 join 字段
|
||||||
|
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
<!-- 操作工具栏 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
#end
|
||||||
|
## 列表
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
#foreach($column in $subColumns)
|
||||||
|
#if ($column.listOperationResult)
|
||||||
|
#set ($dictType=$column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment=$column.columnComment)
|
||||||
|
#if ( $column.id == $subJoinColumn.id) ## 特殊:忽略主子表的 join 字段,不用填写
|
||||||
|
#elseif ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
|
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.${javaField}) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||||
|
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#else
|
||||||
|
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||||
|
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<${subSimpleClassName}Form ref="formRef" @success="getList" />
|
||||||
|
#end
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
import ${subSimpleClassName}Form from './${subSimpleClassName}Form.vue';
|
||||||
|
#end
|
||||||
|
export default {
|
||||||
|
name: "${subSimpleClassName}List",
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
components: {
|
||||||
|
${subSimpleClassName}Form
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
props:[
|
||||||
|
'${subJoinColumn.javaField}'
|
||||||
|
],// ${subJoinColumn.columnComment}(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 列表的数据
|
||||||
|
list: [],
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
// 列表的总页数
|
||||||
|
total: 0,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
${subJoinColumn.javaField}: undefined
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
},
|
||||||
|
#if ($table.templateType != 11)
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
${subJoinColumn.javaField}:{
|
||||||
|
handler(val) {
|
||||||
|
this.queryParams.${subJoinColumn.javaField} = val;
|
||||||
|
if (val){
|
||||||
|
this.handleQuery();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
const res = await ${simpleClassName}Api.get${subSimpleClassName}Page(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
#else
|
||||||
|
#if ( $subTable.subJoinMany )
|
||||||
|
const res = await ${simpleClassName}Api.get${subSimpleClassName}ListBy${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||||
|
this.list = res.data;
|
||||||
|
#else
|
||||||
|
const res = await ${simpleClassName}Api.get${subSimpleClassName}By${SubJoinColumnName}(this.${subJoinColumn.javaField});
|
||||||
|
const data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.list.push(data);
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
#if ($table.templateType == 11)
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
if (!this.${subJoinColumn.javaField}) {
|
||||||
|
this.#[[$modal]]#.msgError('请选择一个${table.classComment}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#[[$]]#refs["formRef"].open(id, this.${subJoinColumn.javaField});
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||||
|
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?');
|
||||||
|
try {
|
||||||
|
await ${simpleClassName}Api.delete${subSimpleClassName}(${primaryColumn.javaField});
|
||||||
|
await this.getList();
|
||||||
|
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,4 @@
|
||||||
|
## 子表的 erp 和 inner 使用相似的 list 列表,差异主要两点:
|
||||||
|
## 1)inner 使用 list 不分页,erp 使用 page 分页
|
||||||
|
## 2)erp 支持单个子表的新增、修改、删除,inner 不支持
|
||||||
|
#parse("codegen/vue/views/components/list_sub_erp.vue.vm")
|
|
@ -0,0 +1,320 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<TreeSelect
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
:options="${classNameVar}Tree"
|
||||||
|
:normalizer="normalizer"
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
#set ($hasImageUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<ImageUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
#set ($hasFileUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<FileUpload v-model="formData.${javaField}"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
#set ($hasEditorColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<Editor v-model="formData.${javaField}" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-checkbox-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-radio-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"
|
||||||
|
#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker clearable v-model="formData.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</el-form>
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<el-tabs v-model="subTabsName">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
|
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
#end
|
||||||
|
</el-tabs>
|
||||||
|
#end
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
import TreeSelect from "@riophae/vue-treeselect";
|
||||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
export default {
|
||||||
|
name: "${simpleClassName}Form",
|
||||||
|
components: {
|
||||||
|
#if ($hasImageUploadColumn)
|
||||||
|
ImageUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasFileUploadColumn)
|
||||||
|
FileUpload,
|
||||||
|
#end
|
||||||
|
#if ($hasEditorColumn)
|
||||||
|
Editor,
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
TreeSelect,
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
${subSimpleClassName}Form,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
${classNameVar}Tree: [], // 树形结构
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
/** 子表的表单 */
|
||||||
|
subTabsName: '$subClassNameVars.get(0)'
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await ${simpleClassName}Api.get${simpleClassName}(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.title = "修改${table.classComment}";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.title = "新增${table.classComment}";
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
await this.get${simpleClassName}Tree();
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
// 校验主表
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 校验子表
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
try {
|
||||||
|
## 代码生成后会替换为正确的 refs
|
||||||
|
await this.refs['${subClassNameVar}FormRef'].validate();
|
||||||
|
} catch (e) {
|
||||||
|
this.subTabsName = '${subClassNameVar}';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 拼接子表的数据
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = this.refs['${subClassNameVar}FormRef'].getData();
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
// 修改的提交
|
||||||
|
if (data.${primaryColumn.javaField}) {
|
||||||
|
await ${simpleClassName}Api.update${simpleClassName}(data);
|
||||||
|
this.#[[$modal]]#.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.#[[$]]#emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await ${simpleClassName}Api.create${simpleClassName}(data);
|
||||||
|
this.#[[$modal]]#.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.#[[$]]#emit('success');
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
/** 获得${table.classComment}树 */
|
||||||
|
async get${simpleClassName}Tree() {
|
||||||
|
this.${classNameVar}Tree = [];
|
||||||
|
const res = await ${simpleClassName}Api.get${simpleClassName}List();
|
||||||
|
const root = { id: 0, name: '顶级${table.classComment}', children: [] };
|
||||||
|
root.children = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}')
|
||||||
|
this.${classNameVar}Tree.push(root)
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
/** 转换${table.classComment}数据结构 */
|
||||||
|
normalizer(node) {
|
||||||
|
if (node.children && !node.children.length) {
|
||||||
|
delete node.children;
|
||||||
|
}
|
||||||
|
#if ($treeNameColumn.javaField == "name")
|
||||||
|
return {
|
||||||
|
id: node.id,
|
||||||
|
label: node.name,
|
||||||
|
children: node.children
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
return {
|
||||||
|
id: node.id,
|
||||||
|
label: node['$treeNameColumn.javaField'],
|
||||||
|
children: node.children
|
||||||
|
};
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: [],
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
|
@ -47,18 +46,68 @@
|
||||||
<!-- 操作工具栏 -->
|
<!-- 操作工具栏 -->
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="10" class="mb8">
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
v-hasPermi="['${permissionPrefix}:create']">新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||||
v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
|
v-hasPermi="['${permissionPrefix}:export']">导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="danger" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">
|
||||||
|
展开/折叠
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
#end
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 列表 -->
|
## 特殊:主子表专属逻辑
|
||||||
<el-table v-loading="loading" :data="list">
|
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:highlight-current-row="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#elseif ( $table.templateType == 2 )
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
v-if="refreshTable"
|
||||||
|
row-key="id"
|
||||||
|
:default-expand-all="isExpandAll"
|
||||||
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||||
|
>
|
||||||
|
#else
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<el-table-column type="expand">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tabs value="$subClassNameVars.get(0)">
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
#end
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#end
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
#if ($column.listOperationResult)
|
#if ($column.listOperationResult)
|
||||||
#set ($dictType=$column.dictType)
|
#set ($dictType=$column.dictType)
|
||||||
|
@ -84,102 +133,42 @@
|
||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.${primaryColumn.javaField})"
|
||||||
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
v-hasPermi="['${permissionPrefix}:update']">修改</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
v-hasPermi="['${permissionPrefix}:delete']">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页)
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
@pagination="getList"/>
|
@pagination="getList"/>
|
||||||
|
#end
|
||||||
<!-- 对话框(添加 / 修改) -->
|
<!-- 对话框(添加 / 修改) -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
|
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
## 特殊:主子表专属逻辑
|
||||||
#foreach($column in $columns)
|
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
<!-- 子表的列表 -->
|
||||||
#set ($dictType = $column.dictType)
|
<el-tabs v-model="subTabsName">
|
||||||
#set ($javaField = $column.javaField)
|
#foreach ($subTable in $subTables)
|
||||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set ($index = $foreach.count - 1)
|
||||||
#set ($comment = $column.columnComment)
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
#if ($column.htmlType == "input")
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
#if (!$column.primaryKey)## 忽略主键,不用在表单里
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
<el-input v-model="form.${javaField}" placeholder="请输入${comment}" />
|
<${subSimpleClassName}List v-if="currentRow.id" :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||||
</el-form-item>
|
</el-tab-pane>
|
||||||
|
#end
|
||||||
|
</el-tabs>
|
||||||
#end
|
#end
|
||||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
|
||||||
#set ($hasImageUploadColumn = true)
|
|
||||||
<el-form-item label="${comment}">
|
|
||||||
<imageUpload v-model="form.${javaField}"/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
|
||||||
#set ($hasFileUploadColumn = true)
|
|
||||||
<el-form-item label="${comment}">
|
|
||||||
<fileUpload v-model="form.${javaField}"/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
|
||||||
#set ($hasEditorColumn = true)
|
|
||||||
<el-form-item label="${comment}">
|
|
||||||
<editor v-model="form.${javaField}" :min-height="192"/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "select")## 下拉框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-select v-model="form.${javaField}" placeholder="请选择${comment}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
|
|
||||||
#else##没数据字典
|
|
||||||
<el-option label="请选择字典生成" value="" />
|
|
||||||
#end
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "checkbox")## 多选框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-checkbox-group v-model="form.${javaField}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
|
|
||||||
#else##没数据字典
|
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
|
||||||
#end
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "radio")## 单选框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-radio-group v-model="form.${javaField}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-radio>
|
|
||||||
#else##没数据字典
|
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
|
||||||
#end
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "datetime")## 时间框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-date-picker clearable v-model="form.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "textarea")## 文本框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-input v-model="form.${javaField}" type="textarea" placeholder="请输入内容" />
|
|
||||||
</el-form-item>
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
|
||||||
<el-button @click="cancel">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { create${simpleClassName}, update${simpleClassName}, delete${simpleClassName}, get${simpleClassName}, get${simpleClassName}Page, export${simpleClassName}Excel } from "@/api/${table.moduleName}/${classNameVar}";
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}';
|
||||||
|
import ${simpleClassName}Form from './${simpleClassName}Form.vue';
|
||||||
#if ($hasImageUploadColumn)
|
#if ($hasImageUploadColumn)
|
||||||
import ImageUpload from '@/components/ImageUpload';
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
#end
|
#end
|
||||||
|
@ -189,10 +178,26 @@ import FileUpload from '@/components/FileUpload';
|
||||||
#if ($hasEditorColumn)
|
#if ($hasEditorColumn)
|
||||||
import Editor from '@/components/Editor';
|
import Editor from '@/components/Editor';
|
||||||
#end
|
#end
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType != 10 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue';
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
export default {
|
export default {
|
||||||
name: "${simpleClassName}",
|
name: "${simpleClassName}",
|
||||||
components: {
|
components: {
|
||||||
|
${simpleClassName}Form,
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType != 10 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
|
${subSimpleClassName}List,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
#if ($hasImageUploadColumn)
|
#if ($hasImageUploadColumn)
|
||||||
ImageUpload,
|
ImageUpload,
|
||||||
#end
|
#end
|
||||||
|
@ -211,40 +216,44 @@ export default {
|
||||||
exportLoading: false,
|
exportLoading: false,
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
total: 0,
|
#if ( $table.templateType != 2 )
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
#end
|
||||||
// ${table.classComment}列表
|
// ${table.classComment}列表
|
||||||
list: [],
|
list: [],
|
||||||
// 弹出层标题
|
// 是否展开,默认全部展开
|
||||||
title: "",
|
isExpandAll: true,
|
||||||
// 是否显示弹出层
|
// 重新渲染表格状态
|
||||||
open: false,
|
refreshTable: true,
|
||||||
|
// 选中行
|
||||||
|
currentRow: {},
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNo: 1,
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
pageSize: 10,
|
#if ( $table.templateType != 2 )
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
#end
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if ($column.listOperation)
|
#if ($column.listOperation)
|
||||||
#if ($column.listOperationCondition != 'BETWEEN')
|
#if ($column.listOperationCondition != 'BETWEEN')
|
||||||
$column.javaField: null,
|
$column.javaField: null,
|
||||||
#end
|
#end
|
||||||
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
#if ($column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN")
|
||||||
$column.javaField: [],
|
$column.javaField: [],
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
},
|
},
|
||||||
// 表单参数
|
## 特殊:主子表专属逻辑-erp
|
||||||
form: {},
|
#if ( $table.templateType == 11)
|
||||||
// 表单校验
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
rules: {
|
/** 子表的列表 */
|
||||||
#foreach ($column in $columns)
|
subTabsName: '$subClassNameVars.get(0)'
|
||||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
#end
|
||||||
#set($comment=$column.columnComment)
|
#end
|
||||||
$column.javaField: [{ required: true, message: "${comment}不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }],
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -252,34 +261,21 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
getList() {
|
async getList() {
|
||||||
|
try {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
// 执行查询
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
get${simpleClassName}Page(this.queryParams).then(response => {
|
#if ( $table.templateType == 2 )
|
||||||
this.list = response.data.list;
|
const res = await ${simpleClassName}Api.get${simpleClassName}List(this.queryParams);
|
||||||
this.total = response.data.total;
|
this.list = this.handleTree(res.data, 'id', '${treeParentColumn.javaField}');
|
||||||
|
#else
|
||||||
|
const res = await ${simpleClassName}Api.get${simpleClassName}Page(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
#end
|
||||||
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
}
|
||||||
},
|
|
||||||
/** 取消按钮 */
|
|
||||||
cancel() {
|
|
||||||
this.open = false;
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
/** 表单重置 */
|
|
||||||
reset() {
|
|
||||||
this.form = {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
|
||||||
#if ($column.htmlType == "checkbox")
|
|
||||||
$column.javaField: [],
|
|
||||||
#else
|
|
||||||
$column.javaField: undefined,
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
};
|
|
||||||
this.resetForm("form");
|
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
|
@ -291,79 +287,54 @@ export default {
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
/** 添加/修改操作 */
|
||||||
handleAdd() {
|
openForm(id) {
|
||||||
this.reset();
|
this.#[[$]]#refs["formRef"].open(id);
|
||||||
this.open = true;
|
|
||||||
this.title = "添加${table.classComment}";
|
|
||||||
},
|
|
||||||
/** 修改按钮操作 */
|
|
||||||
handleUpdate(row) {
|
|
||||||
this.reset();
|
|
||||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
|
||||||
get${simpleClassName}(${primaryColumn.javaField}).then(response => {
|
|
||||||
this.form = response.data;
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if($column.htmlType == "checkbox")## checkbox 特殊处理
|
|
||||||
this.form.$column.javaField = this.form.${column.javaField}.split(",");
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
this.open = true;
|
|
||||||
this.title = "修改${table.classComment}";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 提交按钮 */
|
|
||||||
submitForm() {
|
|
||||||
this.#[[$]]#refs["form"].validate(valid => {
|
|
||||||
if (!valid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if($column.htmlType == "checkbox")
|
|
||||||
this.form.$column.javaField = this.form.${column.javaField}.join(",");
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
// 修改的提交
|
|
||||||
if (this.form.${primaryColumn.javaField} != null) {
|
|
||||||
update${simpleClassName}(this.form).then(response => {
|
|
||||||
this.#[[$modal]]#.msgSuccess("修改成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 添加的提交
|
|
||||||
create${simpleClassName}(this.form).then(response => {
|
|
||||||
this.#[[$modal]]#.msgSuccess("新增成功");
|
|
||||||
this.open = false;
|
|
||||||
this.getList();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
handleDelete(row) {
|
async handleDelete(row) {
|
||||||
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
const ${primaryColumn.javaField} = row.${primaryColumn.javaField};
|
||||||
this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?').then(function() {
|
await this.#[[$modal]]#.confirm('是否确认删除${table.classComment}编号为"' + ${primaryColumn.javaField} + '"的数据项?')
|
||||||
return delete${simpleClassName}(${primaryColumn.javaField});
|
try {
|
||||||
}).then(() => {
|
await ${simpleClassName}Api.delete${simpleClassName}(${primaryColumn.javaField});
|
||||||
this.getList();
|
await this.getList();
|
||||||
this.#[[$modal]]#.msgSuccess("删除成功");
|
this.#[[$modal]]#.msgSuccess("删除成功");
|
||||||
}).catch(() => {});
|
} catch {}
|
||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
/** 导出按钮操作 */
|
||||||
handleExport() {
|
async handleExport() {
|
||||||
// 处理查询参数
|
await this.#[[$modal]]#.confirm('是否确认导出所有${table.classComment}数据项?');
|
||||||
let params = {...this.queryParams};
|
try {
|
||||||
params.pageNo = undefined;
|
this.exportLoading = true;
|
||||||
params.pageSize = undefined;
|
const res = await ${simpleClassName}Api.export${simpleClassName}Excel(this.queryParams);
|
||||||
this.#[[$modal]]#.confirm('是否确认导出所有${table.classComment}数据项?').then(() => {
|
this.#[[$]]#download.excel(res.data, '${table.classComment}.xls');
|
||||||
this.exportLoading = true;
|
} catch {
|
||||||
return export${simpleClassName}Excel(params);
|
} finally {
|
||||||
}).then(response => {
|
this.exportLoading = false;
|
||||||
this.#[[$]]#download.excel(response, '${table.classComment}.xls');
|
}
|
||||||
this.exportLoading = false;
|
},
|
||||||
}).catch(() => {});
|
## 特殊:主子表专属逻辑
|
||||||
}
|
#if ( $table.templateType == 11 )
|
||||||
|
/** 选中行操作 */
|
||||||
|
handleCurrentChange(row) {
|
||||||
|
this.currentRow = row;
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
/** 子表的列表 */
|
||||||
|
this.subTabsName = '$subClassNameVars.get(0)';
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
/** 展开/折叠操作 */
|
||||||
|
toggleExpandAll() {
|
||||||
|
this.refreshTable = false
|
||||||
|
this.isExpandAll = !this.isExpandAll
|
||||||
|
this.$nextTick(function () {
|
||||||
|
this.refreshTable = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
[ {
|
||||||
|
"contentPath" : "java/InfraStudentPageReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentPageReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentRespVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentRespVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentSaveReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentSaveReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentController",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/InfraStudentController.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentContactDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentTeacherDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentContactMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentTeacherMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "xml/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/demo/InfraStudentMapper.xml"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImpl",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImpl.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentService",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentService.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImplTest",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImplTest.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/ErrorCodeConstants_手动操作",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants_手动操作.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/sql",
|
||||||
|
"filePath" : "sql/sql.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/h2",
|
||||||
|
"filePath" : "sql/h2.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/index",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "js/student",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentContactForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentContactForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentTeacherForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentTeacherForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentContactList",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentContactList.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentTeacherList",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentTeacherList.vue"
|
||||||
|
} ]
|
|
@ -0,0 +1,6 @@
|
||||||
|
// TODO 待办:请将下面的错误码复制到 yudao-module-infra-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||||
|
// ========== 学生 TODO 补充编号 ==========
|
||||||
|
ErrorCode STUDENT_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生不存在");
|
||||||
|
ErrorCode STUDENT_CONTACT_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生联系人不存在");
|
||||||
|
ErrorCode STUDENT_TEACHER_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生班主任不存在");
|
||||||
|
ErrorCode STUDENT_TEACHER_EXISTS = new ErrorCode(TODO 补充编号, "学生班主任已存在");
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_contact")
|
||||||
|
@KeySequence("infra_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentContactDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentContactMapper extends BaseMapperX<InfraStudentContactDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentContactDO> selectPage(PageParam reqVO, Long studentId) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentContactDO>()
|
||||||
|
.eq(InfraStudentContactDO::getStudentId, studentId)
|
||||||
|
.orderByDesc(InfraStudentContactDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentContactDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.service.demo.InfraStudentService;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 学生")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/infra/student")
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentService studentService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudent(@Valid @RequestBody InfraStudentSaveReqVO createReqVO) {
|
||||||
|
return success(studentService.createStudent(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudent(@Valid @RequestBody InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentRespVO> getStudent(@RequestParam("id") Long id) {
|
||||||
|
InfraStudentDO student = studentService.getStudent(id);
|
||||||
|
return success(BeanUtils.toBean(student, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得学生分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentRespVO>> getStudentPage(@Valid InfraStudentPageReqVO pageReqVO) {
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出学生 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:export')")
|
||||||
|
@OperateLog(type = EXPORT)
|
||||||
|
public void exportStudentExcel(@Valid InfraStudentPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<InfraStudentDO> list = studentService.getStudentPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "学生.xls", "数据", InfraStudentRespVO.class,
|
||||||
|
BeanUtils.toBean(list, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-contact/page")
|
||||||
|
@Operation(summary = "获得学生联系人分页")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentContactDO>> getStudentContactPage(PageParam pageReqVO,
|
||||||
|
@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentContactPage(pageReqVO, studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/student-contact/create")
|
||||||
|
@Operation(summary = "创建学生联系人")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudentContact(@Valid @RequestBody InfraStudentContactDO studentContact) {
|
||||||
|
return success(studentService.createStudentContact(studentContact));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/student-contact/update")
|
||||||
|
@Operation(summary = "更新学生联系人")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudentContact(@Valid @RequestBody InfraStudentContactDO studentContact) {
|
||||||
|
studentService.updateStudentContact(studentContact);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/student-contact/delete")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@Operation(summary = "删除学生联系人")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudentContact(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudentContact(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/student-contact/get")
|
||||||
|
@Operation(summary = "获得学生联系人")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentContactDO> getStudentContact(@RequestParam("id") Long id) {
|
||||||
|
return success(studentService.getStudentContact(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-teacher/page")
|
||||||
|
@Operation(summary = "获得学生班主任分页")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentTeacherDO>> getStudentTeacherPage(PageParam pageReqVO,
|
||||||
|
@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentTeacherPage(pageReqVO, studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/student-teacher/create")
|
||||||
|
@Operation(summary = "创建学生班主任")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudentTeacher(@Valid @RequestBody InfraStudentTeacherDO studentTeacher) {
|
||||||
|
return success(studentService.createStudentTeacher(studentTeacher));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/student-teacher/update")
|
||||||
|
@Operation(summary = "更新学生班主任")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudentTeacher(@Valid @RequestBody InfraStudentTeacherDO studentTeacher) {
|
||||||
|
studentService.updateStudentTeacher(studentTeacher);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/student-teacher/delete")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@Operation(summary = "删除学生班主任")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudentTeacher(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudentTeacher(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/student-teacher/get")
|
||||||
|
@Operation(summary = "获得学生班主任")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentTeacherDO> getStudentTeacher(@RequestParam("id") Long id) {
|
||||||
|
return success(studentService.getStudentTeacher(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student")
|
||||||
|
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||||
|
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||||
|
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||||
|
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||||
|
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||||
|
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(InfraStudentDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class InfraStudentPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "名字", example = "芋头")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", example = "1")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", example = "true")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.excel.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class InfraStudentRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@ExcelProperty("编号")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@ExcelProperty("名字")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@ExcelProperty("简介")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty(value = "性别", converter = DictConvert.class)
|
||||||
|
@DictFormat("system_user_sex") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@ExcelProperty(value = "是否有效", converter = DictConvert.class)
|
||||||
|
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@ExcelProperty("头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@ExcelProperty("附件")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@ExcelProperty("备注")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class InfraStudentSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@NotEmpty(message = "名字不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@NotEmpty(message = "简介不能为空")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "出生日期不能为空")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "性别不能为空")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@NotNull(message = "是否有效不能为空")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@NotEmpty(message = "头像不能为空")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@NotEmpty(message = "附件不能为空")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@NotEmpty(message = "备注不能为空")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface InfraStudentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudent(@Valid InfraStudentSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudent(@Valid InfraStudentSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生
|
||||||
|
*/
|
||||||
|
InfraStudentDO getStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 学生分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生联系人分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生联系人分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentContactDO> getStudentContactPage(PageParam pageReqVO, Long studentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生联系人
|
||||||
|
*
|
||||||
|
* @param studentContact 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudentContact(@Valid InfraStudentContactDO studentContact);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生联系人
|
||||||
|
*
|
||||||
|
* @param studentContact 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudentContact(@Valid InfraStudentContactDO studentContact);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生联系人
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudentContact(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生联系人
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生联系人
|
||||||
|
*/
|
||||||
|
InfraStudentContactDO getStudentContact(Long id);
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生班主任分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生班主任分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentTeacherDO> getStudentTeacherPage(PageParam pageReqVO, Long studentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生班主任
|
||||||
|
*
|
||||||
|
* @param studentTeacher 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudentTeacher(@Valid InfraStudentTeacherDO studentTeacher);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生班主任
|
||||||
|
*
|
||||||
|
* @param studentTeacher 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudentTeacher(@Valid InfraStudentTeacherDO studentTeacher);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生班主任
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudentTeacher(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生班主任
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生班主任
|
||||||
|
*/
|
||||||
|
InfraStudentTeacherDO getStudentTeacher(Long id);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentContactMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentTeacherMapper;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentServiceImpl implements InfraStudentService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentContactMapper studentContactMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentTeacherMapper studentTeacherMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createStudent(InfraStudentSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
InfraStudentDO student = BeanUtils.toBean(createReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.insert(student);
|
||||||
|
// 返回
|
||||||
|
return student.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStudent(InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
InfraStudentDO updateObj = BeanUtils.toBean(updateReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteStudent(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(id);
|
||||||
|
// 删除
|
||||||
|
studentMapper.deleteById(id);
|
||||||
|
|
||||||
|
// 删除子表
|
||||||
|
deleteStudentContactByStudentId(id);
|
||||||
|
deleteStudentTeacherByStudentId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateStudentExists(Long id) {
|
||||||
|
if (studentMapper.selectById(id) == null) {
|
||||||
|
throw exception(STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentDO getStudent(Long id) {
|
||||||
|
return studentMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO) {
|
||||||
|
return studentMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<InfraStudentContactDO> getStudentContactPage(PageParam pageReqVO, Long studentId) {
|
||||||
|
return studentContactMapper.selectPage(pageReqVO, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createStudentContact(InfraStudentContactDO studentContact) {
|
||||||
|
studentContactMapper.insert(studentContact);
|
||||||
|
return studentContact.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStudentContact(InfraStudentContactDO studentContact) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentContactExists(studentContact.getId());
|
||||||
|
// 更新
|
||||||
|
studentContactMapper.updateById(studentContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteStudentContact(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentContactExists(id);
|
||||||
|
// 删除
|
||||||
|
studentContactMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentContactDO getStudentContact(Long id) {
|
||||||
|
return studentContactMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateStudentContactExists(Long id) {
|
||||||
|
if (studentContactMapper.selectById(id) == null) {
|
||||||
|
throw exception(STUDENT_CONTACT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentContactByStudentId(Long studentId) {
|
||||||
|
studentContactMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<InfraStudentTeacherDO> getStudentTeacherPage(PageParam pageReqVO, Long studentId) {
|
||||||
|
return studentTeacherMapper.selectPage(pageReqVO, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createStudentTeacher(InfraStudentTeacherDO studentTeacher) {
|
||||||
|
// 校验是否已经存在
|
||||||
|
if (studentTeacherMapper.selectByStudentId(studentTeacher.getStudentId()) != null) {
|
||||||
|
throw exception(STUDENT_TEACHER_EXISTS);
|
||||||
|
}
|
||||||
|
// 插入
|
||||||
|
studentTeacherMapper.insert(studentTeacher);
|
||||||
|
return studentTeacher.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStudentTeacher(InfraStudentTeacherDO studentTeacher) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentTeacherExists(studentTeacher.getId());
|
||||||
|
// 更新
|
||||||
|
studentTeacherMapper.updateById(studentTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteStudentTeacher(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentTeacherExists(id);
|
||||||
|
// 删除
|
||||||
|
studentTeacherMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentTeacherDO getStudentTeacher(Long id) {
|
||||||
|
return studentTeacherMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateStudentTeacherExists(Long id) {
|
||||||
|
if (studentTeacherMapper.selectById(id) == null) {
|
||||||
|
throw exception(STUDENT_TEACHER_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentTeacherByStudentId(Long studentId) {
|
||||||
|
studentTeacherMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.RandomUtil.*;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Import(InfraStudentServiceImpl.class)
|
||||||
|
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentServiceImpl studentService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateStudent_success() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long studentId = studentService.createStudent(createReqVO);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(studentId);
|
||||||
|
// 校验记录的属性是否正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||||
|
assertPojoEquals(createReqVO, student, "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||||
|
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
// 校验是否更新正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||||
|
assertPojoEquals(updateReqVO, student);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbStudent.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
// 校验数据不存在了
|
||||||
|
assertNull(studentMapper.selectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
Long id = randomLongId();
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||||
|
public void testGetStudentPage() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||||
|
o.setName(null);
|
||||||
|
o.setBirthday(null);
|
||||||
|
o.setSex(null);
|
||||||
|
o.setEnabled(null);
|
||||||
|
o.setCreateTime(null);
|
||||||
|
});
|
||||||
|
studentMapper.insert(dbStudent);
|
||||||
|
// 测试 name 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||||
|
// 测试 birthday 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||||
|
// 测试 sex 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||||
|
// 测试 enabled 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||||
|
reqVO.setName(null);
|
||||||
|
reqVO.setBirthday(null);
|
||||||
|
reqVO.setSex(null);
|
||||||
|
reqVO.setEnabled(null);
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_teacher")
|
||||||
|
@KeySequence("infra_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentTeacherDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentTeacherMapper extends BaseMapperX<InfraStudentTeacherDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentTeacherDO> selectPage(PageParam reqVO, Long studentId) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentTeacherDO>()
|
||||||
|
.eq(InfraStudentTeacherDO::getStudentId, studentId)
|
||||||
|
.orderByDesc(InfraStudentTeacherDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentTeacherDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 创建学生
|
||||||
|
export function createStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/create',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新学生
|
||||||
|
export function updateStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/update',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
export function deleteStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/delete?id=' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生
|
||||||
|
export function getStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/get?id=' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生分页
|
||||||
|
export function getStudentPage(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 导出学生 Excel
|
||||||
|
export function exportStudentExcel(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/export-excel',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
// 获得学生联系人分页
|
||||||
|
export function getStudentContactPage(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/student-contact/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 新增学生联系人
|
||||||
|
export function createStudentContact(data) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/create`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改学生联系人
|
||||||
|
export function updateStudentContact(data) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/update`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学生联系人
|
||||||
|
export function deleteStudentContact(id) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/delete?id=` + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生联系人
|
||||||
|
export function getStudentContact(id) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/get?id=` + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
// 获得学生班主任分页
|
||||||
|
export function getStudentTeacherPage(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/student-teacher/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 新增学生班主任
|
||||||
|
export function createStudentTeacher(data) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/create`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改学生班主任
|
||||||
|
export function updateStudentTeacher(data) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/update`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学生班主任
|
||||||
|
export function deleteStudentTeacher(id) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/delete?id=` + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生班主任
|
||||||
|
export function getStudentTeacher(id) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/get?id=` + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
-- 将该建表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/create_tables.sql 文件里
|
||||||
|
CREATE TABLE IF NOT EXISTS "infra_student" (
|
||||||
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"description" varchar NOT NULL,
|
||||||
|
"birthday" varchar NOT NULL,
|
||||||
|
"sex" int NOT NULL,
|
||||||
|
"enabled" bit NOT NULL,
|
||||||
|
"avatar" varchar NOT NULL,
|
||||||
|
"video" varchar NOT NULL,
|
||||||
|
"memo" varchar NOT NULL,
|
||||||
|
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '学生表';
|
||||||
|
|
||||||
|
-- 将该删表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/clean.sql 文件里
|
||||||
|
DELETE FROM "infra_student";
|
|
@ -0,0 +1,55 @@
|
||||||
|
-- 菜单 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status, component_name
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生管理', '', 2, 0, 888,
|
||||||
|
'student', '', 'infra/demo/index', 0, 'InfraStudent'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 按钮父菜单ID
|
||||||
|
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||||
|
SELECT @parentId := LAST_INSERT_ID();
|
||||||
|
|
||||||
|
-- 按钮 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生查询', 'infra:student:query', 3, 1, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生创建', 'infra:student:create', 3, 2, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生更新', 'infra:student:update', 3, 3, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生删除', 'infra:student:delete', 3, 4, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生导出', 'infra:student:export', 3, 5, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
|
@ -0,0 +1,151 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像" prop="avatar">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件" prop="video">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="memo">
|
||||||
|
<editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentContactForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id, studentId) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
this.formData.studentId = studentId;
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await StudentApi.getStudentContact(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.dialogTitle = "修改学生联系人";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dialogTitle = "新增学生联系人";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 修改的提交
|
||||||
|
if (data.id) {
|
||||||
|
await StudentApi.updateStudentContact(data);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await StudentApi.createStudentContact(data);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
}finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,129 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 操作工具栏 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['infra:student:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
|
<el-table-column label="简介" align="center" prop="description" />
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar" />
|
||||||
|
<el-table-column label="附件" align="center" prop="video" />
|
||||||
|
<el-table-column label="备注" align="center" prop="memo" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<StudentContactForm ref="formRef" @success="getList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import StudentContactForm from './StudentContactForm.vue';
|
||||||
|
export default {
|
||||||
|
name: "StudentContactList",
|
||||||
|
components: {
|
||||||
|
StudentContactForm
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 列表的数据
|
||||||
|
list: [],
|
||||||
|
// 列表的总页数
|
||||||
|
total: 0,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
studentId: undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
this.queryParams.studentId = val;
|
||||||
|
if (val){
|
||||||
|
this.handleQuery();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentContactPage(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
if (!this.studentId) {
|
||||||
|
this.$modal.msgError('请选择一个学生');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs["formRef"].open(id, this.studentId);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const id = row.id;
|
||||||
|
await this.$modal.confirm('是否确认删除学生编号为"' + id + '"的数据项?');
|
||||||
|
try {
|
||||||
|
await StudentApi.deleteStudentContact(id);
|
||||||
|
await this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,149 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<Editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
|
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
|
||||||
|
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
|
||||||
|
sex: [{ required: true, message: '性别不能为空', trigger: 'change' }],
|
||||||
|
enabled: [{ required: true, message: '是否有效不能为空', trigger: 'blur' }],
|
||||||
|
avatar: [{ required: true, message: '头像不能为空', trigger: 'blur' }],
|
||||||
|
video: [{ required: true, message: '附件不能为空', trigger: 'blur' }],
|
||||||
|
memo: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await StudentApi.getStudent(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.title = "修改学生";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.title = "新增学生";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
// 校验主表
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 修改的提交
|
||||||
|
if (data.id) {
|
||||||
|
await StudentApi.updateStudent(data);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await StudentApi.createStudent(data);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,151 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像" prop="avatar">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件" prop="video">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="memo">
|
||||||
|
<editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentTeacherForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id, studentId) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
this.formData.studentId = studentId;
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await StudentApi.getStudentTeacher(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.dialogTitle = "修改学生班主任";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dialogTitle = "新增学生班主任";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 修改的提交
|
||||||
|
if (data.id) {
|
||||||
|
await StudentApi.updateStudentTeacher(data);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await StudentApi.createStudentTeacher(data);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
}finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,129 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 操作工具栏 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['infra:student:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
|
<el-table-column label="简介" align="center" prop="description" />
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar" />
|
||||||
|
<el-table-column label="附件" align="center" prop="video" />
|
||||||
|
<el-table-column label="备注" align="center" prop="memo" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<StudentTeacherForm ref="formRef" @success="getList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import StudentTeacherForm from './StudentTeacherForm.vue';
|
||||||
|
export default {
|
||||||
|
name: "StudentTeacherList",
|
||||||
|
components: {
|
||||||
|
StudentTeacherForm
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 列表的数据
|
||||||
|
list: [],
|
||||||
|
// 列表的总页数
|
||||||
|
total: 0,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
studentId: undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
this.queryParams.studentId = val;
|
||||||
|
if (val){
|
||||||
|
this.handleQuery();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentTeacherPage(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
if (!this.studentId) {
|
||||||
|
this.$modal.msgError('请选择一个学生');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs["formRef"].open(id, this.studentId);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const id = row.id;
|
||||||
|
await this.$modal.confirm('是否确认删除学生编号为"' + id + '"的数据项?');
|
||||||
|
try {
|
||||||
|
await StudentApi.deleteStudentTeacher(id);
|
||||||
|
await this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,233 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入名字" clearable @keyup.enter.native="handleQuery"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="queryParams.birthday" type="date" value-format="yyyy-MM-dd" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="queryParams.sex" placeholder="请选择性别" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-select v-model="queryParams.enabled" placeholder="请选择是否有效" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||||
|
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-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="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['infra:student:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||||
|
v-hasPermi="['infra:student:export']">导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
:stripe="true"
|
||||||
|
:highlight-current-row="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
<el-table-column label="编号" align="center" prop="id">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.id" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="名字" align="center" prop="name">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.name" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="简介" align="center" prop="description">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.description" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.avatar" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件" align="center" prop="video">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.video" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="memo">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.memo" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<StudentForm ref="formRef" @success="getList" />
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<el-tabs v-model="subTabsName">
|
||||||
|
<el-tab-pane label="学生联系人" name="studentContact">
|
||||||
|
<StudentContactList v-if="currentRow.id" :student-id="currentRow.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="学生班主任" name="studentTeacher">
|
||||||
|
<StudentTeacherList v-if="currentRow.id" :student-id="currentRow.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import StudentForm from './StudentForm.vue';
|
||||||
|
import StudentContactList from './components/StudentContactList.vue';
|
||||||
|
import StudentTeacherList from './components/StudentTeacherList.vue';
|
||||||
|
export default {
|
||||||
|
name: "Student",
|
||||||
|
components: {
|
||||||
|
StudentForm,
|
||||||
|
StudentContactList,
|
||||||
|
StudentTeacherList,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 导出遮罩层
|
||||||
|
exportLoading: false,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 学生列表
|
||||||
|
list: [],
|
||||||
|
// 是否展开,默认全部展开
|
||||||
|
isExpandAll: true,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
|
// 选中行
|
||||||
|
currentRow: {},
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
birthday: null,
|
||||||
|
sex: null,
|
||||||
|
enabled: null,
|
||||||
|
createTime: [],
|
||||||
|
},
|
||||||
|
/** 子表的列表 */
|
||||||
|
subTabsName: 'studentContact'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentPage(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
this.$refs["formRef"].open(id);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const id = row.id;
|
||||||
|
await this.$modal.confirm('是否确认删除学生编号为"' + id + '"的数据项?')
|
||||||
|
try {
|
||||||
|
await StudentApi.deleteStudent(id);
|
||||||
|
await this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
async handleExport() {
|
||||||
|
await this.$modal.confirm('是否确认导出所有学生数据项?');
|
||||||
|
try {
|
||||||
|
this.exportLoading = true;
|
||||||
|
const res = await StudentApi.exportStudentExcel(this.queryParams);
|
||||||
|
this.$download.excel(res.data, '学生.xls');
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
this.exportLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 选中行操作 */
|
||||||
|
handleCurrentChange(row) {
|
||||||
|
this.currentRow = row;
|
||||||
|
/** 子表的列表 */
|
||||||
|
this.subTabsName = 'studentContact';
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,73 @@
|
||||||
|
[ {
|
||||||
|
"contentPath" : "java/InfraStudentPageReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentPageReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentRespVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentRespVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentSaveReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentSaveReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentController",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/InfraStudentController.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentContactDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentTeacherDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentContactMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentTeacherMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "xml/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/demo/InfraStudentMapper.xml"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImpl",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImpl.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentService",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentService.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImplTest",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImplTest.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/ErrorCodeConstants_手动操作",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants_手动操作.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/sql",
|
||||||
|
"filePath" : "sql/sql.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/h2",
|
||||||
|
"filePath" : "sql/h2.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/index",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "js/student",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentContactForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentContactForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentTeacherForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentTeacherForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentContactList",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentContactList.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentTeacherList",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentTeacherList.vue"
|
||||||
|
} ]
|
|
@ -0,0 +1,3 @@
|
||||||
|
// TODO 待办:请将下面的错误码复制到 yudao-module-infra-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||||
|
// ========== 学生 TODO 补充编号 ==========
|
||||||
|
ErrorCode STUDENT_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生不存在");
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_contact")
|
||||||
|
@KeySequence("infra_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentContactDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentContactMapper extends BaseMapperX<InfraStudentContactDO> {
|
||||||
|
|
||||||
|
default List<InfraStudentContactDO> selectListByStudentId(Long studentId) {
|
||||||
|
return selectList(InfraStudentContactDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentContactDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.service.demo.InfraStudentService;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 学生")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/infra/student")
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentService studentService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudent(@Valid @RequestBody InfraStudentSaveReqVO createReqVO) {
|
||||||
|
return success(studentService.createStudent(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudent(@Valid @RequestBody InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentRespVO> getStudent(@RequestParam("id") Long id) {
|
||||||
|
InfraStudentDO student = studentService.getStudent(id);
|
||||||
|
return success(BeanUtils.toBean(student, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得学生分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentRespVO>> getStudentPage(@Valid InfraStudentPageReqVO pageReqVO) {
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出学生 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:export')")
|
||||||
|
@OperateLog(type = EXPORT)
|
||||||
|
public void exportStudentExcel(@Valid InfraStudentPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<InfraStudentDO> list = studentService.getStudentPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "学生.xls", "数据", InfraStudentRespVO.class,
|
||||||
|
BeanUtils.toBean(list, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-contact/list-by-student-id")
|
||||||
|
@Operation(summary = "获得学生联系人列表")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<List<InfraStudentContactDO>> getStudentContactListByStudentId(@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentContactListByStudentId(studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-teacher/get-by-student-id")
|
||||||
|
@Operation(summary = "获得学生班主任")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentTeacherDO> getStudentTeacherByStudentId(@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentTeacherByStudentId(studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student")
|
||||||
|
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||||
|
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||||
|
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||||
|
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||||
|
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||||
|
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(InfraStudentDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class InfraStudentPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "名字", example = "芋头")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", example = "1")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", example = "true")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.excel.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class InfraStudentRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@ExcelProperty("编号")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@ExcelProperty("名字")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@ExcelProperty("简介")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty(value = "性别", converter = DictConvert.class)
|
||||||
|
@DictFormat("system_user_sex") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@ExcelProperty(value = "是否有效", converter = DictConvert.class)
|
||||||
|
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@ExcelProperty("头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@ExcelProperty("附件")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@ExcelProperty("备注")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class InfraStudentSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@NotEmpty(message = "名字不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@NotEmpty(message = "简介不能为空")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "出生日期不能为空")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "性别不能为空")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@NotNull(message = "是否有效不能为空")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@NotEmpty(message = "头像不能为空")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@NotEmpty(message = "附件不能为空")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@NotEmpty(message = "备注不能为空")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "学生联系人列表")
|
||||||
|
private List<InfraStudentContactDO> studentContacts;
|
||||||
|
|
||||||
|
@Schema(description = "学生班主任")
|
||||||
|
private InfraStudentTeacherDO studentTeacher;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface InfraStudentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudent(@Valid InfraStudentSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudent(@Valid InfraStudentSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生
|
||||||
|
*/
|
||||||
|
InfraStudentDO getStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 学生分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生联系人列表
|
||||||
|
*
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生联系人列表
|
||||||
|
*/
|
||||||
|
List<InfraStudentContactDO> getStudentContactListByStudentId(Long studentId);
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生班主任
|
||||||
|
*
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生班主任
|
||||||
|
*/
|
||||||
|
InfraStudentTeacherDO getStudentTeacherByStudentId(Long studentId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentContactMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentTeacherMapper;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentServiceImpl implements InfraStudentService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentContactMapper studentContactMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentTeacherMapper studentTeacherMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long createStudent(InfraStudentSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
InfraStudentDO student = BeanUtils.toBean(createReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.insert(student);
|
||||||
|
|
||||||
|
// 插入子表
|
||||||
|
createStudentContactList(student.getId(), createReqVO.getStudentContacts());
|
||||||
|
createStudentTeacher(student.getId(), createReqVO.getStudentTeacher());
|
||||||
|
// 返回
|
||||||
|
return student.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateStudent(InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
InfraStudentDO updateObj = BeanUtils.toBean(updateReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.updateById(updateObj);
|
||||||
|
|
||||||
|
// 更新子表
|
||||||
|
updateStudentContactList(updateReqVO.getId(), updateReqVO.getStudentContacts());
|
||||||
|
updateStudentTeacher(updateReqVO.getId(), updateReqVO.getStudentTeacher());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteStudent(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(id);
|
||||||
|
// 删除
|
||||||
|
studentMapper.deleteById(id);
|
||||||
|
|
||||||
|
// 删除子表
|
||||||
|
deleteStudentContactByStudentId(id);
|
||||||
|
deleteStudentTeacherByStudentId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateStudentExists(Long id) {
|
||||||
|
if (studentMapper.selectById(id) == null) {
|
||||||
|
throw exception(STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentDO getStudent(Long id) {
|
||||||
|
return studentMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO) {
|
||||||
|
return studentMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<InfraStudentContactDO> getStudentContactListByStudentId(Long studentId) {
|
||||||
|
return studentContactMapper.selectListByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createStudentContactList(Long studentId, List<InfraStudentContactDO> list) {
|
||||||
|
list.forEach(o -> o.setStudentId(studentId));
|
||||||
|
studentContactMapper.insertBatch(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStudentContactList(Long studentId, List<InfraStudentContactDO> list) {
|
||||||
|
deleteStudentContactByStudentId(studentId);
|
||||||
|
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
|
||||||
|
createStudentContactList(studentId, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentContactByStudentId(Long studentId) {
|
||||||
|
studentContactMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentTeacherDO getStudentTeacherByStudentId(Long studentId) {
|
||||||
|
return studentTeacherMapper.selectByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createStudentTeacher(Long studentId, InfraStudentTeacherDO studentTeacher) {
|
||||||
|
if (studentTeacher == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
studentTeacher.setStudentId(studentId);
|
||||||
|
studentTeacherMapper.insert(studentTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStudentTeacher(Long studentId, InfraStudentTeacherDO studentTeacher) {
|
||||||
|
if (studentTeacher == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
studentTeacher.setStudentId(studentId);
|
||||||
|
studentTeacher.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||||
|
studentTeacherMapper.insertOrUpdate(studentTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentTeacherByStudentId(Long studentId) {
|
||||||
|
studentTeacherMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.RandomUtil.*;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Import(InfraStudentServiceImpl.class)
|
||||||
|
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentServiceImpl studentService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateStudent_success() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long studentId = studentService.createStudent(createReqVO);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(studentId);
|
||||||
|
// 校验记录的属性是否正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||||
|
assertPojoEquals(createReqVO, student, "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||||
|
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
// 校验是否更新正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||||
|
assertPojoEquals(updateReqVO, student);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbStudent.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
// 校验数据不存在了
|
||||||
|
assertNull(studentMapper.selectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
Long id = randomLongId();
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||||
|
public void testGetStudentPage() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||||
|
o.setName(null);
|
||||||
|
o.setBirthday(null);
|
||||||
|
o.setSex(null);
|
||||||
|
o.setEnabled(null);
|
||||||
|
o.setCreateTime(null);
|
||||||
|
});
|
||||||
|
studentMapper.insert(dbStudent);
|
||||||
|
// 测试 name 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||||
|
// 测试 birthday 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||||
|
// 测试 sex 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||||
|
// 测试 enabled 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||||
|
reqVO.setName(null);
|
||||||
|
reqVO.setBirthday(null);
|
||||||
|
reqVO.setSex(null);
|
||||||
|
reqVO.setEnabled(null);
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_teacher")
|
||||||
|
@KeySequence("infra_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentTeacherDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentTeacherMapper extends BaseMapperX<InfraStudentTeacherDO> {
|
||||||
|
|
||||||
|
default InfraStudentTeacherDO selectByStudentId(Long studentId) {
|
||||||
|
return selectOne(InfraStudentTeacherDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentTeacherDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 创建学生
|
||||||
|
export function createStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/create',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新学生
|
||||||
|
export function updateStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/update',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
export function deleteStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/delete?id=' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生
|
||||||
|
export function getStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/get?id=' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生分页
|
||||||
|
export function getStudentPage(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 导出学生 Excel
|
||||||
|
export function exportStudentExcel(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/export-excel',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
// 获得学生联系人列表
|
||||||
|
export function getStudentContactListByStudentId(studentId) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/list-by-student-id?studentId=` + studentId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
// 获得学生班主任
|
||||||
|
export function getStudentTeacherByStudentId(studentId) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/get-by-student-id?studentId=` + studentId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
-- 将该建表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/create_tables.sql 文件里
|
||||||
|
CREATE TABLE IF NOT EXISTS "infra_student" (
|
||||||
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"description" varchar NOT NULL,
|
||||||
|
"birthday" varchar NOT NULL,
|
||||||
|
"sex" int NOT NULL,
|
||||||
|
"enabled" bit NOT NULL,
|
||||||
|
"avatar" varchar NOT NULL,
|
||||||
|
"video" varchar NOT NULL,
|
||||||
|
"memo" varchar NOT NULL,
|
||||||
|
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '学生表';
|
||||||
|
|
||||||
|
-- 将该删表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/clean.sql 文件里
|
||||||
|
DELETE FROM "infra_student";
|
|
@ -0,0 +1,55 @@
|
||||||
|
-- 菜单 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status, component_name
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生管理', '', 2, 0, 888,
|
||||||
|
'student', '', 'infra/demo/index', 0, 'InfraStudent'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 按钮父菜单ID
|
||||||
|
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||||
|
SELECT @parentId := LAST_INSERT_ID();
|
||||||
|
|
||||||
|
-- 按钮 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生查询', 'infra:student:query', 3, 1, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生创建', 'infra:student:create', 3, 2, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生更新', 'infra:student:update', 3, 3, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生删除', 'infra:student:delete', 3, 4, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生导出', 'infra:student:export', 3, 5, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
|
@ -0,0 +1,177 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
v-loading="formLoading"
|
||||||
|
label-width="0px"
|
||||||
|
:inline-message="true"
|
||||||
|
>
|
||||||
|
<el-table :data="formData" class="-mt-10px">
|
||||||
|
<el-table-column label="序号" type="index" width="100" />
|
||||||
|
<el-table-column label="名字" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.name`" :rules="formRules.name" class="mb-0px!">
|
||||||
|
<el-input v-model="row.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="简介" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.description`" :rules="formRules.description" class="mb-0px!">
|
||||||
|
<el-input v-model="row.description" type="textarea" placeholder="请输入简介" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生日期" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.birthday`" :rules="formRules.birthday" class="mb-0px!">
|
||||||
|
<el-date-picker clearable v-model="row.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.sex`" :rules="formRules.sex" class="mb-0px!">
|
||||||
|
<el-select v-model="row.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.enabled`" :rules="formRules.enabled" class="mb-0px!">
|
||||||
|
<el-radio-group v-model="row.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.avatar`" :rules="formRules.avatar" class="mb-0px!">
|
||||||
|
<ImageUpload v-model="row.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.video`" :rules="formRules.video" class="mb-0px!">
|
||||||
|
<FileUpload v-model="row.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" min-width="400">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.memo`" :rules="formRules.memo" class="mb-0px!">
|
||||||
|
<Editor v-model="row.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||||
|
<template v-slot="{ $index }">
|
||||||
|
<el-link @click="handleDelete($index)">—</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<el-row justify="center" class="mt-3">
|
||||||
|
<el-button @click="handleAdd" round>+ 添加学生联系人</el-button>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentContactForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: [],
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
// 1. 重置表单
|
||||||
|
this.formData = []
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.formLoading = true;
|
||||||
|
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||||
|
const that = this;
|
||||||
|
StudentApi.getStudentContactListByStudentId(val).then(function (res){
|
||||||
|
that.formData = res.data;
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
const row = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
}
|
||||||
|
row.studentId = this.studentId;
|
||||||
|
this.formData.push(row);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(index) {
|
||||||
|
this.formData.splice(index, 1);
|
||||||
|
},
|
||||||
|
/** 表单校验 */
|
||||||
|
validate(){
|
||||||
|
return this.$refs["formRef"].validate();
|
||||||
|
},
|
||||||
|
/** 表单值 */
|
||||||
|
getData(){
|
||||||
|
return this.formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
|
<el-table-column label="简介" align="center" prop="description" />
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar" />
|
||||||
|
<el-table-column label="附件" align="center" prop="video" />
|
||||||
|
<el-table-column label="备注" align="center" prop="memo" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
export default {
|
||||||
|
name: "StudentContactList",
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 列表的数据
|
||||||
|
list: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
this.queryParams.studentId = val;
|
||||||
|
if (val){
|
||||||
|
this.handleQuery();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentContactListByStudentId(this.studentId);
|
||||||
|
this.list = res.data;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,180 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<Editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<el-tabs v-model="subTabsName">
|
||||||
|
<el-tab-pane label="学生联系人" name="studentContact">
|
||||||
|
<StudentContactForm ref="studentContactFormRef" :student-id="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="学生班主任" name="studentTeacher">
|
||||||
|
<StudentTeacherForm ref="studentTeacherFormRef" :student-id="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
import StudentContactForm from './components/StudentContactForm.vue'
|
||||||
|
import StudentTeacherForm from './components/StudentTeacherForm.vue'
|
||||||
|
export default {
|
||||||
|
name: "StudentForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
StudentContactForm,
|
||||||
|
StudentTeacherForm,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
|
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
|
||||||
|
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
|
||||||
|
sex: [{ required: true, message: '性别不能为空', trigger: 'change' }],
|
||||||
|
enabled: [{ required: true, message: '是否有效不能为空', trigger: 'blur' }],
|
||||||
|
avatar: [{ required: true, message: '头像不能为空', trigger: 'blur' }],
|
||||||
|
video: [{ required: true, message: '附件不能为空', trigger: 'blur' }],
|
||||||
|
memo: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
/** 子表的表单 */
|
||||||
|
subTabsName: 'studentContact'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await StudentApi.getStudent(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.title = "修改学生";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.title = "新增学生";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
// 校验主表
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
// 校验子表
|
||||||
|
try {
|
||||||
|
await this.$refs['studentContactFormRef'].validate();
|
||||||
|
} catch (e) {
|
||||||
|
this.subTabsName = 'studentContact';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.$refs['studentTeacherFormRef'].validate();
|
||||||
|
} catch (e) {
|
||||||
|
this.subTabsName = 'studentTeacher';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 拼接子表的数据
|
||||||
|
data.studentContacts = this.$refs['studentContactFormRef'].getData();
|
||||||
|
data.studentTeacher = this.$refs['studentTeacherFormRef'].getData();
|
||||||
|
// 修改的提交
|
||||||
|
if (data.id) {
|
||||||
|
await StudentApi.updateStudent(data);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await StudentApi.createStudent(data);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,127 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入简介" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<Editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentTeacherForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: [],
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
// 1. 重置表单
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
}
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.formLoading = true;
|
||||||
|
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||||
|
const that = this;
|
||||||
|
StudentApi.getStudentTeacherByStudentId(val).then(function (res){
|
||||||
|
const data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.formData = data;
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 表单校验 */
|
||||||
|
validate(){
|
||||||
|
return this.$refs["formRef"].validate();
|
||||||
|
},
|
||||||
|
/** 表单值 */
|
||||||
|
getData(){
|
||||||
|
return this.formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,93 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
|
<el-table-column label="简介" align="center" prop="description" />
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar" />
|
||||||
|
<el-table-column label="附件" align="center" prop="video" />
|
||||||
|
<el-table-column label="备注" align="center" prop="memo" />
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
export default {
|
||||||
|
name: "StudentTeacherList",
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 列表的数据
|
||||||
|
list: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
this.queryParams.studentId = val;
|
||||||
|
if (val){
|
||||||
|
this.handleQuery();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentTeacherByStudentId(this.studentId);
|
||||||
|
const data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.list.push(data);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,222 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入名字" clearable @keyup.enter.native="handleQuery"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="queryParams.birthday" type="date" value-format="yyyy-MM-dd" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="queryParams.sex" placeholder="请选择性别" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-select v-model="queryParams.enabled" placeholder="请选择是否有效" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||||
|
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-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="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['infra:student:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||||
|
v-hasPermi="['infra:student:export']">导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<!-- 子表的列表 -->
|
||||||
|
<el-table-column type="expand">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tabs value="studentContact">
|
||||||
|
<el-tab-pane label="学生联系人" name="studentContact">
|
||||||
|
<StudentContactList :student-id="scope.row.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="学生班主任" name="studentTeacher">
|
||||||
|
<StudentTeacherList :student-id="scope.row.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="编号" align="center" prop="id">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.id" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="名字" align="center" prop="name">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.name" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="简介" align="center" prop="description">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.description" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.avatar" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件" align="center" prop="video">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.video" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="memo">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.memo" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<StudentForm ref="formRef" @success="getList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import StudentForm from './StudentForm.vue';
|
||||||
|
import StudentContactList from './components/StudentContactList.vue';
|
||||||
|
import StudentTeacherList from './components/StudentTeacherList.vue';
|
||||||
|
export default {
|
||||||
|
name: "Student",
|
||||||
|
components: {
|
||||||
|
StudentForm,
|
||||||
|
StudentContactList,
|
||||||
|
StudentTeacherList,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 导出遮罩层
|
||||||
|
exportLoading: false,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 学生列表
|
||||||
|
list: [],
|
||||||
|
// 是否展开,默认全部展开
|
||||||
|
isExpandAll: true,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
|
// 选中行
|
||||||
|
currentRow: {},
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
birthday: null,
|
||||||
|
sex: null,
|
||||||
|
enabled: null,
|
||||||
|
createTime: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentPage(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
this.$refs["formRef"].open(id);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const id = row.id;
|
||||||
|
await this.$modal.confirm('是否确认删除学生编号为"' + id + '"的数据项?')
|
||||||
|
try {
|
||||||
|
await StudentApi.deleteStudent(id);
|
||||||
|
await this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
async handleExport() {
|
||||||
|
await this.$modal.confirm('是否确认导出所有学生数据项?');
|
||||||
|
try {
|
||||||
|
this.exportLoading = true;
|
||||||
|
const res = await StudentApi.exportStudentExcel(this.queryParams);
|
||||||
|
this.$download.excel(res.data, '学生.xls');
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
this.exportLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||||
|
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||||
|
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||||
|
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||||
|
-->
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,67 @@
|
||||||
|
[ {
|
||||||
|
"contentPath" : "java/InfraStudentPageReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentPageReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentRespVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentRespVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentSaveReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentSaveReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentController",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/InfraStudentController.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentContactDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentTeacherDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentContactMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentContactMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentTeacherMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentTeacherMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "xml/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/demo/InfraStudentMapper.xml"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImpl",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImpl.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentService",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentService.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImplTest",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImplTest.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/ErrorCodeConstants_手动操作",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants_手动操作.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/sql",
|
||||||
|
"filePath" : "sql/sql.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/h2",
|
||||||
|
"filePath" : "sql/h2.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/index",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "js/student",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentContactForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentContactForm.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentTeacherForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/components/StudentTeacherForm.vue"
|
||||||
|
} ]
|
|
@ -0,0 +1,3 @@
|
||||||
|
// TODO 待办:请将下面的错误码复制到 yudao-module-infra-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||||
|
// ========== 学生 TODO 补充编号 ==========
|
||||||
|
ErrorCode STUDENT_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生不存在");
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_contact")
|
||||||
|
@KeySequence("infra_student_contact_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentContactDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生联系人 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentContactMapper extends BaseMapperX<InfraStudentContactDO> {
|
||||||
|
|
||||||
|
default List<InfraStudentContactDO> selectListByStudentId(Long studentId) {
|
||||||
|
return selectList(InfraStudentContactDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentContactDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.service.demo.InfraStudentService;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 学生")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/infra/student")
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentService studentService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudent(@Valid @RequestBody InfraStudentSaveReqVO createReqVO) {
|
||||||
|
return success(studentService.createStudent(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudent(@Valid @RequestBody InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentRespVO> getStudent(@RequestParam("id") Long id) {
|
||||||
|
InfraStudentDO student = studentService.getStudent(id);
|
||||||
|
return success(BeanUtils.toBean(student, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得学生分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentRespVO>> getStudentPage(@Valid InfraStudentPageReqVO pageReqVO) {
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出学生 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:export')")
|
||||||
|
@OperateLog(type = EXPORT)
|
||||||
|
public void exportStudentExcel(@Valid InfraStudentPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<InfraStudentDO> list = studentService.getStudentPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "学生.xls", "数据", InfraStudentRespVO.class,
|
||||||
|
BeanUtils.toBean(list, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-contact/list-by-student-id")
|
||||||
|
@Operation(summary = "获得学生联系人列表")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<List<InfraStudentContactDO>> getStudentContactListByStudentId(@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentContactListByStudentId(studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@GetMapping("/student-teacher/get-by-student-id")
|
||||||
|
@Operation(summary = "获得学生班主任")
|
||||||
|
@Parameter(name = "studentId", description = "学生编号")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentTeacherDO> getStudentTeacherByStudentId(@RequestParam("studentId") Long studentId) {
|
||||||
|
return success(studentService.getStudentTeacherByStudentId(studentId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student")
|
||||||
|
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||||
|
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||||
|
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||||
|
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||||
|
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||||
|
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(InfraStudentDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class InfraStudentPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "名字", example = "芋头")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", example = "1")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", example = "true")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.excel.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class InfraStudentRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@ExcelProperty("编号")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@ExcelProperty("名字")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@ExcelProperty("简介")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty(value = "性别", converter = DictConvert.class)
|
||||||
|
@DictFormat("system_user_sex") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@ExcelProperty(value = "是否有效", converter = DictConvert.class)
|
||||||
|
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@ExcelProperty("头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@ExcelProperty("附件")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@ExcelProperty("备注")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class InfraStudentSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@NotEmpty(message = "名字不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@NotEmpty(message = "简介不能为空")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "出生日期不能为空")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "性别不能为空")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@NotNull(message = "是否有效不能为空")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@NotEmpty(message = "头像不能为空")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@NotEmpty(message = "附件不能为空")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@NotEmpty(message = "备注不能为空")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "学生联系人列表")
|
||||||
|
private List<InfraStudentContactDO> studentContacts;
|
||||||
|
|
||||||
|
@Schema(description = "学生班主任")
|
||||||
|
private InfraStudentTeacherDO studentTeacher;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface InfraStudentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudent(@Valid InfraStudentSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudent(@Valid InfraStudentSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生
|
||||||
|
*/
|
||||||
|
InfraStudentDO getStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 学生分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生联系人列表
|
||||||
|
*
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生联系人列表
|
||||||
|
*/
|
||||||
|
List<InfraStudentContactDO> getStudentContactListByStudentId(Long studentId);
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生班主任
|
||||||
|
*
|
||||||
|
* @param studentId 学生编号
|
||||||
|
* @return 学生班主任
|
||||||
|
*/
|
||||||
|
InfraStudentTeacherDO getStudentTeacherByStudentId(Long studentId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentContactDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentContactMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentTeacherMapper;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentServiceImpl implements InfraStudentService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentContactMapper studentContactMapper;
|
||||||
|
@Resource
|
||||||
|
private InfraStudentTeacherMapper studentTeacherMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long createStudent(InfraStudentSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
InfraStudentDO student = BeanUtils.toBean(createReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.insert(student);
|
||||||
|
|
||||||
|
// 插入子表
|
||||||
|
createStudentContactList(student.getId(), createReqVO.getStudentContacts());
|
||||||
|
createStudentTeacher(student.getId(), createReqVO.getStudentTeacher());
|
||||||
|
// 返回
|
||||||
|
return student.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateStudent(InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
InfraStudentDO updateObj = BeanUtils.toBean(updateReqVO, InfraStudentDO.class);
|
||||||
|
studentMapper.updateById(updateObj);
|
||||||
|
|
||||||
|
// 更新子表
|
||||||
|
updateStudentContactList(updateReqVO.getId(), updateReqVO.getStudentContacts());
|
||||||
|
updateStudentTeacher(updateReqVO.getId(), updateReqVO.getStudentTeacher());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteStudent(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateStudentExists(id);
|
||||||
|
// 删除
|
||||||
|
studentMapper.deleteById(id);
|
||||||
|
|
||||||
|
// 删除子表
|
||||||
|
deleteStudentContactByStudentId(id);
|
||||||
|
deleteStudentTeacherByStudentId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateStudentExists(Long id) {
|
||||||
|
if (studentMapper.selectById(id) == null) {
|
||||||
|
throw exception(STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentDO getStudent(Long id) {
|
||||||
|
return studentMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO) {
|
||||||
|
return studentMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<InfraStudentContactDO> getStudentContactListByStudentId(Long studentId) {
|
||||||
|
return studentContactMapper.selectListByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createStudentContactList(Long studentId, List<InfraStudentContactDO> list) {
|
||||||
|
list.forEach(o -> o.setStudentId(studentId));
|
||||||
|
studentContactMapper.insertBatch(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStudentContactList(Long studentId, List<InfraStudentContactDO> list) {
|
||||||
|
deleteStudentContactByStudentId(studentId);
|
||||||
|
list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新
|
||||||
|
createStudentContactList(studentId, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentContactByStudentId(Long studentId) {
|
||||||
|
studentContactMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InfraStudentTeacherDO getStudentTeacherByStudentId(Long studentId) {
|
||||||
|
return studentTeacherMapper.selectByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createStudentTeacher(Long studentId, InfraStudentTeacherDO studentTeacher) {
|
||||||
|
if (studentTeacher == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
studentTeacher.setStudentId(studentId);
|
||||||
|
studentTeacherMapper.insert(studentTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStudentTeacher(Long studentId, InfraStudentTeacherDO studentTeacher) {
|
||||||
|
if (studentTeacher == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
studentTeacher.setStudentId(studentId);
|
||||||
|
studentTeacher.setUpdater(null).setUpdateTime(null); // 解决更新情况下:updateTime 不更新
|
||||||
|
studentTeacherMapper.insertOrUpdate(studentTeacher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStudentTeacherByStudentId(Long studentId) {
|
||||||
|
studentTeacherMapper.deleteByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.RandomUtil.*;
|
||||||
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link InfraStudentServiceImpl} 的单元测试类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Import(InfraStudentServiceImpl.class)
|
||||||
|
public class InfraStudentServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentServiceImpl studentService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentMapper studentMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateStudent_success() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO createReqVO = randomPojo(InfraStudentSaveReqVO.class).setId(null);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long studentId = studentService.createStudent(createReqVO);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(studentId);
|
||||||
|
// 校验记录的属性是否正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(studentId);
|
||||||
|
assertPojoEquals(createReqVO, student, "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class, o -> {
|
||||||
|
o.setId(dbStudent.getId()); // 设置更新的 ID
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
// 校验是否更新正确
|
||||||
|
InfraStudentDO student = studentMapper.selectById(updateReqVO.getId()); // 获取最新的
|
||||||
|
assertPojoEquals(updateReqVO, student);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentSaveReqVO updateReqVO = randomPojo(InfraStudentSaveReqVO.class);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.updateStudent(updateReqVO), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_success() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class);
|
||||||
|
studentMapper.insert(dbStudent);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbStudent.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
// 校验数据不存在了
|
||||||
|
assertNull(studentMapper.selectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteStudent_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
Long id = randomLongId();
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> studentService.deleteStudent(id), STUDENT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||||
|
public void testGetStudentPage() {
|
||||||
|
// mock 数据
|
||||||
|
InfraStudentDO dbStudent = randomPojo(InfraStudentDO.class, o -> { // 等会查询到
|
||||||
|
o.setName(null);
|
||||||
|
o.setBirthday(null);
|
||||||
|
o.setSex(null);
|
||||||
|
o.setEnabled(null);
|
||||||
|
o.setCreateTime(null);
|
||||||
|
});
|
||||||
|
studentMapper.insert(dbStudent);
|
||||||
|
// 测试 name 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setName(null)));
|
||||||
|
// 测试 birthday 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setBirthday(null)));
|
||||||
|
// 测试 sex 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setSex(null)));
|
||||||
|
// 测试 enabled 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setEnabled(null)));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
studentMapper.insert(cloneIgnoreId(dbStudent, o -> o.setCreateTime(null)));
|
||||||
|
// 准备参数
|
||||||
|
InfraStudentPageReqVO reqVO = new InfraStudentPageReqVO();
|
||||||
|
reqVO.setName(null);
|
||||||
|
reqVO.setBirthday(null);
|
||||||
|
reqVO.setSex(null);
|
||||||
|
reqVO.setEnabled(null);
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbStudent, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student_teacher")
|
||||||
|
@KeySequence("infra_student_teacher_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentTeacherDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 学生编号
|
||||||
|
*/
|
||||||
|
private Long studentId;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentTeacherDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生班主任 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentTeacherMapper extends BaseMapperX<InfraStudentTeacherDO> {
|
||||||
|
|
||||||
|
default InfraStudentTeacherDO selectByStudentId(Long studentId) {
|
||||||
|
return selectOne(InfraStudentTeacherDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int deleteByStudentId(Long studentId) {
|
||||||
|
return delete(InfraStudentTeacherDO::getStudentId, studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 创建学生
|
||||||
|
export function createStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/create',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新学生
|
||||||
|
export function updateStudent(data) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/update',
|
||||||
|
method: 'put',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
export function deleteStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/delete?id=' + id,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生
|
||||||
|
export function getStudent(id) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/get?id=' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得学生分页
|
||||||
|
export function getStudentPage(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 导出学生 Excel
|
||||||
|
export function exportStudentExcel(params) {
|
||||||
|
return request({
|
||||||
|
url: '/infra/student/export-excel',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
responseType: 'blob'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生联系人) ====================
|
||||||
|
|
||||||
|
// 获得学生联系人列表
|
||||||
|
export function getStudentContactListByStudentId(studentId) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-contact/list-by-student-id?studentId=` + studentId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 子表(学生班主任) ====================
|
||||||
|
|
||||||
|
// 获得学生班主任
|
||||||
|
export function getStudentTeacherByStudentId(studentId) {
|
||||||
|
return request({
|
||||||
|
url: `/infra/student/student-teacher/get-by-student-id?studentId=` + studentId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
-- 将该建表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/create_tables.sql 文件里
|
||||||
|
CREATE TABLE IF NOT EXISTS "infra_student" (
|
||||||
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"description" varchar NOT NULL,
|
||||||
|
"birthday" varchar NOT NULL,
|
||||||
|
"sex" int NOT NULL,
|
||||||
|
"enabled" bit NOT NULL,
|
||||||
|
"avatar" varchar NOT NULL,
|
||||||
|
"video" varchar NOT NULL,
|
||||||
|
"memo" varchar NOT NULL,
|
||||||
|
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '学生表';
|
||||||
|
|
||||||
|
-- 将该删表 SQL 语句,添加到 yudao-module-infra-biz 模块的 test/resources/sql/clean.sql 文件里
|
||||||
|
DELETE FROM "infra_student";
|
|
@ -0,0 +1,55 @@
|
||||||
|
-- 菜单 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status, component_name
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生管理', '', 2, 0, 888,
|
||||||
|
'student', '', 'infra/demo/index', 0, 'InfraStudent'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 按钮父菜单ID
|
||||||
|
-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
|
||||||
|
SELECT @parentId := LAST_INSERT_ID();
|
||||||
|
|
||||||
|
-- 按钮 SQL
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生查询', 'infra:student:query', 3, 1, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生创建', 'infra:student:create', 3, 2, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生更新', 'infra:student:update', 3, 3, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生删除', 'infra:student:delete', 3, 4, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
||||||
|
INSERT INTO system_menu(
|
||||||
|
name, permission, type, sort, parent_id,
|
||||||
|
path, icon, component, status
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'学生导出', 'infra:student:export', 3, 5, @parentId,
|
||||||
|
'', '', '', 0
|
||||||
|
);
|
|
@ -0,0 +1,177 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
v-loading="formLoading"
|
||||||
|
label-width="0px"
|
||||||
|
:inline-message="true"
|
||||||
|
>
|
||||||
|
<el-table :data="formData" class="-mt-10px">
|
||||||
|
<el-table-column label="序号" type="index" width="100" />
|
||||||
|
<el-table-column label="名字" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.name`" :rules="formRules.name" class="mb-0px!">
|
||||||
|
<el-input v-model="row.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="简介" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.description`" :rules="formRules.description" class="mb-0px!">
|
||||||
|
<el-input v-model="row.description" type="textarea" placeholder="请输入简介" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生日期" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.birthday`" :rules="formRules.birthday" class="mb-0px!">
|
||||||
|
<el-date-picker clearable v-model="row.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.sex`" :rules="formRules.sex" class="mb-0px!">
|
||||||
|
<el-select v-model="row.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" min-width="150">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.enabled`" :rules="formRules.enabled" class="mb-0px!">
|
||||||
|
<el-radio-group v-model="row.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.avatar`" :rules="formRules.avatar" class="mb-0px!">
|
||||||
|
<ImageUpload v-model="row.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件" min-width="200">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.video`" :rules="formRules.video" class="mb-0px!">
|
||||||
|
<FileUpload v-model="row.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" min-width="400">
|
||||||
|
<template v-slot="{ row, $index }">
|
||||||
|
<el-form-item :prop="`${$index}.memo`" :rules="formRules.memo" class="mb-0px!">
|
||||||
|
<Editor v-model="row.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" width="60">
|
||||||
|
<template v-slot="{ $index }">
|
||||||
|
<el-link @click="handleDelete($index)">—</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<el-row justify="center" class="mt-3">
|
||||||
|
<el-button @click="handleAdd" round>+ 添加学生联系人</el-button>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentContactForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: [],
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
// 1. 重置表单
|
||||||
|
this.formData = []
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.formLoading = true;
|
||||||
|
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||||
|
const that = this;
|
||||||
|
StudentApi.getStudentContactListByStudentId(val).then(function (res){
|
||||||
|
that.formData = res.data;
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 新增按钮操作 */
|
||||||
|
handleAdd() {
|
||||||
|
const row = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
}
|
||||||
|
row.studentId = this.studentId;
|
||||||
|
this.formData.push(row);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
handleDelete(index) {
|
||||||
|
this.formData.splice(index, 1);
|
||||||
|
},
|
||||||
|
/** 表单校验 */
|
||||||
|
validate(){
|
||||||
|
return this.$refs["formRef"].validate();
|
||||||
|
},
|
||||||
|
/** 表单值 */
|
||||||
|
getData(){
|
||||||
|
return this.formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,180 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="formRef" :model="formData" :rules="formRules" v-loading="formLoading" label-width="100px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入内容" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<Editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<!-- 子表的表单 -->
|
||||||
|
<el-tabs v-model="subTabsName">
|
||||||
|
<el-tab-pane label="学生联系人" name="studentContact">
|
||||||
|
<StudentContactForm ref="studentContactFormRef" :student-id="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="学生班主任" name="studentTeacher">
|
||||||
|
<StudentTeacherForm ref="studentTeacherFormRef" :student-id="formData.id" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitForm" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
import StudentContactForm from './components/StudentContactForm.vue'
|
||||||
|
import StudentTeacherForm from './components/StudentTeacherForm.vue'
|
||||||
|
export default {
|
||||||
|
name: "StudentForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
StudentContactForm,
|
||||||
|
StudentTeacherForm,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 弹出层标题
|
||||||
|
dialogTitle: "",
|
||||||
|
// 是否显示弹出层
|
||||||
|
dialogVisible: false,
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
},
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
|
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
|
||||||
|
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
|
||||||
|
sex: [{ required: true, message: '性别不能为空', trigger: 'change' }],
|
||||||
|
enabled: [{ required: true, message: '是否有效不能为空', trigger: 'blur' }],
|
||||||
|
avatar: [{ required: true, message: '头像不能为空', trigger: 'blur' }],
|
||||||
|
video: [{ required: true, message: '附件不能为空', trigger: 'blur' }],
|
||||||
|
memo: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
|
||||||
|
},
|
||||||
|
/** 子表的表单 */
|
||||||
|
subTabsName: 'studentContact'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 打开弹窗 */
|
||||||
|
async open(id) {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.reset();
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const res = await StudentApi.getStudent(id);
|
||||||
|
this.formData = res.data;
|
||||||
|
this.title = "修改学生";
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.title = "新增学生";
|
||||||
|
},
|
||||||
|
/** 提交按钮 */
|
||||||
|
async submitForm() {
|
||||||
|
// 校验主表
|
||||||
|
await this.$refs["formRef"].validate();
|
||||||
|
// 校验子表
|
||||||
|
try {
|
||||||
|
await this.$refs['studentContactFormRef'].validate();
|
||||||
|
} catch (e) {
|
||||||
|
this.subTabsName = 'studentContact';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.$refs['studentTeacherFormRef'].validate();
|
||||||
|
} catch (e) {
|
||||||
|
this.subTabsName = 'studentTeacher';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.formLoading = true;
|
||||||
|
try {
|
||||||
|
const data = this.formData;
|
||||||
|
// 拼接子表的数据
|
||||||
|
data.studentContacts = this.$refs['studentContactFormRef'].getData();
|
||||||
|
data.studentTeacher = this.$refs['studentTeacherFormRef'].getData();
|
||||||
|
// 修改的提交
|
||||||
|
if (data.id) {
|
||||||
|
await StudentApi.updateStudent(data);
|
||||||
|
this.$modal.msgSuccess("修改成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 添加的提交
|
||||||
|
await StudentApi.createStudent(data);
|
||||||
|
this.$modal.msgSuccess("新增成功");
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$emit('success');
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 表单重置 */
|
||||||
|
reset() {
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
};
|
||||||
|
this.resetForm("formRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,127 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="简介" prop="description">
|
||||||
|
<el-input v-model="formData.description" type="textarea" placeholder="请输入简介" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="formData.birthday" type="date" value-format="timestamp" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="formData.sex" placeholder="请选择性别">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-radio-group v-model="formData.enabled">
|
||||||
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.value">{{dict.label}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<ImageUpload v-model="formData.avatar"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<FileUpload v-model="formData.video"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<Editor v-model="formData.memo" :min-height="192"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import ImageUpload from '@/components/ImageUpload';
|
||||||
|
import FileUpload from '@/components/FileUpload';
|
||||||
|
import Editor from '@/components/Editor';
|
||||||
|
export default {
|
||||||
|
name: "StudentTeacherForm",
|
||||||
|
components: {
|
||||||
|
ImageUpload,
|
||||||
|
FileUpload,
|
||||||
|
Editor,
|
||||||
|
},
|
||||||
|
props:[
|
||||||
|
'studentId'
|
||||||
|
],// 学生编号(主表的关联字段)
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
formLoading: false,
|
||||||
|
// 表单参数
|
||||||
|
formData: [],
|
||||||
|
// 表单校验
|
||||||
|
formRules: {
|
||||||
|
studentId: [{ required: true, message: "学生编号不能为空", trigger: "blur" }],
|
||||||
|
name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
|
||||||
|
description: [{ required: true, message: "简介不能为空", trigger: "blur" }],
|
||||||
|
birthday: [{ required: true, message: "出生日期不能为空", trigger: "blur" }],
|
||||||
|
sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
|
||||||
|
enabled: [{ required: true, message: "是否有效不能为空", trigger: "blur" }],
|
||||||
|
avatar: [{ required: true, message: "头像不能为空", trigger: "blur" }],
|
||||||
|
memo: [{ required: true, message: "备注不能为空", trigger: "blur" }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch:{/** 监听主表的关联字段的变化,加载对应的子表数据 */
|
||||||
|
studentId:{
|
||||||
|
handler(val) {
|
||||||
|
// 1. 重置表单
|
||||||
|
this.formData = {
|
||||||
|
id: undefined,
|
||||||
|
studentId: undefined,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
birthday: undefined,
|
||||||
|
sex: undefined,
|
||||||
|
enabled: undefined,
|
||||||
|
avatar: undefined,
|
||||||
|
video: undefined,
|
||||||
|
memo: undefined,
|
||||||
|
}
|
||||||
|
// 2. val 非空,则加载数据
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.formLoading = true;
|
||||||
|
// 这里还是需要获取一下 this 的不然取不到 formData
|
||||||
|
const that = this;
|
||||||
|
StudentApi.getStudentTeacherByStudentId(val).then(function (res){
|
||||||
|
const data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.formData = data;
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
this.formLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 表单校验 */
|
||||||
|
validate(){
|
||||||
|
return this.$refs["formRef"].validate();
|
||||||
|
},
|
||||||
|
/** 表单值 */
|
||||||
|
getData(){
|
||||||
|
return this.formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,205 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="名字" prop="name">
|
||||||
|
<el-input v-model="queryParams.name" placeholder="请输入名字" clearable @keyup.enter.native="handleQuery"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生日期" prop="birthday">
|
||||||
|
<el-date-picker clearable v-model="queryParams.birthday" type="date" value-format="yyyy-MM-dd" placeholder="选择出生日期" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别" prop="sex">
|
||||||
|
<el-select v-model="queryParams.sex" placeholder="请选择性别" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否有效" prop="enabled">
|
||||||
|
<el-select v-model="queryParams.enabled" placeholder="请选择是否有效" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||||
|
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-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="el-icon-plus" size="mini" @click="openForm(undefined)"
|
||||||
|
v-hasPermi="['infra:student:create']">新增</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
||||||
|
v-hasPermi="['infra:student:export']">导出</el-button>
|
||||||
|
</el-col>
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
|
<el-table-column label="编号" align="center" prop="id">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.id" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="名字" align="center" prop="name">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.name" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="简介" align="center" prop="description">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.description" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="出生日期" align="center" prop="birthday" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.birthday) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否有效" align="center" prop="enabled">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.enabled" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="头像" align="center" prop="avatar">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.avatar" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件" align="center" prop="video">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.video" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" align="center" prop="memo">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.memo" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="openForm(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:student:update']">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
|
||||||
|
v-hasPermi="['infra:student:delete']">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<StudentForm ref="formRef" @success="getList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as StudentApi from '@/api/infra/demo';
|
||||||
|
import StudentForm from './StudentForm.vue';
|
||||||
|
export default {
|
||||||
|
name: "Student",
|
||||||
|
components: {
|
||||||
|
StudentForm,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 导出遮罩层
|
||||||
|
exportLoading: false,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 学生列表
|
||||||
|
list: [],
|
||||||
|
// 是否展开,默认全部展开
|
||||||
|
isExpandAll: true,
|
||||||
|
// 重新渲染表格状态
|
||||||
|
refreshTable: true,
|
||||||
|
// 选中行
|
||||||
|
currentRow: {},
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
name: null,
|
||||||
|
birthday: null,
|
||||||
|
sex: null,
|
||||||
|
enabled: null,
|
||||||
|
createTime: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
const res = await StudentApi.getStudentPage(this.queryParams);
|
||||||
|
this.list = res.data.list;
|
||||||
|
this.total = res.data.total;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
openForm(id) {
|
||||||
|
this.$refs["formRef"].open(id);
|
||||||
|
},
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
async handleDelete(row) {
|
||||||
|
const id = row.id;
|
||||||
|
await this.$modal.confirm('是否确认删除学生编号为"' + id + '"的数据项?')
|
||||||
|
try {
|
||||||
|
await StudentApi.deleteStudent(id);
|
||||||
|
await this.getList();
|
||||||
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
async handleExport() {
|
||||||
|
await this.$modal.confirm('是否确认导出所有学生数据项?');
|
||||||
|
try {
|
||||||
|
this.exportLoading = true;
|
||||||
|
const res = await StudentApi.exportStudentExcel(this.queryParams);
|
||||||
|
this.$download.excel(res.data, '学生.xls');
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
this.exportLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="cn.iocoder.yudao.module.infra.dal.mysql.demo.InfraStudentMapper">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||||
|
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||||
|
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||||
|
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||||
|
-->
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,49 @@
|
||||||
|
[ {
|
||||||
|
"contentPath" : "java/InfraStudentPageReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentPageReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentRespVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentRespVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentSaveReqVO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/vo/InfraStudentSaveReqVO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentController",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/demo/InfraStudentController.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentDO",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/demo/InfraStudentDO.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/demo/InfraStudentMapper.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "xml/InfraStudentMapper",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/resources/mapper/demo/InfraStudentMapper.xml"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImpl",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImpl.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentService",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentService.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/InfraStudentServiceImplTest",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/demo/InfraStudentServiceImplTest.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "java/ErrorCodeConstants_手动操作",
|
||||||
|
"filePath" : "yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/enums/ErrorCodeConstants_手动操作.java"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/sql",
|
||||||
|
"filePath" : "sql/sql.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "sql/h2",
|
||||||
|
"filePath" : "sql/h2.sql"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/index",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/index.vue"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "js/student",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/api/infra/student.js"
|
||||||
|
}, {
|
||||||
|
"contentPath" : "vue/StudentForm",
|
||||||
|
"filePath" : "yudao-ui-admin-vue2/src/views/infra/demo/StudentForm.vue"
|
||||||
|
} ]
|
|
@ -0,0 +1,3 @@
|
||||||
|
// TODO 待办:请将下面的错误码复制到 yudao-module-infra-api 模块的 ErrorCodeConstants 类中。注意,请给“TODO 补充编号”设置一个错误码编号!!!
|
||||||
|
// ========== 学生 TODO 补充编号 ==========
|
||||||
|
ErrorCode STUDENT_NOT_EXISTS = new ErrorCode(TODO 补充编号, "学生不存在");
|
|
@ -0,0 +1,95 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.service.demo.InfraStudentService;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 学生")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/infra/student")
|
||||||
|
@Validated
|
||||||
|
public class InfraStudentController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private InfraStudentService studentService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:create')")
|
||||||
|
public CommonResult<Long> createStudent(@Valid @RequestBody InfraStudentSaveReqVO createReqVO) {
|
||||||
|
return success(studentService.createStudent(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新学生")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:update')")
|
||||||
|
public CommonResult<Boolean> updateStudent(@Valid @RequestBody InfraStudentSaveReqVO updateReqVO) {
|
||||||
|
studentService.updateStudent(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:delete')")
|
||||||
|
public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
|
||||||
|
studentService.deleteStudent(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得学生")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<InfraStudentRespVO> getStudent(@RequestParam("id") Long id) {
|
||||||
|
InfraStudentDO student = studentService.getStudent(id);
|
||||||
|
return success(BeanUtils.toBean(student, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得学生分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:query')")
|
||||||
|
public CommonResult<PageResult<InfraStudentRespVO>> getStudentPage(@Valid InfraStudentPageReqVO pageReqVO) {
|
||||||
|
PageResult<InfraStudentDO> pageResult = studentService.getStudentPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出学生 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('infra:student:export')")
|
||||||
|
@OperateLog(type = EXPORT)
|
||||||
|
public void exportStudentExcel(@Valid InfraStudentPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<InfraStudentDO> list = studentService.getStudentPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "学生.xls", "数据", InfraStudentRespVO.class,
|
||||||
|
BeanUtils.toBean(list, InfraStudentRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.dataobject.demo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("infra_student")
|
||||||
|
@KeySequence("infra_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class InfraStudentDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 简介
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 出生日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO system_user_sex 对应的类}
|
||||||
|
*/
|
||||||
|
private Integer sex;
|
||||||
|
/**
|
||||||
|
* 是否有效
|
||||||
|
*
|
||||||
|
* 枚举 {@link TODO infra_boolean_string 对应的类}
|
||||||
|
*/
|
||||||
|
private Boolean enabled;
|
||||||
|
/**
|
||||||
|
* 头像
|
||||||
|
*/
|
||||||
|
private String avatar;
|
||||||
|
/**
|
||||||
|
* 附件
|
||||||
|
*/
|
||||||
|
private String video;
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.dal.mysql.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Mapper
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InfraStudentMapper extends BaseMapperX<InfraStudentDO> {
|
||||||
|
|
||||||
|
default PageResult<InfraStudentDO> selectPage(InfraStudentPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<InfraStudentDO>()
|
||||||
|
.likeIfPresent(InfraStudentDO::getName, reqVO.getName())
|
||||||
|
.eqIfPresent(InfraStudentDO::getBirthday, reqVO.getBirthday())
|
||||||
|
.eqIfPresent(InfraStudentDO::getSex, reqVO.getSex())
|
||||||
|
.eqIfPresent(InfraStudentDO::getEnabled, reqVO.getEnabled())
|
||||||
|
.betweenIfPresent(InfraStudentDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(InfraStudentDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class InfraStudentPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "名字", example = "芋头")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", example = "1")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", example = "true")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.excel.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class InfraStudentRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@ExcelProperty("编号")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@ExcelProperty("名字")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@ExcelProperty("简介")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("出生日期")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty(value = "性别", converter = DictConvert.class)
|
||||||
|
@DictFormat("system_user_sex") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@ExcelProperty(value = "是否有效", converter = DictConvert.class)
|
||||||
|
@DictFormat("infra_boolean_string") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@ExcelProperty("头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@ExcelProperty("附件")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@ExcelProperty("备注")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.demo.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 学生新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class InfraStudentSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋头")
|
||||||
|
@NotEmpty(message = "名字不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是介绍")
|
||||||
|
@NotEmpty(message = "简介不能为空")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "出生日期不能为空")
|
||||||
|
private LocalDateTime birthday;
|
||||||
|
|
||||||
|
@Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "性别不能为空")
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@NotNull(message = "是否有效不能为空")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
|
||||||
|
@NotEmpty(message = "头像不能为空")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "附件", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.mp4")
|
||||||
|
@NotEmpty(message = "附件不能为空")
|
||||||
|
private String video;
|
||||||
|
|
||||||
|
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是备注")
|
||||||
|
@NotEmpty(message = "备注不能为空")
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.demo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import javax.validation.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.demo.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.demo.InfraStudentDO;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface InfraStudentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建学生
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createStudent(@Valid InfraStudentSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateStudent(@Valid InfraStudentSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 学生
|
||||||
|
*/
|
||||||
|
InfraStudentDO getStudent(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得学生分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 学生分页
|
||||||
|
*/
|
||||||
|
PageResult<InfraStudentDO> getStudentPage(InfraStudentPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue