master
cxy 22 hours ago
parent e30939afa4
commit 302254bcbb

@ -13,5 +13,17 @@
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="@localhost" uuid="ed7248bc-a4b3-4474-aedf-9d944f853ff8">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

@ -0,0 +1,21 @@
package com.backend.anno;
import com.backend.validaion.StateValidation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = {StateValidation.class})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface State {
String message() default "state参数的值只能是已签收、未签收";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

@ -2,16 +2,18 @@ package com.backend.controller;
import com.backend.pojo.Express;
import com.backend.pojo.PageBean;
import com.backend.pojo.Result;
import com.backend.service.ExpressService;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Date;
@RestController
@ -25,79 +27,40 @@ public class ExpressController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@PostMapping("/addexpress")
public Result<Express> addexpress(
@Pattern(regexp = "^[A-Za-z0-9]{10,20}$") final String expressid, // 快递ID长度10-20字符字母或数字
@Pattern(regexp = "^\\S{2,30}$") final String sename, // 发件人姓名长度2-30字符不能有空白
@Pattern(regexp = "^[0-9]{11}$") final String sephone, // 发件人电话11位数字
@Pattern(regexp = "^\\S{5,100}$") final String seaddress, // 发件人地址长度5-100字符
@Pattern(regexp = "^\\S{2,30}$") final String rename, // 收件人姓名长度2-30字符不能有空白
@Pattern(regexp = "^[0-9]{11}$") final String rephone, // 收件人电话11位数字
@Pattern(regexp = "^\\S{5,100}$") final String readdress, // 收件人地址长度5-100字符
@Pattern(regexp = "^[0-1]$") final Integer issign, // 是否签收0或1
@Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$") final Date signtime // 签收时间格式yyyy-MM-dd HH:mm:ss
) {
final Express existexpress = expressService.findExpressById(expressid);
if (existexpress== null) {
expressService.insert(expressid, sename, sephone, seaddress, rename, rephone, readdress, issign, signtime);
@PostMapping
public Result<Express> add(
@RequestBody @Validated(Express.Add.class) Express express){
expressService.add(express);
return Result.success();
} else {
return Result.error("该快递单号已存在");
}
}
@PostMapping("/updateexpress")
public Result<Express> updateExpress(
@Pattern(regexp = "^[A-Za-z0-9]{10,20}$") final String expressid, // 快递ID长度10-20字符字母或数字
@Pattern(regexp = "^\\S{2,30}$") final String sename, // 发件人姓名长度2-30字符不能有空白
@Pattern(regexp = "^[0-9]{11}$") final String sephone, // 发件人电话11位数字
@Pattern(regexp = "^\\S{5,100}$") final String seaddress, // 发件人地址长度5-100字符
@Pattern(regexp = "^\\S{2,30}$") final String rename, // 收件人姓名长度2-30字符不能有空白
@Pattern(regexp = "^[0-9]{11}$") final String rephone, // 收件人电话10位数字
@Pattern(regexp = "^\\S{5,100}$") final String readdress, // 收件人地址长度5-100字符
@Pattern(regexp = "^[0-1]$") final Integer issign, // 是否签收0或1
@Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$") final Date signtime // 签收时间格式yyyy-MM-dd HH:mm:ss
@GetMapping
public Result<PageBean<Express>> list(final String expressid,
final String sename,
final String sephone,
final String seaddress,
final String rename,
final String rephone,
final String readdress,
final String issign,
final LocalDateTime signtime
) {
Express express = new Express();
express.setExpressid(expressid);
express.setSename(sename);
express.setSephone(sephone);
express.setSeaddress(seaddress);
express.setRename(rename);
express.setRephone(rephone);
express.setReaddress(readdress);
express.setIssigned(issign);
express.setSigntime(signtime);
expressService.update(express);
return Result.success(express);
final PageBean<Express> expresslist = expressService.list(expressid, sename, sephone, seaddress,
rename, rephone, readdress, issign, signtime);
return Result.success(expresslist);
}
@PutMapping
public Result<String> update(
@RequestBody @Validated(Express.Update.class) Express express) {
@PostMapping("/deleteexpress")
public Result<Express> deleteExpress(
@Pattern(regexp = "^[A-Za-z0-9]{10,20}$") final String expressid
) {
final Express express = expressService.findExpressById(expressid);
if(express!= null){
expressService.delete(express);
expressService.update(express);
return Result.success();
} else {
return Result.error("快递单号为空或者不存在");
}
}
@PostMapping("/getexpress")
public Result<Express> getExpress(
@Pattern(regexp = "^[A-Za-z0-9]{10,20}$") final String expressid
) {
final Express express = expressService.findExpressById(expressid);
if(express != null){
return Result.success(express);
} else {
return Result.error("快递单号为空或者不存在");
}
@DeleteMapping
public Result<Express> delete(@NotNull final Integer id) {
expressService.delete(id);
return Result.success();
}
}

@ -2,27 +2,28 @@ package com.backend.mapper;
import com.backend.pojo.Express;
import org.apache.ibatis.annotations.*;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.List;
@Mapper
public interface ExpressMapper {
@Select("SELECT * FROM express_info WHERE expressid = #{expressid}")
Express findExpressById(String expressid);
@Insert("INSERT INTO express_info(expressid, sename, sephone, seaddress, rename, rephone, readdress, issign, signtime) " +
"VALUES(#{expressid}, #{sename}, #{sephone}, #{seaddress}, #{rename}, #{rephone}, #{readdress}, #{issign} , #{signtime})")
void add(final String expressid, final String sename, final String sephone,
final String seaddress, final String rename, final String rephone,
final String readdress, final Integer isSign, final Date signtime);
@Insert("INSERT INTO express_info(expressid, sename, sephone, seaddress, rename, rephone, readdress, issigned, signtime) " +
"VALUES(#{expressid}, #{sename}, #{sephone}, #{seaddress}, #{rename}, #{rephone}, #{readdress}, #{issigned} , #{signtime})")
void add(final Express express);
@Update("UPDATE express_info SET expressid = #{expressid}, sename = #{sename}," +
" seaddress = #{seaddress}, rename = #{rename}, readdress = #{readdress}, isSign = #{isSign} WHERE expressid = #{expressid}")
void update(Express express);
" seaddress = #{seaddress}, rename = #{rename}, readdress = #{readdress}, isSigned = #{isSigned} WHERE id = #{id}")
void update(final Express express);
@Delete("DELETE FROM express_info WHERE id = #{id}")
void delete(final Integer id);
@Delete("DELETE FROM express_info WHERE expressid = #{expressid}")
void delete(Express express);
List<Express> list( final Integer id, final String sename,
final String sephone, final String seaddress,
final String rename, final String rephone,
final String readdress, final String issigned,
final LocalDateTime signtime);
}

@ -1,21 +1,41 @@
package com.backend.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.backend.anno.State;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.groups.Default;
import lombok.Data;
import java.util.Date;
import java.time.LocalDateTime;
@Data
public class Express {
@NotNull
private Integer id;
@NotNull
private String expressid;
@NotEmpty
private String sename;
@NotEmpty
private String sephone;
@NotEmpty
private String seaddress;
@NotEmpty
private String rename;
@NotEmpty
private String rephone;
@NotEmpty
private String readdress;
private Integer issigned;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy年MM月dd日")
private Date signtime;
@State
private String issigned;
@NotNull
private LocalDateTime signtime;
public interface Add extends Default {
}
public interface Update extends Default{
}
}

@ -0,0 +1,16 @@
package com.backend.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
//分页返回结果对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean <T>{
private Long total;//总条数
private List<T> items;//当前页数据集合
}

@ -25,4 +25,5 @@ public class Result<T> {
public static <T> Result<T> error(String message) {
return new Result<>(1, message, null);
}
}

@ -1,8 +1,6 @@
package com.backend.pojo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;

@ -1,18 +1,26 @@
package com.backend.service;
import com.backend.pojo.Express;
import com.backend.pojo.PageBean;
import java.time.LocalDateTime;
import java.util.Date;
public interface ExpressService {
Express findExpressById(final String expressId);
void insert(final String expressId,
final String sename, final String sephone, final String seaddress,
final String rename, final String rephone, final String readdress,
final Integer issign, final Date signtime);
void add(final Express express);
void update(final Express express);
void delete(final Express express);
void delete(Integer id);
PageBean<Express> list(final String expressid,
final String sename,
final String sephone,
final String seaddress,
final String rename,
final String rephone,
final String readdress,
final String issign,
final LocalDateTime signtime);
}

@ -1,13 +1,16 @@
package com.backend.service.impl;
import com.backend.mapper.ExpressMapper;
import com.backend.pojo.Express;
import com.backend.pojo.PageBean;
import com.backend.service.ExpressService;
import com.backend.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.Map;
@Service
public class ExpressServiceImpl implements ExpressService {
@ -15,29 +18,39 @@ public class ExpressServiceImpl implements ExpressService {
@Autowired
private ExpressMapper expressMapper;
@Override
public Express findExpressById(String expressid) {
return expressMapper.findExpressById(expressid);
}
@Override
public void insert(final String expressId,
final String sename, final String sephone, final String seaddress,
final String rename, final String rephone, final String readdress,
final Integer issign, final Date signtime) {
expressMapper.add(expressId, sename, sephone, seaddress, rename, rephone, readdress, issign, signtime);
public void add(Express express) {
final Map<String, Object> map = ThreadLocalUtil.get();
final Integer id = (Integer) map.get("id");
express.setId(id);
expressMapper.add(express);
}
@Override
public void update(Express express) {
public void update(final Express express) {
expressMapper.update(express);
}
@Override
public void delete(final Express express) {
expressMapper.delete(express);
public void delete(final Integer id) {
expressMapper.delete(id);
}
@Override
public PageBean<Express> list(String expressid, String sename, String sephone, String seaddress, String rename, String rephone, String readdress, String issigned, LocalDateTime signtime) {
final PageBean<Express> pageBean = new PageBean<>();
final Map<String, Object> map = ThreadLocalUtil.get();
final Integer id = (Integer) map.get("id");
final Page<Express> expressList = (Page<Express>) expressMapper.list(id, sename,
sephone, seaddress,
rename, rephone,
readdress, issigned,
signtime);
pageBean.setTotal(expressList.getTotal());
pageBean.setItems(expressList.getResult());
return pageBean;
}

@ -0,0 +1,16 @@
package com.backend.validaion;
import com.backend.anno.State;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class StateValidation implements ConstraintValidator<State, String> {
@Override
public boolean isValid(final String value, final ConstraintValidatorContext constraintValidatorContext) {
if (value == null) {
return false;
}
return value.equals("已签收") || value.equals("未签收");
}
}

@ -14,3 +14,4 @@ mybatis:
#mybatis:
# mapper-locations: classpath:./mapper/*.xml
# type-aliases-package: com.backend.pojo

@ -0,0 +1,13 @@
<?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="com.backend.mapper.ExpressMapper">
<select id="list" resultType="com.backend.pojo.Express">
SELECT * FROM express_info
WHERE id = #{id} OR sename = #{sename} OR sephone = #{sephone} OR seaddress = #{seaddress}
OR rename = #{rename} OR rephone = #{rephone} OR readdress = #{readdress} OR issigned = #{issigned}
OR signtime = #{signtime}
</select>
</mapper>

@ -0,0 +1,13 @@
<?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="com.backend.mapper.ExpressMapper">
<select id="list" resultType="com.backend.pojo.Express">
SELECT * FROM express_info
WHERE id = #{id} OR sename = #{sename} OR sephone = #{sephone} OR seaddress = #{seaddress}
OR rename = #{rename} OR rephone = #{rephone} OR readdress = #{readdress} OR issigned = #{issigned}
OR signtime = #{signtime}
</select>
</mapper>

@ -31,10 +31,10 @@
<h1 style="text-align: center;">卓越城市服务</h1>
<h2 style="text-align: center;">批发市场寄递方案</h2>
<p style="text-align: center;">满足多重寄递需求灵活高效价更优</p>
<div class="search-section">
<input type="text" placeholder="您可以输运单号进行查询" class="search-input" />
<button class="search-button">马上查</button>
</div>
<el-form class="search-section" ref="form">
<input type="text" placeholder="您可以输运单号进行查询" v-model="expressForm.expressid" class="search-input" />
<button class="search-button" @click="findExpress"></button>
</el-form>
<div class="services-grid">
<div class="service-item">
@ -98,15 +98,25 @@
<script setup>
import { ref, computed, onMounted } from "vue";
import { useRouter } from "vue-router";
import {ElMessage} from "element-plus";
const router = useRouter();
const form = ref(null)
const currentIndex = ref(0);
const carouselItems = ref([
{ image: 'lun1.png', title: '卓越速运,值得信赖', description: '快速、安全、专业的物流服务' },
{ image: 'lun2.png', title: '智慧科技,创新未来', description: '领先的物流技术和解决方案' }
]);
const expressForm = ref({
expressid: "",
});
const findExpress = async () => {
const valid = await form.value.validate();
if (valid) {
const result = await expressFindService(expressForm.value);
ElMessage.success(result.message ? result.message : "查询成功");
}
};
const nextSlide = () => {
currentIndex.value = (currentIndex.value + 1) % carouselItems.value.length;
};

@ -1,11 +1,174 @@
<template>
<el-container class="layout-container">
<!-- 左侧菜单 -->
<el-aside width="200px">
<div class="el-aside__logo"></div>
<el-menu active-text-color="#ffd04b" background-color="#ccccd6" text-color="#fff"
router>
<el-menu-item index="/expressForm">
<el-icon>
<Management/>
</el-icon>
<span>我要求寄件</span>
</el-menu-item>
<el-menu-item index="/expressList">
<el-icon>
<Promotion/>
</el-icon>
<span>运输查询</span>
</el-menu-item>
<el-sub-menu>
<template #title>
<el-icon>
<UserFilled/>
</el-icon>
<span>个人中心</span>
</template>
<el-menu-item index="/userInfo">
<el-icon>
<User/>
</el-icon>
<span>我的资料</span>
</el-menu-item>
<el-menu-item index="/user/resetPassword">
<el-icon>
<EditPen/>
</el-icon>
<span>重置密码</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
<!-- 右侧主区域 -->
<el-container>
<!-- 头部区域 -->
<el-header>
<div>欢迎您: <strong>{{ userInfoStore.userInfo.nickname }}</strong></div>
<el-dropdown placement="bottom-end" @command="handleCommand">
<span class="el-dropdown__box">
<el-avatar :src="userInfoStore.userInfo.userPic?userInfoStore.userInfo.userPic:avatar"/>
<el-icon>
<CaretBottom/>
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="info" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="resetPassword" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<!-- 中间区域 -->
<el-main>
<router-view/>
</el-main>
<!-- 底部区域 -->
<el-footer>卓越快递</el-footer>
</el-container>
</el-container>
</template>
<script setup>
import {
CaretBottom,
Crop,
EditPen,
Management,
Promotion,
SwitchButton,
User,
UserFilled
} from '@element-plus/icons-vue'
import avatar from '@/assets/default.png'
import {userInfoService} from "@/api/user";
import {useUserInfoStore} from "@/stores/userInfo";
import {useRouter} from "vue-router";
import {ElMessage, ElMessageBox} from "element-plus";
import {useTokenStore} from "@/stores/token";
const userInfoStore = useUserInfoStore();
const getUserInfo = async () => {
const result = await userInfoService();
userInfoStore.setUserInfo(result.data)
}
getUserInfo()
const router = useRouter();
const tokenStore = useTokenStore();
const handleCommand = (command) => {
if (command === 'logout') {
ElMessageBox.confirm(
'你确认要退出吗?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}
).then(
async () => {
// clear data in pinia
userInfoStore.removeUserInfo()
tokenStore.removeToken()
ElMessage.success("退出成功")
await router.push('/login')
}
)
} else {
router.push('/user/' + command)
}
}
</script>
<style lang="scss" scoped>
.layout-container {
height: 100vh;
<template>
.el-aside {
background-color: #ccccd6;
</template>
&__logo {
height: 120px;
background: url('/logo.png') no-repeat center / 120px auto;
}
.el-menu {
border-right: none;
}
}
.el-header {
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
.el-dropdown__box {
display: flex;
align-items: center;
.el-icon {
color: #999;
margin-left: 10px;
}
<style scoped>
&:active,
&:focus {
outline: none;
}
}
}
.el-footer {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #ccccd6;
}
}
</style>

@ -125,7 +125,7 @@ const login = async () => {
ElMessage.success(result.message ? result.message : '登录成功')
tokenStore.setToken(result.data)
router.push('index')
router.push('Layout')
}
}
@ -136,21 +136,16 @@ const clearRegisterData = () => {
rePassword: ''
}
}
</script>
<style lang="scss" scoped>
/* 样式 */
.login-page {
height: 100vh;
background-color: #fff;
.bg {
background:
url('/login.jpg') no-repeat center / cover; /* 修改了背景图片路径 */
url('/login.jpg') no-repeat center / cover;
border-radius: 0 20px 20px 0;
}

@ -0,0 +1,218 @@
<script setup>
import { Delete, Edit, Plus } from '@element-plus/icons-vue'
import { ref } from 'vue'
import {
expressListService,
expressAddService,
expressUpdateService,
expressDeleteService
} from '@/api/express';
import { ElMessage, ElMessageBox } from "element-plus";
//
const expressList = ref([]);
const visibleDrawer = ref(false);
const drawerTitle = ref('');
const expressModel = ref({
expressid: '',
sename: '',
sephone: '',
seaddress: '',
rename: '',
rephone: '',
readdress: '',
issigned: '',
signtime: '',
});
//
const pageNum = ref(1); //
const total = ref(20); //
const pageSize = ref(3); //
const onSizeChange = (size) => {
pageSize.value = size;
fetchExpressList();
};
const onCurrentChange = (num) => {
pageNum.value = num;
fetchExpressList();
};
const fetchExpressList = async () => {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value,
// ExpressMapperlist
id: null, // ID
sename: '',
sephone: '',
seaddress: '',
rename: '',
rephone: '',
readdress: '',
issigned: '',
signtime: '',
};
try {
const result = await expressListService(params);
expressList.value = result.data.items;
total.value = result.data.total;
} catch (error) {
console.error('获取快递列表失败:', error);
ElMessage.error('获取快递列表失败');
}
};
fetchExpressList();
const showAddDialog = (title) => {
clearData();
drawerTitle.value = title;
visibleDrawer.value = true;
};
const clearData = () => {
expressModel.value = {
expressid: '',
sename: '',
sephone: '',
seaddress: '',
rename: '',
rephone: '',
readdress: '',
issigned: '',
signtime: '',
};
};
const addExpress = async () => {
await expressAddService(expressModel.value);
ElMessage.success('添加成功');
visibleDrawer.value = false;
await fetchExpressList();
};
const showEditDialog = (row, title) => {
visibleDrawer.value = true;
drawerTitle.value = title;
expressModel.value = { ...row };
};
const updateExpress = async () => {
await expressUpdateService(expressModel.value);
ElMessage.success("更新成功");
visibleDrawer.value = false;
await fetchExpressList();
};
const deleteExpress = (row) => {
ElMessageBox.confirm(
'你确认要删除该快递信息吗?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}
).then(async () => {
await expressDeleteService(row.id);
ElMessage.success("删除成功");
await fetchExpressList();
});
};
</script>
<template>
<el-card class="page-container">
<template #header>
<div class="header">
<span>快递管理</span>
<div class="extra">
<el-button type="primary" @click="showAddDialog('添加快递')"></el-button>
</div>
</div>
</template>
<el-table :data="expressList" style="width: 100%">
<el-table-column label="订单号" prop="expressid"></el-table-column>
<el-table-column label="发件人" prop="sename"></el-table-column>
<el-table-column label="发件人电话" prop="sephone"></el-table-column>
<el-table-column label="发件人地址" prop="seaddress"></el-table-column>
<el-table-column label="收件人" prop="rename"></el-table-column>
<el-table-column label="收件人电话" prop="rephone"></el-table-column>
<el-table-column label="收件人地址" prop="readdress"></el-table-column>
<el-table-column label="签收时间" prop="signtime"></el-table-column>
<el-table-column label="状态" prop="issigned"></el-table-column>
<el-table-column label="操作" width="100">
<template #default="{ row }">
<el-button :icon="Edit" circle plain type="primary" @click="showEditDialog(row,'编辑快递')"></el-button>
<el-button :icon="Delete" circle plain type="danger" @click="deleteExpress(row)"></el-button>
</template>
</el-table-column>
<template #empty>
<el-empty description="没有数据" />
</template>
</el-table>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :page-sizes="[3, 5, 10, 15]"
layout="jumper, total, sizes, prev, pager, next" background :total="total"
@size-change="onSizeChange"
@current-change="onCurrentChange" style="margin-top: 20px; justify-content: flex-end"/>
</el-card>
<!-- 抽屉 -->
<el-drawer v-model="visibleDrawer" :title="drawerTitle" direction="rtl" size="50%">
<el-form :model="expressModel" label-width="100px">
<el-form-item label="订单号">
<el-input v-model="expressModel.expressid" placeholder="请输入订单号"></el-input>
</el-form-item>
<el-form-item label="发件人">
<el-input v-model="expressModel.sename" placeholder="请输入发件人"></el-input>
</el-form-item>
<el-form-item label="发件人电话">
<el-input v-model="expressModel.sephone" placeholder="请输入发件人电话"></el-input>
</el-form-item>
<el-form-item label="发件人地址">
<el-input v-model="expressModel.seaddress" placeholder="请输入发件人地址"></el-input>
</el-form-item>
<el-form-item label="收件人">
<el-input v-model="expressModel.rename" placeholder="请输入收件人"></el-input>
</el-form-item>
<el-form-item label="收件人电话">
<el-input v-model="expressModel.rephone" placeholder="请输入收件人电话"></el-input>
</el-form-item>
<el-form-item label="收件人地址">
<el-input v-model="expressModel.readdress" placeholder="请输入收件人地址"></el-input>
</el-form-item>
<el-form-item label="签收时间">
<el-date-picker v-model="expressModel.signtime" type="date" placeholder="请选择签收时间"></el-date-picker>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="expressModel.issigned" placeholder="请选择状态">
<el-option label="未签收" value="0"></el-option>
<el-option label="已签收" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="expressModel.id ? updateExpress() : addExpress()">
{{ expressModel.id ? '更新' : '添加' }}
</el-button>
</el-form-item>
</el-form>
</el-drawer>
</template>
<style lang="scss" scoped>
.page-container {
min-height: 100%;
box-sizing: border-box;
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
}
</style>

@ -1,153 +0,0 @@
<template>
<el-row class="page">
<el-row class="block-view" v-for="(item,index) in expressList">
<el-row class="top">
<el-row> 运单号: {{item.express_no}}</el-row>
<el-row class="top-time"> 签收时间: {{item.s_datetime}}</el-row>
</el-row>
<el-row class="express-view">
<el-row class="express-no-view">
<el-text class="city">
{{item.senderCity}}
</el-text>
<el-text class="user">
{{item.senderName}}
</el-text>
</el-row>
<el-row class="express-no-view">
<el-image class="logo" src="/logo.png"></el-image>
<el-text class="sign">
已签收
</el-text>
</el-row>
<el-row class="express-no-view">
<el-text class="city">
{{item.receiverCity}}
</el-text>
<el-text class="user">
{{item.receiverName}}
</el-text>
</el-row>
<el-row class="express-icon-view">
<el-icon>
<Delete />
</el-icon>
<el-icon>
<Edit />
</el-icon>
</el-row>
</el-row>
<el-row class="line-view"></el-row>
</el-row>
</el-row>
</template>
<script setup>
import {
Delete,
Edit
} from '@element-plus/icons-vue'
import {
reactive
} from 'vue';
const expressList = reactive([{
"express_no": "SF1313131313123",
"senderCity":"深圳市",
"senderName":"冰凉凉1",
"receiverCity":"福州市",
"receiverName":"叶丽丽",
"s_datetime": "2024-10-24 11:58"
},
{
"express_no": "SF1313131313123",
"senderCity":"深圳市",
"senderName":"冰凉凉2",
"receiverCity":"福州市",
"receiverName":"叶丽丽",
"s_datetime": "2024-10-24 11:58"
},
{
"express_no": "SF1313131313123",
"senderCity":"深圳市",
"senderName":"冰凉凉3",
"receiverCity":"福州市",
"receiverName":"叶丽丽",
"s_datetime": "2024-10-24 11:58"
},
{
"express_no": "SF1313131313123",
"senderCity":"深圳市",
"senderName":"冰凉凉4",
"receiverCity":"福州市",
"receiverName":"叶丽丽",
"s_datetime": "2024-10-24 11:58"
}
])
</script>
<style>
.page {
display: flex;
flex-direction: column;
width: 100%;
background-color: white;
line-height: 20px;
}
.block-view {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.top {
display: flex;
justify-content: flex-start;
width: 100%;
padding-left: 20px;
color: gray;
font-size: 12px;
}
.top-time {
margin-left: 120px;
}
.express-view {
display: flex;
flex-flow: row;
justify-content: space-around;
width: 100%;
}
.express-no-view {
display: flex;
flex-direction: column;
}
.logo {
width: 40px;
height: 10px;
}
.city {
font-size: 20px;
margin-bottom: 10px;
}
.user {
color: gray;
}
.sign {
color: red;
margin-top: 10px;
}
.express-icon-view {
width: 10%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.line-view {
height: 0.5px;
width: 95%;
background-color: lightgray;
margin-top: 20px;
margin-bottom: 20px;
}
</style>

@ -1,4 +1,3 @@
<template>
<div>
<el-row class="top">
@ -8,16 +7,13 @@
<el-row class="body">
<el-image class="user-img" src="/user.jpg"></el-image>
<el-text class="phone">13456789000</el-text>
<el-form label-width="auto" style="max-width: 600px">
<el-form-item label="性别">
<el-select placeholder="男">
<el-option>
<el-radio-group v-model="radio1">
<el-radio value="Value 1"></el-radio>
<el-radio value="Label 2&Label 2"></el-radio>
<el-radio value="male"></el-radio>
<el-radio value="female"></el-radio>
</el-radio-group>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="生日">
<el-date-picker
@ -27,21 +23,63 @@
/>
</el-form-item>
<el-form-item label="地区">
<el-input></el-input>
<el-input v-model="region"></el-input>
</el-form-item>
<el-form-item label="绑定手机">
<el-input></el-input>
<el-input v-model="phone"></el-input>
</el-form-item>
<el-form :model="userInfo" :rules="rules" label-width="100px" size="large">
<el-form-item label="登录名称">
<el-input v-model="userInfo.username" disabled></el-input>
</el-form-item>
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="userInfo.nickname"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateUserInfo"></el-button>
</el-form-item>
</el-form>
</el-form>
</el-row>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useUserInfoStore } from "@/stores/userInfo.js";
import { userInfoUpdateService } from "@/api/user";
import { ElMessage } from "element-plus";
const value1 = ref('new Date()')
const value1 = ref('')
const radio1 = ref('male') // radio1'male'
const region = ref('')
const phone = ref('')
const userInfoStore = useUserInfoStore();
const userInfo = ref({
...userInfoStore.userInfo
})
const rules = {
nickname: [
{ required: true, message: '请输入用户昵称', trigger: 'blur' },
{
pattern: /^\S{2,10}$/,
message: '昵称必须是2-10位的非空字符串',
trigger: 'blur'
}
],
}
const updateUserInfo = async () => {
try {
await userInfoUpdateService(userInfo.value);
ElMessage.success('修改成功')
userInfoStore.setUserInfo(userInfo.value)
} catch (error) {
ElMessage.error('修改失败')
console.error(error)
}
}
</script>
<style>

@ -14,9 +14,6 @@
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="userInfo.nickname"></el-input>
</el-form-item>
<el-form-item label="用户邮箱" prop="email">
<el-input v-model="userInfo.email"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateUserInfo"></el-button>
</el-form-item>
@ -46,10 +43,6 @@ const rules = {
trigger: 'blur'
}
],
email: [
{required: true, message: '请输入用户邮箱', trigger: 'blur'},
{type: 'email', message: '邮箱格式不正确', trigger: 'blur'}
]
}
const updateUserInfo = () => {

@ -0,0 +1,19 @@
import request from "@/utils/request";
export const expressListService = (params) => {
return request.get('/express', {params})
}
export const expressAddService = (expressData) => {
return request.post('/express', expressData)
}
export const expressUpdateService = (expressData) => {
return request.put('/express', expressData)
}
export const expressDeleteService = (id) => {
return request.delete('/express?id=' + id)
}

@ -34,3 +34,4 @@ export const userPwdUpdateService = (pwdData) => {
return request.patch('/user/updatePwd', pwdData)
}

@ -2,7 +2,7 @@ import {
createRouter,
createWebHashHistory
} from "vue-router"
import {userStore} from "./stores"
import {storeToRefs} from "pinia"
const router = createRouter({
@ -34,11 +34,11 @@ const router = createRouter({
},
{
path: '/expressList',
component: () => import('./View/user/ExpressList.vue')
component: () => import('./View/express/ExpressList.vue')
},
{
path: '/expressForm',
component: () => import('./View/user/ExpressForm.vue')
component: () => import('./View/express/ExpressForm.vue')
}
]
},

@ -1,14 +1,14 @@
import { defineStore } from "pinia";
export const userStore=defineStore('storeId',{
state(){
return{
loginState:false//已登录为true未登录为false
}
},
getters:{},
actions:{
setLoginState(state){
this.loginState=state
}
}
})
// import { defineStore } from "pinia";
// export const userStore=defineStore('storeId',{
// state(){
// return{
// loginState:false//已登录为true未登录为false
// }
// },
// getters:{},
// actions:{
// setLoginState(state){
// this.loginState=state
// }
// }
// })
Loading…
Cancel
Save