mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-09-17 10:56:39 +08:00
【smart-app更新】1、意见反馈;2、我的;3、退出登录;4、等等其他
This commit is contained in:
parent
4b36de6de5
commit
83d316a2d1
@ -10,8 +10,9 @@
|
|||||||
- 前端:Vue3 + Vite5 + Vue-Router + Pinia + Ant Design Vue 4.X
|
- 前端:Vue3 + Vite5 + Vue-Router + Pinia + Ant Design Vue 4.X
|
||||||
- 移动端:uniapp (vue3版本) + uni-ui + (同时支持APP、小程序、H5)
|
- 移动端:uniapp (vue3版本) + uni-ui + (同时支持APP、小程序、H5)
|
||||||
- 后端:SpringBoot + Sa Token + Mybatis-plus + 多种数据库
|
- 后端:SpringBoot + Sa Token + Mybatis-plus + 多种数据库
|
||||||
- 在线预览:[https://preview.smartadmin.vip](https://preview.smartadmin.vip)
|
- 电脑在线预览:[https://preview.smartadmin.vip](https://preview.smartadmin.vip)
|
||||||
- 官方文档:[https://smartadmin.vip](https://smartadmin.vip)
|
- 官方文档:[https://smartadmin.vip](https://smartadmin.vip)
|
||||||
|
- 移动端在线预览:[https://app.smartadmin.vip](https://app.smartadmin.vip)
|
||||||
### **理念与思想**
|
### **理念与思想**
|
||||||
|
|
||||||
- 我们分享的不是徒劳无功的各种功能,而是必须有的功能,如:网络安全、数据变动记录、系统说明文档、版本更新记录、意见反馈、日志、心跳、单号生成器等等。
|
- 我们分享的不是徒劳无功的各种功能,而是必须有的功能,如:网络安全、数据变动记录、系统说明文档、版本更新记录、意见反馈、日志、心跳、单号生成器等等。
|
||||||
|
@ -44,11 +44,9 @@ public class NoticeVO {
|
|||||||
private LocalDateTime publishTime;
|
private LocalDateTime publishTime;
|
||||||
|
|
||||||
@Schema(description = "作者")
|
@Schema(description = "作者")
|
||||||
@NotBlank(message = "作者不能为空")
|
|
||||||
private String author;
|
private String author;
|
||||||
|
|
||||||
@Schema(description = "来源")
|
@Schema(description = "来源")
|
||||||
@NotBlank(message = "标题不能为空")
|
|
||||||
private String source;
|
private String source;
|
||||||
|
|
||||||
@Schema(description = "文号")
|
@Schema(description = "文号")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.lab1024.sa.admin.module.system.login.controller;
|
package net.lab1024.sa.admin.module.system.login.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -47,7 +48,10 @@ public class LoginController {
|
|||||||
@GetMapping("/login/getLoginInfo")
|
@GetMapping("/login/getLoginInfo")
|
||||||
@Operation(summary = "获取登录结果信息 @author 卓大")
|
@Operation(summary = "获取登录结果信息 @author 卓大")
|
||||||
public ResponseDTO<LoginResultVO> getLoginInfo() {
|
public ResponseDTO<LoginResultVO> getLoginInfo() {
|
||||||
return ResponseDTO.ok(loginService.getLoginResult(AdminRequestUtil.getRequestUser()));
|
LoginResultVO loginResult = loginService.getLoginResult(AdminRequestUtil.getRequestUser());
|
||||||
|
String tokenValue = StpUtil.getTokenValue();
|
||||||
|
loginResult.setToken(tokenValue);
|
||||||
|
return ResponseDTO.ok(loginResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "退出登陆 @author 卓大")
|
@Operation(summary = "退出登陆 @author 卓大")
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
<if test="query.keywords != null and query.keywords !=''">
|
<if test="query.keywords != null and query.keywords !=''">
|
||||||
AND ( INSTR(t_notice.title,#{query.keywords})
|
AND ( INSTR(t_notice.title,#{query.keywords})
|
||||||
OR INSTR(t_notice.author,#{query.keywords})
|
OR INSTR(t_notice.author,#{query.keywords})
|
||||||
OR INSTR(t_notice.documentNumber,#{query.keywords})
|
OR INSTR(t_notice.document_number,#{query.keywords})
|
||||||
OR INSTR(t_notice.source,#{query.keywords})
|
OR INSTR(t_notice.source,#{query.keywords})
|
||||||
)
|
)
|
||||||
</if>
|
</if>
|
||||||
|
@ -25,12 +25,12 @@ public class PageParam {
|
|||||||
|
|
||||||
@Schema(description = "页码(不能为空)", example = "1")
|
@Schema(description = "页码(不能为空)", example = "1")
|
||||||
@NotNull(message = "分页参数不能为空")
|
@NotNull(message = "分页参数不能为空")
|
||||||
private Integer pageNum;
|
private Long pageNum;
|
||||||
|
|
||||||
@Schema(description = "每页数量(不能为空)", example = "10")
|
@Schema(description = "每页数量(不能为空)", example = "10")
|
||||||
@NotNull(message = "每页数量不能为空")
|
@NotNull(message = "每页数量不能为空")
|
||||||
@Max(value = 200, message = "每页最大为200")
|
@Max(value = 500, message = "每页最大为500")
|
||||||
private Integer pageSize;
|
private Long pageSize;
|
||||||
|
|
||||||
@Schema(description = "是否查询总条数")
|
@Schema(description = "是否查询总条数")
|
||||||
protected Boolean searchCount;
|
protected Boolean searchCount;
|
||||||
|
@ -9,9 +9,7 @@ import net.lab1024.sa.base.constant.SwaggerTagConst;
|
|||||||
import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogQueryForm;
|
import net.lab1024.sa.base.module.support.changelog.domain.form.ChangeLogQueryForm;
|
||||||
import net.lab1024.sa.base.module.support.changelog.domain.vo.ChangeLogVO;
|
import net.lab1024.sa.base.module.support.changelog.domain.vo.ChangeLogVO;
|
||||||
import net.lab1024.sa.base.module.support.changelog.service.ChangeLogService;
|
import net.lab1024.sa.base.module.support.changelog.service.ChangeLogService;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
@ -36,4 +34,11 @@ public class ChangeLogController extends SupportBaseController {
|
|||||||
public ResponseDTO<PageResult<ChangeLogVO>> queryPage(@RequestBody @Valid ChangeLogQueryForm queryForm) {
|
public ResponseDTO<PageResult<ChangeLogVO>> queryPage(@RequestBody @Valid ChangeLogQueryForm queryForm) {
|
||||||
return ResponseDTO.ok(changeLogService.queryPage(queryForm));
|
return ResponseDTO.ok(changeLogService.queryPage(queryForm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(summary = "变更内容详情 @author 卓大")
|
||||||
|
@GetMapping("/changeLog/getDetail/{changeLogId}")
|
||||||
|
public ResponseDTO<ChangeLogVO> getDetail(@PathVariable Long changeLogId) {
|
||||||
|
return ResponseDTO.ok(changeLogService.getById(changeLogId));
|
||||||
|
}
|
||||||
}
|
}
|
@ -33,7 +33,6 @@ public class ChangeLogService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询
|
* 分页查询
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public PageResult<ChangeLogVO> queryPage(ChangeLogQueryForm queryForm) {
|
public PageResult<ChangeLogVO> queryPage(ChangeLogQueryForm queryForm) {
|
||||||
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
|
||||||
@ -57,7 +56,6 @@ public class ChangeLogService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新
|
* 更新
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public synchronized ResponseDTO<String> update(ChangeLogUpdateForm updateForm) {
|
public synchronized ResponseDTO<String> update(ChangeLogUpdateForm updateForm) {
|
||||||
ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getVersion());
|
ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getVersion());
|
||||||
@ -71,7 +69,6 @@ public class ChangeLogService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除
|
* 批量删除
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public synchronized ResponseDTO<String> batchDelete(List<Long> idList) {
|
public synchronized ResponseDTO<String> batchDelete(List<Long> idList) {
|
||||||
if (CollectionUtils.isEmpty(idList)) {
|
if (CollectionUtils.isEmpty(idList)) {
|
||||||
@ -93,4 +90,8 @@ public class ChangeLogService {
|
|||||||
changeLogDao.deleteById(changeLogId);
|
changeLogDao.deleteById(changeLogId);
|
||||||
return ResponseDTO.ok();
|
return ResponseDTO.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChangeLogVO getById(Long changeLogId) {
|
||||||
|
return SmartBeanUtil.copy(changeLogDao.selectById(changeLogId), ChangeLogVO.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,22 +65,6 @@ server:
|
|||||||
pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)"
|
pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)"
|
||||||
|
|
||||||
|
|
||||||
# 文件上传 配置
|
|
||||||
#file:
|
|
||||||
# storage:
|
|
||||||
# mode: local
|
|
||||||
# local:
|
|
||||||
# upload-path: /home/smart_admin_v3/upload/ #文件上传目录
|
|
||||||
# url-prefix:
|
|
||||||
# cloud:
|
|
||||||
# region: oss-cn-qingdao
|
|
||||||
# endpoint: oss-cn-qingdao.aliyuncs.com
|
|
||||||
# bucket-name: common
|
|
||||||
# access-key:
|
|
||||||
# secret-key:
|
|
||||||
# url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
|
|
||||||
# private-url-expire-seconds: 3600
|
|
||||||
|
|
||||||
# 文件上传 配置
|
# 文件上传 配置
|
||||||
file:
|
file:
|
||||||
storage:
|
storage:
|
||||||
@ -97,6 +81,7 @@ file:
|
|||||||
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
|
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
|
||||||
private-url-expire-seconds: 3600
|
private-url-expire-seconds: 3600
|
||||||
|
|
||||||
|
|
||||||
# open api配置
|
# open api配置
|
||||||
springdoc:
|
springdoc:
|
||||||
swagger-ui:
|
swagger-ui:
|
||||||
|
22463
smart-app/package-lock.json
generated
Normal file
22463
smart-app/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
smart-app/src/api/support/feedback-api.js
Normal file
17
smart-app/src/api/support/feedback-api.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* 意见反馈
|
||||||
|
*
|
||||||
|
* @Author: 1024创新实验室:开云
|
||||||
|
* @Date: 2022-09-03 21:56:31
|
||||||
|
* @Wechat: zhuda1024
|
||||||
|
* @Email: lab1024@163.com
|
||||||
|
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||||
|
*/
|
||||||
|
import { postRequest } from '/src/lib/smart-request';
|
||||||
|
|
||||||
|
export const feedbackApi = {
|
||||||
|
// 意见反馈-新增
|
||||||
|
addFeedback: (params) => {
|
||||||
|
return postRequest('/support/feedback/add', params);
|
||||||
|
},
|
||||||
|
};
|
14
smart-app/src/api/support/file-api.js
Normal file
14
smart-app/src/api/support/file-api.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* 系统更新日志 api 封装
|
||||||
|
*
|
||||||
|
* @Author: 卓大
|
||||||
|
* @Date: 2022-09-26 14:53:50
|
||||||
|
* @Copyright 1024创新实验室
|
||||||
|
*/
|
||||||
|
import { uploadRequest } from '/@/lib/smart-request';
|
||||||
|
|
||||||
|
export const fileApi = {
|
||||||
|
upload: (file, folder) => {
|
||||||
|
return uploadRequest(file, folder);
|
||||||
|
},
|
||||||
|
};
|
@ -12,6 +12,7 @@ import loginDevice from './system/login-device-const';
|
|||||||
import enterpriseConst from './business/oa/enterprise-const';
|
import enterpriseConst from './business/oa/enterprise-const';
|
||||||
import goodsConst from './business/erp/goods-const';
|
import goodsConst from './business/erp/goods-const';
|
||||||
import changeLogConst from './support/change-log-const';
|
import changeLogConst from './support/change-log-const';
|
||||||
|
import fileConst from './support/file-const';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
FLAG_NUMBER_ENUM,
|
FLAG_NUMBER_ENUM,
|
||||||
@ -21,4 +22,5 @@ export default {
|
|||||||
...enterpriseConst,
|
...enterpriseConst,
|
||||||
...goodsConst,
|
...goodsConst,
|
||||||
...changeLogConst,
|
...changeLogConst,
|
||||||
|
...fileConst,
|
||||||
};
|
};
|
||||||
|
31
smart-app/src/constants/support/file-const.js
Normal file
31
smart-app/src/constants/support/file-const.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 文件类型
|
||||||
|
*
|
||||||
|
* @Author: 1024创新实验室-主任:卓大
|
||||||
|
* @Date: 2022-09-03 22:09:10
|
||||||
|
* @Wechat: zhuda1024
|
||||||
|
* @Email: lab1024@163.com
|
||||||
|
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||||
|
*/
|
||||||
|
// 文件上传类型
|
||||||
|
export const FILE_FOLDER_TYPE_ENUM = {
|
||||||
|
COMMON: {
|
||||||
|
value: 1,
|
||||||
|
desc: '通用',
|
||||||
|
},
|
||||||
|
NOTICE: {
|
||||||
|
value: 2,
|
||||||
|
desc: '公告',
|
||||||
|
},
|
||||||
|
HELP_DOC: {
|
||||||
|
value: 3,
|
||||||
|
desc: '帮助中心',
|
||||||
|
},
|
||||||
|
FEEDBACK: {
|
||||||
|
value: 4,
|
||||||
|
desc: '意见反馈',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export default {
|
||||||
|
FILE_FOLDER_TYPE_ENUM,
|
||||||
|
};
|
@ -23,18 +23,9 @@ function getUserToken() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用请求封装
|
* 处理返回的消息
|
||||||
*/
|
*/
|
||||||
export const request = function (url, method, data) {
|
function handleResponse(response, resolve, reject) {
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
uni.request({
|
|
||||||
url: baseUrl + url, //拼接请求路径
|
|
||||||
data: data,
|
|
||||||
method: method,
|
|
||||||
header: {
|
|
||||||
'x-access-token': getUserToken(),
|
|
||||||
},
|
|
||||||
success: (response) => {
|
|
||||||
// 如果是加密数据
|
// 如果是加密数据
|
||||||
if (response.data.dataType === DATA_TYPE_ENUM.ENCRYPT.value) {
|
if (response.data.dataType === DATA_TYPE_ENUM.ENCRYPT.value) {
|
||||||
response.data.encryptData = response.data.data;
|
response.data.encryptData = response.data.data;
|
||||||
@ -64,6 +55,22 @@ export const request = function (url, method, data) {
|
|||||||
} else {
|
} else {
|
||||||
resolve(res);
|
resolve(res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用请求封装
|
||||||
|
*/
|
||||||
|
export const request = function (url, method, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.request({
|
||||||
|
url: baseUrl + url, //拼接请求路径
|
||||||
|
data: data,
|
||||||
|
method: method,
|
||||||
|
header: {
|
||||||
|
'x-access-token': getUserToken(),
|
||||||
|
},
|
||||||
|
success: (response) => {
|
||||||
|
handleResponse(response, resolve, reject);
|
||||||
},
|
},
|
||||||
fail: (error) => {
|
fail: (error) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
@ -94,3 +101,28 @@ export const postRequest = (url, data) => {
|
|||||||
export const postEncryptRequest = (url, data) => {
|
export const postEncryptRequest = (url, data) => {
|
||||||
return request(url, 'POST', { encryptData: encryptData(data) });
|
return request(url, 'POST', { encryptData: encryptData(data) });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ================================= 文件 =================================
|
||||||
|
|
||||||
|
export const uploadRequest = function (filePath, folder) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: baseUrl + '/support/file/upload',
|
||||||
|
filePath,
|
||||||
|
header: {
|
||||||
|
'x-access-token': getUserToken(),
|
||||||
|
},
|
||||||
|
name: 'file',
|
||||||
|
formData: {
|
||||||
|
folder,
|
||||||
|
},
|
||||||
|
success: (response) => {
|
||||||
|
response.data = JSON.parse(response.data.replace('\uFEFF', ''));
|
||||||
|
handleResponse(response, resolve, reject);
|
||||||
|
},
|
||||||
|
fail: (error) => {
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/home/index",
|
"path": "pages/home/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle":"custom"
|
"navigationStyle":"custom",
|
||||||
|
"navigationBarTitleText": "首页"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -135,7 +136,7 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText" : "常见列表样式1",
|
"navigationBarTitleText" : "常见列表样式1",
|
||||||
"enablePullDownRefresh" : false,
|
"enablePullDownRefresh" : false,
|
||||||
"navigationStyle": "custom"
|
"navigationBarBackgroundColor": "#fff"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -155,6 +156,15 @@
|
|||||||
"enablePullDownRefresh" : false,
|
"enablePullDownRefresh" : false,
|
||||||
"navigationBarBackgroundColor": "#fff"
|
"navigationBarBackgroundColor": "#fff"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "pages/support/feedback/feedback-form",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "意见反馈",
|
||||||
|
"enablePullDownRefresh" : false,
|
||||||
|
"navigationBarBackgroundColor": "#fff"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
@ -178,7 +188,7 @@
|
|||||||
"pagePath": "pages/list/list",
|
"pagePath": "pages/list/list",
|
||||||
"iconPath": "static/images/tabbar/list-icon.png",
|
"iconPath": "static/images/tabbar/list-icon.png",
|
||||||
"selectedIconPath": "static/images/tabbar/list-icon-h.png",
|
"selectedIconPath": "static/images/tabbar/list-icon-h.png",
|
||||||
"text": "常见列表"
|
"text": "常见列表1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/list2/list",
|
"pagePath": "pages/list2/list",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="menu-container">
|
<view class="menu-container">
|
||||||
<uni-grid :column="5" :highlight="true" :showBorder="false">
|
<uni-grid :column="5" :highlight="true" :show-border="false" customStyle="display: block;">
|
||||||
<!--------------------------------- 第一排--------------------------------->
|
<!--------------------------------- 第一排--------------------------------->
|
||||||
<uni-grid-item class="menu-grid">
|
<uni-grid-item class="menu-grid">
|
||||||
<view class="menu-item" @click="changeHome">
|
<view class="menu-item" @click="changeHome">
|
||||||
@ -61,9 +61,9 @@
|
|||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
</uni-grid-item>
|
||||||
<uni-grid-item class="menu-grid">
|
<uni-grid-item class="menu-grid">
|
||||||
<view class="menu-item" @click="navigateTo('/pages/change-log/change-log-list')">
|
<view class="menu-item" @click="developing">
|
||||||
<image class="item-image" src="/@/static/images/index/ic_home_menu10.png"></image>
|
<image class="item-image" src="/@/static/images/index/ic_home_menu10.png"></image>
|
||||||
<view class="item-text"> 加密安全 </view>
|
<view class="item-text"> 接口加密 </view>
|
||||||
</view>
|
</view>
|
||||||
</uni-grid-item>
|
</uni-grid-item>
|
||||||
</uni-grid>
|
</uni-grid>
|
||||||
@ -71,6 +71,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { SmartToast } from '/@/lib/smart-support';
|
||||||
const emit = defineEmits(['changeHome']);
|
const emit = defineEmits(['changeHome']);
|
||||||
|
|
||||||
function changeHome() {
|
function changeHome() {
|
||||||
@ -87,6 +88,10 @@
|
|||||||
url,
|
url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function developing() {
|
||||||
|
SmartToast.toast('敬请期待');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -110,6 +115,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
width: 134rpx;
|
||||||
|
height: 134rpx;
|
||||||
.item-image {
|
.item-image {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
|
@ -37,15 +37,23 @@
|
|||||||
import Notice from './components/notice.vue';
|
import Notice from './components/notice.vue';
|
||||||
import Goods from './components/goods.vue';
|
import Goods from './components/goods.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { onShow } from '@dcloudio/uni-app';
|
||||||
|
|
||||||
const showBannerFlag = ref(false);
|
const showBannerFlag = ref(false);
|
||||||
function changeHome() {
|
function changeHome() {
|
||||||
showBannerFlag.value = !showBannerFlag.value;
|
showBannerFlag.value = !showBannerFlag.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
uni.pageScrollTo({
|
||||||
|
scrollTop: 0,
|
||||||
|
duration: 300,
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
page {
|
.page {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<y-tabs v-model="active" sticky :offsetTop="0" color="#007aff">
|
<y-tabs v-model="active" sticky :offsetTop="43" color="#007aff">
|
||||||
<y-tab class="y-tab-virtual" v-for="item in tabsList" :key="item.value" :title="item.title"> </y-tab>
|
<y-tab v-for="item in tabsList" :key="item.value" :title="item.title"> </y-tab>
|
||||||
</y-tabs>
|
</y-tabs>
|
||||||
|
|
||||||
<ListUI1 v-if="active === 0" />
|
<ListUI1 v-if="active === 0" />
|
||||||
@ -42,25 +42,6 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
page {
|
page {
|
||||||
background: #f5f6f8;
|
background-color: #f5f5f5;
|
||||||
}
|
|
||||||
.input {
|
|
||||||
width: 526rpx;
|
|
||||||
height: 72rpx;
|
|
||||||
background: #f7f8f9;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8rpx 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
icon {
|
|
||||||
margin-left: 20rpx;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
margin-left: 8rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
.placeolder-input {
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<y-tabs v-model="active" sticky :offsetTop="0" color="#007aff">
|
<view>
|
||||||
<y-tab class="y-tab-virtual" v-for="item in tabsList" :key="item.value" :title="item.title"> </y-tab>
|
<y-tabs v-model="active" sticky :offsetTop="43" color="#007aff">
|
||||||
|
<y-tab v-for="item in tabsList" :key="item.value" :title="item.title"> </y-tab>
|
||||||
</y-tabs>
|
</y-tabs>
|
||||||
|
|
||||||
<ExpressList v-if="active === 0" />
|
<ExpressList v-if="active === 0" />
|
||||||
@ -8,6 +9,7 @@
|
|||||||
<IotList v-if="active === 2" />
|
<IotList v-if="active === 2" />
|
||||||
<ServiceList v-if="active === 3" />
|
<ServiceList v-if="active === 3" />
|
||||||
<CourseList v-if="active === 4" />
|
<CourseList v-if="active === 4" />
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -48,6 +50,6 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
page {
|
page {
|
||||||
background: #f5f6f8;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const agreeFlag = ref(false);
|
const agreeFlag = ref(true);
|
||||||
|
|
||||||
function agree() {
|
function agree() {
|
||||||
agreeFlag.value = !agreeFlag.value;
|
agreeFlag.value = !agreeFlag.value;
|
||||||
@ -38,14 +38,14 @@
|
|||||||
.check-item {
|
.check-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: $small-size;
|
font-size: 12px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
margin-bottom: 7px;
|
margin-bottom: 20rpx;
|
||||||
|
|
||||||
image {
|
image {
|
||||||
width: 17px;
|
width: 24px;
|
||||||
height: 17px;
|
height: 24px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { nextTick, reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { onShow } from '@dcloudio/uni-app';
|
import { onShow } from '@dcloudio/uni-app';
|
||||||
import OtherWayBox from './components/other-way-box.vue';
|
import OtherWayBox from './components/other-way-box.vue';
|
||||||
import LoginCheckBox from './components/login-check-box.vue';
|
import LoginCheckBox from './components/login-check-box.vue';
|
||||||
@ -292,9 +292,8 @@
|
|||||||
|
|
||||||
.login-check-box {
|
.login-check-box {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-top: 69px;
|
margin-top: 150rpx;
|
||||||
margin-bottom: 63px;
|
margin-bottom: 120rpx;
|
||||||
margin-left: 22px;
|
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -7,18 +7,18 @@
|
|||||||
<image class="icon" src="/static/images/mine/mine-account.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-account.png" mode=""></image>
|
||||||
</template>
|
</template>
|
||||||
</uni-list-item>
|
</uni-list-item>
|
||||||
<uni-list-item title="消息通知" link showBadge badgeText="6" badgeType="error" @click="gotoMessage">
|
<uni-list-item title="消息通知" link="switchTab" showBadge badgeText="6" badgeType="error" to="/pages/message/message">
|
||||||
<template #header>
|
<template #header>
|
||||||
<image class="icon" src="/static/images/mine/mine-message.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-message.png" mode=""></image>
|
||||||
</template>
|
</template>
|
||||||
</uni-list-item>
|
</uni-list-item>
|
||||||
|
|
||||||
<uni-list-item title="意见反馈" link rightText="欢迎吐槽" showBadge>
|
<uni-list-item title="意见反馈" link rightText="欢迎吐槽" showBadge to="/pages/support/feedback/feedback-form">
|
||||||
<template #header>
|
<template #header>
|
||||||
<image class="icon" src="/static/images/mine/mine-feedback.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-feedback.png" mode=""></image>
|
||||||
</template>
|
</template>
|
||||||
</uni-list-item>
|
</uni-list-item>
|
||||||
<uni-list-item title="联系客服" showBadge>
|
<uni-list-item title="联系客服" showBadge clickable @click="callService">
|
||||||
<template #header>
|
<template #header>
|
||||||
<image class="icon" src="/static/images/mine/mine-service.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-service.png" mode=""></image>
|
||||||
</template>
|
</template>
|
||||||
@ -56,9 +56,9 @@
|
|||||||
<image class="icon" src="/static/images/mine/mine-about-us.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-about-us.png" mode=""></image>
|
||||||
</template>
|
</template>
|
||||||
</uni-list-item>
|
</uni-list-item>
|
||||||
<uni-list-item title="设置" link showBadge>
|
<uni-list-item title="设置" showBadge clickable @click="developing">
|
||||||
<template #header>
|
<template #header>
|
||||||
<image class="icon" src="/static/images/mine/mine-protocol.png" mode=""></image>
|
<image class="icon" src="/static/images/mine/mine-protocol.png"></image>
|
||||||
</template>
|
</template>
|
||||||
</uni-list-item>
|
</uni-list-item>
|
||||||
</uni-list>
|
</uni-list>
|
||||||
@ -66,14 +66,22 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { SmartToast } from '/@/lib/smart-support';
|
||||||
|
|
||||||
const emits = defineEmits(['changeStyle']);
|
const emits = defineEmits(['changeStyle']);
|
||||||
|
|
||||||
function changeStyle() {
|
function changeStyle() {
|
||||||
emits('changeStyle');
|
emits('changeStyle');
|
||||||
}
|
}
|
||||||
|
|
||||||
function gotoMessage() {
|
function developing() {
|
||||||
uni.switchTab({ url: '/pages/message/message' });
|
SmartToast.toast('敬请期待');
|
||||||
|
}
|
||||||
|
|
||||||
|
function callService() {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: '18637925892',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -18,12 +18,30 @@
|
|||||||
import MineUserBlue from './components/mine-user-blue.vue';
|
import MineUserBlue from './components/mine-user-blue.vue';
|
||||||
import MineUserWhite from './components/mine-user-white.vue';
|
import MineUserWhite from './components/mine-user-white.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
const logout = () => {};
|
import { useUserStore } from '/@/store/modules/system/user';
|
||||||
|
import { SmartLoading, SmartToast } from '/@/lib/smart-support';
|
||||||
|
import { smartSentry } from '/@/lib/smart-sentry';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
const blueUserFlag = ref(true);
|
const blueUserFlag = ref(true);
|
||||||
function onChangeStyle() {
|
function onChangeStyle() {
|
||||||
blueUserFlag.value = !blueUserFlag.value;
|
blueUserFlag.value = !blueUserFlag.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function logout() {
|
||||||
|
try {
|
||||||
|
setTimeout(() => {
|
||||||
|
userStore.logout();
|
||||||
|
uni.navigateTo({ url: '/pages/login/login' });
|
||||||
|
}, 500);
|
||||||
|
await SmartLoading.show();
|
||||||
|
SmartToast.toast('退出成功');
|
||||||
|
} catch (e) {
|
||||||
|
smartSentry.captureError(e);
|
||||||
|
} finally {
|
||||||
|
SmartLoading.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
@ -37,13 +55,12 @@
|
|||||||
margin: 24px 27px 50px;
|
margin: 24px 27px 50px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
background: #ffffff;
|
background: $uni-color-error;
|
||||||
border-radius: 22px;
|
border-radius: 22px;
|
||||||
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
|
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 44px;
|
line-height: 44px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #353535;
|
color: white;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
168
smart-app/src/pages/support/feedback/feedback-form.vue
Normal file
168
smart-app/src/pages/support/feedback/feedback-form.vue
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="smart-form">
|
||||||
|
<uni-forms ref="formRef" :label-width="100" :modelValue="form" label-position="left" :rules="rules">
|
||||||
|
<view class="smart-form-group">
|
||||||
|
<view class="smart-form-group-title"> 反馈内容 </view>
|
||||||
|
<view class="smart-form-group-content">
|
||||||
|
<uni-forms-item class="smart-form-item" label="意见反馈:" name="feedbackContent" required>
|
||||||
|
<uni-easyinput type="textarea" trim="all" v-model="form.feedbackContent" placeholder="请输入 宝贵的意见和建议" />
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item class="smart-form-item" label="相关图片:" name="unifiedSocialCreditCode">
|
||||||
|
<uni-file-picker
|
||||||
|
limit="9"
|
||||||
|
title="最多选择9个图片"
|
||||||
|
@delete="onDeleteFile"
|
||||||
|
v-model="feedbackFile"
|
||||||
|
@select="onSelectFile"
|
||||||
|
></uni-file-picker>
|
||||||
|
</uni-forms-item>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-forms>
|
||||||
|
|
||||||
|
<view class="smart-form-submit smart-margin-top20 bottom-button">
|
||||||
|
<button class="smart-form-submit-btn smart-margin-right20" type="default" @click="cancel">取消</button>
|
||||||
|
<button class="smart-form-submit-btn" type="primary" @click="submit">保存</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
|
||||||
|
import { smartSentry } from '/@/lib/smart-sentry';
|
||||||
|
import { SmartLoading, SmartToast } from '/@/lib/smart-support';
|
||||||
|
import { onLoad, onReady } from '@dcloudio/uni-app';
|
||||||
|
import { fileApi } from '/@/api/support/file-api';
|
||||||
|
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { feedbackApi } from '/@/api/support/feedback-api';
|
||||||
|
|
||||||
|
// --------------------- 表单 ---------------------
|
||||||
|
|
||||||
|
const defaultFormData = {
|
||||||
|
feedbackContent: '',
|
||||||
|
feedbackAttachment: [],
|
||||||
|
};
|
||||||
|
let form = reactive({ ...defaultFormData });
|
||||||
|
const feedbackFile = ref([]);
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
feedbackContent: {
|
||||||
|
rules: [{ required: true, errorMessage: '请输入反馈意见' }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------- 文件 ---------------------
|
||||||
|
function onSelectFile(param) {
|
||||||
|
let tempFilePaths = param.tempFilePaths;
|
||||||
|
for (const tempFilePath of tempFilePaths) {
|
||||||
|
upload(tempFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(param, 2);
|
||||||
|
console.log(feedbackFile, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upload(tempFilePath) {
|
||||||
|
try {
|
||||||
|
SmartLoading.show();
|
||||||
|
let res = await fileApi.upload(tempFilePath, FILE_FOLDER_TYPE_ENUM.FEEDBACK.value);
|
||||||
|
res.data.tempFilePath = tempFilePath;
|
||||||
|
form.feedbackAttachment.push(res.data);
|
||||||
|
} catch (e) {
|
||||||
|
smartSentry.captureError(e);
|
||||||
|
} finally {
|
||||||
|
SmartLoading.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeleteFile(param) {
|
||||||
|
if (!param.tempFilePath) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_.remove(form.feedbackAttachment, (e) => e.tempFilePath === param.tempFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------- 详情 ---------------------
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
if (options.enterpriseId) {
|
||||||
|
form.enterpriseId = options.enterpriseId;
|
||||||
|
getDetail(options.enterpriseId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onReady(() => {
|
||||||
|
if (form.enterpriseId) {
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: '修改客户',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getDetail(id) {
|
||||||
|
try {
|
||||||
|
SmartLoading.show();
|
||||||
|
let res = await enterpriseApi.detail(id);
|
||||||
|
form.enterpriseId = res.data.enterpriseId;
|
||||||
|
form.enterpriseName = res.data.enterpriseName;
|
||||||
|
form.unifiedSocialCreditCode = res.data.unifiedSocialCreditCode;
|
||||||
|
form.type = res.data.type;
|
||||||
|
form.contact = res.data.contact;
|
||||||
|
form.contactPhone = res.data.contactPhone;
|
||||||
|
form.email = res.data.email;
|
||||||
|
form.address = res.data.address;
|
||||||
|
} catch (e) {
|
||||||
|
smartSentry.captureError(e);
|
||||||
|
} finally {
|
||||||
|
SmartLoading.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------- 表单操作 ------------------------
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
function cancel() {
|
||||||
|
close();
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定
|
||||||
|
function submit() {
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(async () => {
|
||||||
|
SmartLoading.show();
|
||||||
|
try {
|
||||||
|
await feedbackApi.addFeedback(form);
|
||||||
|
SmartToast.success('提交反馈成功');
|
||||||
|
uni.navigateBack();
|
||||||
|
} catch (error) {
|
||||||
|
smartSentry.captureError(error);
|
||||||
|
} finally {
|
||||||
|
SmartLoading.hide();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.log('error', error);
|
||||||
|
SmartToast.toast('参数验证错误,请仔细填写表单数据!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.query-form-pop {
|
||||||
|
height: 800rpx;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-button {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
@ -51,6 +51,7 @@ export const useUserStore = defineStore({
|
|||||||
actions: {
|
actions: {
|
||||||
logout() {
|
logout() {
|
||||||
this.token = null;
|
this.token = null;
|
||||||
|
this.setUserLoginInfo(defaultUserInfo);
|
||||||
uni.removeStorage(USER_TOKEN);
|
uni.removeStorage(USER_TOKEN);
|
||||||
},
|
},
|
||||||
clearUserLoginInfo() {
|
clearUserLoginInfo() {
|
||||||
|
@ -134,7 +134,6 @@
|
|||||||
.smart-form-item {
|
.smart-form-item {
|
||||||
min-height: 100rpx;
|
min-height: 100rpx;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding-bottom: 24rpx;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border: none;
|
border: none;
|
||||||
|
Loading…
Reference in New Issue
Block a user