keqiaoling 7 months ago
commit
1f77c86238
80 changed files with 10467 additions and 0 deletions
  1. 17 0
      .gitignore
  2. 84 0
      App - 副本.vue
  3. 93 0
      App.vue
  4. 21 0
      LICENSE
  5. 3 0
      README.md
  6. 66 0
      api/login.js
  7. 136 0
      api/order/manu-order.js
  8. 47 0
      api/order/schedule.js
  9. 41 0
      api/system/user.js
  10. 73 0
      api/trade/quotation.js
  11. 158 0
      api/trade/shoe-style.js
  12. 27 0
      api/workman.js
  13. 51 0
      components/custom-head/custom-head.vue
  14. 145 0
      components/page-head/page-head.vue
  15. 167 0
      components/uni-section/uni-section.vue
  16. 39 0
      config.js
  17. 21 0
      main.js
  18. 70 0
      manifest.json
  19. 155 0
      pages.json
  20. 43 0
      pages/common/textview/index.vue
  21. 34 0
      pages/common/webview/index.vue
  22. 435 0
      pages/index.vue
  23. 208 0
      pages/login.vue
  24. 111 0
      pages/loginSso.vue
  25. 75 0
      pages/mine/about/index.vue
  26. 631 0
      pages/mine/avatar/index.vue
  27. 112 0
      pages/mine/help/index.vue
  28. 198 0
      pages/mine/index.vue
  29. 127 0
      pages/mine/info/edit.vue
  30. 58 0
      pages/mine/info/index.vue
  31. 85 0
      pages/mine/pwd/index.vue
  32. 78 0
      pages/mine/setting/index.vue
  33. 196 0
      pages/register.vue
  34. 248 0
      pages/sign/index.vue
  35. 632 0
      pages/sign/signMode/signMode.vue
  36. 220 0
      pages/trade/shoe-style/ShoeStyleView.vue
  37. 216 0
      pages/trade/shoe-style/index.vue
  38. 183 0
      pages/work/index.vue
  39. 49 0
      permission - 副本.js
  40. 48 0
      permission.js
  41. 60 0
      plugins/auth.js
  42. 14 0
      plugins/index.js
  43. 75 0
      plugins/modal.js
  44. 30 0
      plugins/tab.js
  45. BIN
      static/favicon.ico
  46. 90 0
      static/font/iconfont.css
  47. BIN
      static/font/iconfont.ttf
  48. BIN
      static/images/banner/banner01.jpg
  49. BIN
      static/images/banner/banner02.jpg
  50. BIN
      static/images/banner/banner03.jpg
  51. BIN
      static/images/profile.jpg
  52. BIN
      static/images/sgin.png
  53. BIN
      static/images/star-active.png
  54. BIN
      static/images/star.png
  55. BIN
      static/images/tabbar/home.png
  56. BIN
      static/images/tabbar/home_.png
  57. BIN
      static/images/tabbar/mine.png
  58. BIN
      static/images/tabbar/mine_.png
  59. BIN
      static/images/tabbar/work.png
  60. BIN
      static/images/tabbar/work_.png
  61. 20 0
      static/index.html
  62. BIN
      static/logo.png
  63. BIN
      static/logo200.png
  64. 3956 0
      static/scss/colorui.css
  65. 99 0
      static/scss/global.scss
  66. 11 0
      static/scss/index.scss
  67. 8 0
      store/getters.js
  68. 15 0
      store/index.js
  69. 98 0
      store/modules/user.js
  70. 64 0
      uni.scss
  71. 111 0
      utils/auth.js
  72. 55 0
      utils/common.js
  73. 8 0
      utils/constant.js
  74. 119 0
      utils/date.js
  75. 6 0
      utils/errorCode.js
  76. 0 0
      utils/jweixin.js
  77. 51 0
      utils/permission.js
  78. 74 0
      utils/request.js
  79. 32 0
      utils/storage.js
  80. 70 0
      utils/upload.js

+ 17 - 0
.gitignore

@@ -0,0 +1,17 @@
+######################################################################
+# Build Tools
+
+/unpackage/*
+/node_modules/*
+/uni_modules/*
+
+######################################################################
+# Development Tools
+
+/.idea/*
+/.vscode/*
+/.hbuilderx/*
+
+package-lock.json
+yarn.lock
+

+ 84 - 0
App - 副本.vue

@@ -0,0 +1,84 @@
+<script>
+	import config from './config'
+	import store from '@/store'
+	import {
+		getToken,
+		getSsoToken
+	} from '@/utils/auth'
+
+	export default {
+		onLaunch: function() {
+			this.initApp()
+		},
+		methods: {
+			// 初始化应用
+			initApp() {
+				// 初始化应用配置
+				this.initConfig()
+				// 检查用户登录状态
+				//#ifdef H5
+				this.checkLogins()
+				//#endif
+			},
+			initConfig() {
+				this.globalData.config = config
+				// if (this.globalData.config.VITE_SSO_LOGIN == true) {
+				// 	console.log(222)
+				// 	this.$tab.reLaunch('/pages/loginSso')
+				// };
+			},
+			checkLogin() {
+				if (!getToken()) {
+					this.$tab.reLaunch('/pages/login')
+				}
+			},
+			checkLogins() {
+				if (!getToken()) {
+					this.$tab.reLaunch('/pages/work/CleanGov/')
+					// // 非静默授权,第一次有弹框 
+					// this.code = ''
+					// var callback_url = 'https://tools-m.huaxiazhizao.com/#/pages/work/CleanGov/index'
+					// // 获取页面url 
+					// var appid = 'wx2cfd24c7380cdc08'
+					// this.code = this.getUrlCode().code
+					// // 截取code 
+					// if (this.code == null || this.code === '') {
+					// 	// 如果没有code,则去请求
+					// 	window.location.href =
+					// 		`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${encodeURIComponent( callback_url )}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
+					// } else {
+					// 	// 当code不等于空时,调用后端接口获取用户信息 
+					// 	this.getUserInfo()
+					// 	// 你自己的业务逻辑 
+					// }
+				}
+			},
+			getUrlCode() {
+				// 截取url中的code方法 
+				var url = location.search
+				var theRequest = new Object()
+				if (url.indexOf('?') != -1) {
+					var str = url.substr(1)
+					var strs = str.split('&')
+					for (var i = 0; i < strs.length; i++) {
+						theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1]
+					}
+				}
+				return theRequest
+			},
+			getUserInfo() {
+				let data = {}
+				data.code = this.code
+				data.appid = 'wx2cfd24c7380cdc08'
+				authorizeLogin(data).then(res => {
+					uni.setStorageSync('X-Token', res.data.token)
+					console.log(res.data.token)
+				}).catch(() => {})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import '@/static/scss/index.scss'
+</style>

+ 93 - 0
App.vue

@@ -0,0 +1,93 @@
+<script>
+	import config from './config'
+	import store from '@/store'
+	import { getToken,getTokens,getSsoAdminToken } from '@/utils/auth'
+
+	export default {
+		onLaunch: function() {
+			this.initApp()
+		},
+		methods: {
+			// 初始化应用
+			initApp() {
+				// 初始化应用配置
+				this.initConfig()
+				// 检查用户登录状态
+				//#ifdef H5
+				//this.checkLogins()
+				//#endif
+			},
+			initConfig() {
+				this.globalData.config = config
+				  // if (this.globalData.config.VITE_SSO_LOGIN == true&&!getToken()) {
+					 //   this.$tab.reLaunch('/pages/loginSso') 
+				  //   // getSsoToken();
+				  // };
+			},
+			checkLogin() {
+				if (!getToken()) {
+					this.$tab.reLaunch('/pages/login')
+				}
+			},
+			checkLogins() {
+				if (!getToken()) {
+					  // this.$tab.reLaunch('/pages/work/CleanGov/') 
+					// // 非静默授权,第一次有弹框 
+					this.code = ''
+					var callback_url = 'https://tools-m.huaxiazhizao.com/#/pages/trade/shoe-style/index'
+					// 获取页面url 
+					var appid = 'wx2cfd24c7380cdc08'
+					this.code = this.getUrlCode().code
+					// 截取code 
+					if (this.code == null || this.code === '') {
+						// 如果没有code,则去请求
+						window.location.href =
+							`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${encodeURIComponent( callback_url )}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
+					} else {
+						// 当code不等于空时,调用后端接口获取用户信息 
+						this.getUserInfo()
+						// 你自己的业务逻辑 
+					}
+				}else{
+					var options = uni.getStorageSync('options')
+					if (options) {
+						this.$tab.reLaunch('/pages/trade/shoe-style/ShoeStyleView')
+					} else { //如果没有上一页返回首页
+						this.$tab.reLaunch('/pages/trade/shoe-style/index')
+					}
+				}
+			},
+			getUrlCode() {
+				// 截取url中的code方法 
+				var url = location.search
+				var theRequest = new Object()
+				if (url.indexOf('?') != -1) {
+					var str = url.substr(1)
+					var strs = str.split('&')
+					for (var i = 0; i < strs.length; i++) {
+						theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1]
+					}
+				}
+				return theRequest
+			},
+			getUserInfo() {
+				let data = {}
+				data.code = this.code
+				data.appid = 'wx2cfd24c7380cdc08'
+				authorizeLogin(data).then(res => {
+					uni.setStorageSync('X-Token', res.data.token)
+				}).catch(() => {})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import '@/static/scss/index.scss'
+	uni-list-item  .uni-list-item__extra{
+			   flex:1
+	}
+	.uni-list-item .uni-list-item__content{
+			   flex: none;
+	}
+</style>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 若依
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 3 - 0
README.md

@@ -0,0 +1,3 @@
+# office-tool-m
+
+办公工具移动端

+ 66 - 0
api/login.js

@@ -0,0 +1,66 @@
+import request from '@/utils/request'
+
+// 登录方法
+export function login(username, password, code, uuid) {
+  const data = {
+    username,
+    password,
+    code,
+    uuid
+  }
+  return request({
+    'url': '/login',
+    headers: {
+      isToken: false
+    },
+    'method': 'post',
+    'data': data
+  })
+}
+
+// 注册方法
+export function register(data) {
+  return request({
+    url: '/register',
+    headers: {
+      isToken: false
+    },
+    method: 'post',
+    data: data
+  })
+}
+
+// 获取用户详细信息
+export function getInfo() {
+  return request({
+    'url': '/getInfo',
+    'method': 'get'
+  })
+}
+
+// 退出方法
+export function logout() {
+  return request({
+    'url': '/logout',
+    'method': 'post'
+  })
+}
+
+// 获取验证码
+export function getCodeImg() {
+  return request({
+    'url': '/captchaImage',
+    headers: {
+      isToken: false
+    },
+    method: 'get',
+    timeout: 20000
+  })
+}
+export function authorizeLogin(data) {
+  return request({
+    'url': '/api/sns/wxoa/authorizeLogin',
+    method: 'post',
+    params: data
+  })
+}

+ 136 - 0
api/order/manu-order.js

@@ -0,0 +1,136 @@
+/**
+ * @Description 指令单API
+ * @Author 何伯法
+ * @Date 2023-08-14 10:50
+ * @LastEditors 何伯法
+ * @LastEditTime 2023-09-19 09:26
+ */
+
+import request from '@/utils/request'
+import { merge } from 'lodash'
+
+// 列表搜索参数
+export const MANU_ORDER_QUERY = {
+    custName: null, // 客人名称
+    facName: null, // 生产工厂
+    styleNum: null, // 工厂款号
+    custNum: null, // 客人款号
+    manuNum: null, // 指令号
+    beginDate: null, // 开始:工厂交期
+    endDate: null, // 结束:工厂交期
+    status: null, // 状态:0-生产 1-完成
+    createBy: null, // 创建人
+    createTime: null, // 创建时间
+    pageNum: 1, // 页面索引
+    pageSize: 15 // 分页数量
+}
+
+/**
+ * 查询指令单列表
+ * @permi manu:ord:list
+ * @param { MANU_ORDER_QUERY } query 查询条件
+ * @returns { Object } {total,rows:[]}
+ */
+export function listManuOrder(query) {
+    return request({
+        url: '/manu/ord/list',
+        method: 'get',
+        params: merge({}, MANU_ORDER_QUERY, query)
+    })
+};
+
+/**
+ * 获取指令单
+ * @permi manu:ord:view || manu:ord:edit
+ * @param {Number} id 指令单ID
+ * @returns {Object} {data}
+ */
+export function getManuOrder(id) {
+    return request({
+        url: '/manu/ord/' + id,
+        method: 'get'
+    })
+};
+
+/**
+ * 添加指令单
+ * @permi manu:ord:add
+ * @param {Object} data 指令单数据
+ * @returns {Object} {data}
+ */
+export function addManuOrder(data) {
+    return request({
+        url: '/manu/ord',
+        method: 'post',
+        data: data
+    })
+};
+
+/**
+ * 修改指令单
+ * @permi manu:ord:edit
+ * @param {Object} data 指令单数据
+ * @returns {Object} {data}
+ */
+export function editManuOrder(data) {
+    return request({
+        url: '/manu/ord',
+        method: 'put',
+        data: data
+    })
+};
+
+/**
+ * 删除指令单
+ * @permi manu:ord:delete
+ * @param {Number} ids 指令单ID集合
+ * @returns {Object} {data}
+ */
+export function deleteManuOrder(ids) {
+    return request({
+        url: '/manu/ord/' + (ids || []).join(','),
+        method: 'delete'
+    })
+};
+
+/**
+ * 完成指令单
+ * @permi manu:ord:complete
+ * @param {Number} ids 指令单ID集合
+ * @returns {Object} {data}
+ */
+export function completeManuOrder(ids) {
+    return request({
+        url: '/manu/ord/complete',
+        method: 'get',
+        params: { ids: (ids || []).join(','), status: '1' }
+    })
+};
+
+/**
+ * 下载导入模板(指令单)
+ * @permi ['manu:ord:add', 'customer:order:edit'] 导入所需权限
+ * @param 
+ * @returns 
+ */
+export function downloadTemplate() {
+    return request({
+        url: '/manu/ord/download_template',
+        method: 'get'
+    })
+};
+
+
+/**
+ * 通过鞋款查询指令单列表
+ * @permi
+ * @param 
+ * @returns 
+ */
+export function getStyleNumList() {
+    return request({
+        url: '/manu/ord/style_num',
+        method: 'get'
+    })
+};
+

+ 47 - 0
api/order/schedule.js

@@ -0,0 +1,47 @@
+
+import request from '@/utils/request'
+// import { merge } from 'lodash'
+
+// 列表搜索参数
+export const MANU_ORDER_QUERY = {
+    custName: null, // 客人名称
+    custNum: null, // 客人款号
+    facId: null, // 生产工厂
+    styleNum: null, // 工厂款号
+    manuNum: null, // 指令号
+    beginDate: null, // 开始:工厂交期
+    endDate: null, // 结束:工厂交期
+    status: null, // 状态:0-生产 1-完成
+    createBy: null, // 创建人
+    createTime: null, // 创建时间
+    pageNum: 1, // 页面索引
+    pageSize: 15 // 分页数量
+}
+
+/**
+ * 查询订单进度
+ * @permi manu:ord:list
+ * @param {MANU_ORDER_QUERY} query 查询条件
+ * @returns {Object}
+ */
+export function listManuOrder(query) {
+    return request({
+        url: '/manu/sched/list',
+        method: 'get',
+        params: merge({}, MANU_ORDER_QUERY, query)
+    })
+};
+
+/**
+ * 下载导入模板(指令单排程)
+ * @permi ['manu:sched:add'] 导入所需权限
+ * @param 
+ * @returns 
+ */
+export function downloadTemplate() {
+    return request({
+        url: '/manu/sched/download_template',
+        method: 'get'
+    })
+};
+

+ 41 - 0
api/system/user.js

@@ -0,0 +1,41 @@
+import upload from '@/utils/upload'
+import request from '@/utils/request'
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+  const data = {
+    oldPassword,
+    newPassword
+  }
+  return request({
+    url: '/system/user/profile/updatePwd',
+    method: 'put',
+    params: data
+  })
+}
+
+// 查询用户个人信息
+export function getUserProfile() {
+  return request({
+    url: '/system/user/profile',
+    method: 'get'
+  })
+}
+
+// 修改用户个人信息
+export function updateUserProfile(data) {
+  return request({
+    url: '/system/user/profile',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户头像上传
+export function uploadAvatar(data) {
+  return upload({
+    url: '/system/user/profile/avatar',
+    name: data.name,
+    filePath: data.filePath
+  })
+}

+ 73 - 0
api/trade/quotation.js

@@ -0,0 +1,73 @@
+/**
+ * @Description 报价API
+ * @Author 何伯法
+ * @Date 2024-04-20
+ * @LastEditors 何伯法
+ * @LastEditTime 2024-04-20
+ */
+import request from '@/utils/request'
+import { merge } from 'lodash'
+
+
+// 列表搜索参数
+export const QUOTATION_QUERY = {
+	company: null, // 公司
+	cust: null, // 客人
+	color: null, // 颜色
+	beginOrderDate: null, // 下单日期:开始
+	endOrderDate: null, // 下单日期:结束
+	createBy: null, // 创建人
+	createTime: null, // 创建时间
+	pageNum: 1, // 页面索引
+	pageSize: 15 // 分页数量
+}
+
+/**
+ * 查询
+ * @permi trade:quotation:list
+ * @param {QUOTATION_QUERY} query 查询条件
+ * @returns {Object}
+ */
+export function listQuotation(query) {
+	return request({
+		url: '/trade/quotation/list',
+		method: 'get',
+		params: merge({}, QUOTATION_QUERY, query)
+	})
+};
+
+/**
+ * 获取
+ * @permi trade:quotation:view || trade:quotation:edit
+ * @param {Number} id ID
+ * @returns {Object} {data}
+ */
+export function getQuotation(id) {
+	return request({
+		url: '/trade/quotation/' + id,
+		method: 'get'
+	})
+};
+
+
+/* 表单参数 */
+export const QUOTATION_FROM = {
+	remark: null, // 备注
+	fob: null, // 价格
+	createBy: null, // 创建人
+	createTime: null // 创建时间
+}
+
+/**
+ * 添加
+ * @permi trade:quotation:add
+ * @param {QUOTATION_FROM} data 数据
+ * @returns {Object} {data}
+ */
+export function addQuotation(data) {
+	return request({
+		url: '/trade/quotation',
+		method: 'post',
+		data: merge({}, QUOTATION_FROM, data)
+	})
+};

+ 158 - 0
api/trade/shoe-style.js

@@ -0,0 +1,158 @@
+/**
+ * @Description 外贸API
+ * @Author 何伯法
+ * @Date 2024-04-17
+ * @LastEditors 何伯法
+ * @LastEditTime 2024-04-17
+ */
+import request from '@/utils/request'
+import { merge } from 'lodash'
+
+// 列表搜索参数
+export const SHOE_STYLE_QUERY = {
+	styleNum: null, // 工厂款号
+	version: null, // 版本号
+	color: null, // 颜色
+	beginOrderDate: null, // 下单日期:开始
+	endOrderDate: null, // 下单日期:结束
+	createBy: null, // 创建人
+	createTime: null, // 创建时间
+	pageNum: 1, // 页面索引
+	pageSize: 15 // 分页数量
+}
+
+/**
+ * 查询
+ * @permi trade:style:list
+ * @param {SHOE_STYLE_QUERY} query 查询条件
+ * @returns {Object}
+ */
+export function listShoeStyle(query) {
+	return request({
+		url: '/trade/style/list',
+		method: 'get',
+		params: merge({}, SHOE_STYLE_QUERY, query)
+	})
+};
+
+/**
+ * 通过IDS查询
+ * @permi trade:style:list
+ * @param {Array} ids 查询条件
+ * @returns {Array}
+ */
+export function queryByIds(ids) {
+	return request({
+		url: '/trade/style/ids',
+		method: 'get',
+		params: { ids: (ids || []).join(',') }
+	})
+};
+
+
+/**
+ * jsd
+ * @permi trade:style:remove
+ * @param {Number} ids ID集合
+ * @returns {Object} {data}
+ */
+export function getSign(query) {
+	return request({
+		url: '/api/sns/wx/jssdk_sign',
+		method: 'get',
+		params: merge({}, query)
+	})
+};
+
+/**
+ * 获取
+ * @permi trade:style:view || trade:style:edit
+ * @param {Number} id ID
+ * @returns {Object} {data}
+ */
+export function getShoeStyle(id) {
+	return request({
+		url: '/trade/style/' + id,
+		method: 'get'
+	})
+};
+
+
+
+/* 表单参数 */
+export const SHOE_STYLE_FROM = {
+	styleNum: null, // 鞋款
+	version: null, // 版本
+	color: null, // 颜色
+	orderDate: null, // 下单日期
+	foto: null, // 鞋图
+	pice: null, // 鞋底图
+	enColor: null, // 英文颜色
+	size: null, // 尺码
+	qty: null, // 数量
+	upper: null, // 面料
+	lining: null, // 内衬
+	insole: null, // 内里
+	outsole: null, // 大底
+	outsoleNumber: null, // 大底编号
+	codeSegment: null, // 码段
+	gender: null, // 性别
+	fob: null, // 价格
+	lastNumber: null, // 楦头编号
+	createBy: null, // 创建人
+	createTime: null // 创建时间
+}
+
+/**
+ * 添加
+ * @permi trade:style:add
+ * @param {SHOE_STYLE_FROM} data 数据
+ * @returns {Object} {data}
+ */
+export function addShoeStyle(data) {
+	return request({
+		url: '/trade/style',
+		method: 'post',
+		data: merge({}, SHOE_STYLE_FROM, data)
+	})
+};
+
+/**
+ * 编辑
+ * @permi trade:style:update
+ * @param {SHOE_STYLE_FROM} data 数据
+ * @returns {Object} {data}
+ */
+export function editShoeStyle(data) {
+	return request({
+		url: '/trade/style',
+		method: 'post',
+		data: merge({}, SHOE_STYLE_FROM, data)
+	})
+};
+
+/**
+ * 删除
+ * @permi trade:style:remove
+ * @param {Number} ids ID集合
+ * @returns {Object} {data}
+ */
+export function deleteShoeStyle(ids) {
+	return request({
+		url: '/trade/style/' + (ids || []).join(','),
+		method: 'delete'
+	})
+};
+
+/**
+ * 下载导入模板
+ * @permi 
+ * @param 
+ * @returns 
+ */
+export function downloadTemplate() {
+	return request({
+		url: '/trade/style/download_template',
+		method: 'get'
+	})
+};

+ 27 - 0
api/workman.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 工资条列表
+const baseApi='/api/workman'
+export function salaryList() {
+  return request({
+    'url': baseApi+'/own_salary_list',
+    'method': 'get'
+  })
+}
+
+// 薪资明细
+export function viewSalary(data) {
+  return request({
+    url: baseApi+'/view_salary',
+    method: 'get',
+    params: data
+  })
+}
+// 薪资签名
+export function sign(data) {
+  return request({
+    url: baseApi+'/sign',
+    method: 'post',
+    data: data
+  })
+}

+ 51 - 0
components/custom-head/custom-head.vue

@@ -0,0 +1,51 @@
+<template>
+  <view class="custom-header">
+    <view class="title">{{ title }}</view>
+    <view class="right-buttons">
+      <!-- 这里可以放置更多按钮,根据需要添加 -->
+      <text @click="onClickMore">更多</text>
+    </view>
+  </view>
+</template>
+ 
+<script>
+export default {
+  props: {
+    title: String
+  },
+  methods: {
+    onClickMore() {
+      // 处理更多按钮的点击事件
+      console.log('更多按钮被点击');
+      // 可以通过事件通知父组件
+      this.$emit('more');
+    }
+  }
+}
+</script>
+ 
+<style scoped>
+.custom-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10px;
+  background-color: #f7f7f7;
+  border-bottom: 1px solid #eee;
+}
+.title {
+  font-size: 18px;
+  font-weight: bold;
+}
+.right-buttons {
+  display: flex;
+  align-items: center;
+}
+.right-buttons text {
+  margin-left: 10px;
+  font-size: 16px;
+  color: #000;
+  /* 添加点击效果的样式 */
+  cursor: pointer;
+}
+</style>

+ 145 - 0
components/page-head/page-head.vue

@@ -0,0 +1,145 @@
+<template>
+	<view>
+		<view class="bg-white padding-lr-15 uni-top">
+			<view class="flex justify-between top-button">
+				<uni-easyinput :prefixIcon="searchShow ? 'bottom' : 'right'" suffixIcon="search"
+					v-model="queryfrom.styleNum" placeholder="搜索工厂款号" @iconClick="iconClick" @confirm="getData(1)">
+				</uni-easyinput>
+				<view v-if="showQutation" style="width: 60px;margin-left: 10rpx;">
+					<button @click="goQutation" type="primary" class="import-btn">
+						<view style="font-size: 16px;">报价</view>
+					</button>
+				</view>
+				<view style="margin-top: -4px;margin-left: 5rpx;">
+					<uni-icons @click="scan" type="scan" size="43" color="#409EFF"></uni-icons>
+				</view>
+			</view>
+			<view class="flex" v-if="searchShow">
+				<view class="flex-sub padding-left-xs padding-top-xs">
+					<uni-easyinput v-model="queryfrom.version" placeholder="搜索版本号"
+						@confirm="getData(1)"></uni-easyinput>
+					<uni-easyinput style="margin-top: 5px;" v-model="queryfrom.color" placeholder="搜索颜色"
+						@confirm="getData(1)"></uni-easyinput>
+				</view>
+			</view>
+			<view class="flex justify-between padding-top-sm" v-if="searchShow">
+				<button class="mini-btn" type="default" size="mini" @click="searchShow = !searchShow">
+					<text class="cuIcon-fold" style="margin-right: 5px;"></text>收回
+				</button>
+				<button class="mini-btn" type="primary" size="mini" @click="getData(1)">搜索</button>
+			</view>
+		</view>
+		<view style="padding: 20px;" class="padding">
+		</view>
+		<uni-popup style="width: 100%;" class="" ref="popup" type="dialog" border-radius="10px 10px 10px 10px">
+			<div style="width: 100%;" class="bg-white">我是分界线</div>
+		</uni-popup>
+	</view>
+</template>
+<script>
+	/**
+	 * Section 标题栏
+	 * @description 标题栏
+	 * @property {String} type = [line|circle|square] 标题装饰类型
+	 * @value line 竖线
+	 * @value circle 圆形
+	 * @value square 正方形
+	 * @property {String} title 主标题
+	 * @property {String} titleFontSize 主标题字体大小
+	 * @property {String} titleColor 主标题字体颜色
+	 * @property {String} subTitle 副标题
+	 * @property {String} subTitleFontSize 副标题字体大小
+	 * @property {String} subTitleColor 副标题字体颜色
+	 * @property {String} padding 默认插槽 padding
+	 */
+	import jweixin from 'weixin-js-sdk'
+	import {
+		getSign
+	} from '@/api/trade/shoe-style.js'
+	export default {
+		name: 'pageHead',
+		emits: ['click'],
+		props: {
+			showQutation: {
+				type: Boolean,
+				default: true
+			},
+		},
+		data() {
+			return {
+				searchShow: false,
+				getSign: getSign,
+				queryfrom: {
+					version: '',
+					styleNum: '',
+					color: ''
+				}
+			}
+		},
+		created() {
+			this.getConfig()
+		},
+		methods: {
+			goQutation() {
+				uni.navigateTo({
+					url: '/pages/trade/quotation/QuotationAdd'
+				})
+			},
+			openPopup() {
+				this.$refs.popup.open('center')
+			},
+			getConfig() {
+				this.getSign({
+					url: location.href,
+					appid: 'wx2cfd24c7380cdc08',
+				}).then(res => {
+					var s = res.data
+					jweixin.config({
+						debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
+						appId: s.appId, // 必填,公众号的唯一标识
+						timestamp: s.timestamp, // 必填,生成签名的时间戳
+						nonceStr: s.nonceStr, // 必填,生成签名的随机串
+						signature: s.signature, // 必填,签名
+						jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表
+					})
+				})
+			},
+			scan() {
+				const _this = this
+				jweixin.scanQRCode({
+					needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+					scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
+					success: function(res) {
+						let str = res.resultStr // 当needResult 为 1 时,扫码返回的结果
+						// let exURL = "https://zhtool.huaxiazhizao.com/pages/trade/shoe-style/ShoeStyleView?data=1";
+						let encodedURL = encodeURI(str)
+						// console.log(encodedURL)
+						window.location.href = encodedURL
+					}
+				})
+			},
+			iconClick(type) {
+				if (type === 'prefix') {
+					this.searchShow = !this.searchShow
+				} else {
+					this.$emit('headGetData', this.queryfrom)
+				};
+				// uni.showToast({
+				// 	title: `点击了${type==='prefix'?'左侧':'右侧'}的图标`,
+				// 	icon: 'none'
+				// })
+			},
+			getData() {
+				this.$emit('headGetData', this.queryfrom)
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.uni-top {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+	}
+</style>

+ 167 - 0
components/uni-section/uni-section.vue

@@ -0,0 +1,167 @@
+<template>
+	<view class="uni-section">
+		<view class="uni-section-header" @click="onClick">
+				<view class="uni-section-header__decoration" v-if="type" :class="type" />
+        <slot v-else name="decoration"></slot>
+
+        <view class="uni-section-header__content">
+          <text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
+          <text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
+        </view>
+
+        <view class="uni-section-header__slot-right">
+          <slot name="right"></slot>
+        </view>
+		</view>
+
+		<view class="uni-section-content" :style="{padding: _padding}">
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+
+	/**
+	 * Section 标题栏
+	 * @description 标题栏
+	 * @property {String} type = [line|circle|square] 标题装饰类型
+	 * 	@value line 竖线
+	 * 	@value circle 圆形
+	 * 	@value square 正方形
+	 * @property {String} title 主标题
+	 * @property {String} titleFontSize 主标题字体大小
+	 * @property {String} titleColor 主标题字体颜色
+	 * @property {String} subTitle 副标题
+	 * @property {String} subTitleFontSize 副标题字体大小
+	 * @property {String} subTitleColor 副标题字体颜色
+	 * @property {String} padding 默认插槽 padding
+	 */
+
+	export default {
+		name: 'UniSection',
+    emits:['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			title: {
+				type: String,
+				required: true,
+				default: ''
+			},
+      titleFontSize: {
+        type: String,
+        default: '14px'
+      },
+			titleColor:{
+				type: String,
+				default: '#333'
+			},
+			subTitle: {
+				type: String,
+				default: ''
+			},
+      subTitleFontSize: {
+        type: String,
+        default: '12px'
+      },
+      subTitleColor: {
+        type: String,
+        default: '#999'
+      },
+			padding: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+    computed:{
+      _padding(){
+        if(typeof this.padding === 'string'){
+          return this.padding
+        }
+
+        return this.padding?'10px':''
+      }
+    },
+		watch: {
+			title(newVal) {
+				if (uni.report && newVal !== '') {
+					uni.report('title', newVal)
+				}
+			}
+		},
+    methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	$uni-primary: #2979ff !default;
+
+	.uni-section {
+		background-color: #fff;
+    .uni-section-header {
+      position: relative;
+      /* #ifndef APP-NVUE */
+      display: flex;
+      /* #endif */
+      flex-direction: row;
+      align-items: center;
+      padding: 12px 10px;
+      font-weight: normal;
+
+      &__decoration{
+        margin-right: 6px;
+        background-color: $uni-primary;
+        &.line {
+          width: 4px;
+          height: 12px;
+          border-radius: 10px;
+        }
+
+        &.circle {
+          width: 8px;
+          height: 8px;
+          border-top-right-radius: 50px;
+          border-top-left-radius: 50px;
+          border-bottom-left-radius: 50px;
+          border-bottom-right-radius: 50px;
+        }
+
+        &.square {
+          width: 8px;
+          height: 8px;
+        }
+      }
+
+      &__content {
+        /* #ifndef APP-NVUE */
+        display: flex;
+        /* #endif */
+        flex-direction: column;
+        flex: 1;
+        color: #333;
+
+        .distraction {
+          flex-direction: row;
+          align-items: center;
+        }
+        &-sub {
+          margin-top: 2px;
+        }
+      }
+
+      &__slot-right{
+        font-size: 14px;
+      }
+    }
+
+    .uni-section-content{
+      font-size: 14px;
+    }
+	}
+</style>

+ 39 - 0
config.js

@@ -0,0 +1,39 @@
+// 应用全局配置
+module.exports = {
+	// baseUrl: 'https://vue.ruoyi.vip/prod-api',
+	// baseUrl: 'https://tools-server.huaxiazhizao.com',
+	devServer: {
+		disableHostCheck: true,
+		// historyApiFallback: true,
+		// allowedHosts: "all",
+	},
+ // 单点登录
+	VITE_SSO_LOGIN:true,
+	baseUrl: 'http://localhost:8083',
+	// if (window.location.host.indexOf('localhost') > -1) {
+		// baseUrl: 'http://localhost:8083',
+	// }else {
+	// 	baseUrl: 'https://tools-server.huaxiazhizao.com',
+	// }
+	// 应用信息
+	appInfo: {
+		// 应用名称
+		name: 'ruoyi-app',
+		// 应用版本
+		version: '1.1.0',
+		// 应用logo
+		logo: '/static/logo.png',
+		// 官方网站
+		site_url: 'http://ruoyi.vip',
+		// 政策协议
+		agreements: [{
+				title: '隐私政策',
+				url: 'https://ruoyi.vip/protocol.html'
+			},
+			{
+				title: '用户服务协议',
+				url: 'https://ruoyi.vip/protocol.html'
+			}
+		]
+	}
+}

+ 21 - 0
main.js

@@ -0,0 +1,21 @@
+import Vue from 'vue'
+import App from './App'
+import store from './store' // store
+import plugins from './plugins' // plugins
+import './permission' // permission
+Vue.use(plugins)
+
+Vue.config.productionTip = false
+Vue.prototype.$store = store
+
+App.mpType = 'app'
+// 全局注册
+import pageHead from './components/page-head/page-head.vue'
+import customHead from './components/custom-head/custom-head.vue'
+Vue.component('page-head', pageHead)
+Vue.component('custom-head', customHead)
+const app = new Vue({
+  ...App
+})
+
+app.$mount()

+ 70 - 0
manifest.json

@@ -0,0 +1,70 @@
+{
+    "name" : "若依移动端",
+    "appid" : "__UNI__E69C5A0",
+    "description" : "",
+    "versionName" : "1.1.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {},
+        "distribute" : {
+            "android" : {
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "ios" : {},
+            "sdkConfigs" : {}
+        }
+    },
+    "quickapp" : {},
+    "mp-weixin" : {
+        "appid" : "wx85d719778bcec9e6",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : false,
+            "minified" : true,
+            "postcss" : true
+        },
+        "optimization" : {
+            "subPackages" : true
+        },
+        "usingComponents" : true
+    },
+    "vueVersion" : "2",
+    "h5" : {
+        "template" : "static/index.html",
+        "devServer" : {
+            "port" : 8080,
+            "https" : false,
+            "disableHostCheck" : true
+        },
+        "title" : "RuoYi-App",
+        "router" : {
+            "mode" : "history",
+            "base" : "/"
+        }
+    }
+}

+ 155 - 0
pages.json

@@ -0,0 +1,155 @@
+{
+	"easycom": {
+		"autoscan": true,
+		"custom": {
+			// uni-ui 规则如下配置
+			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
+		}
+	},
+	"pages": [{
+		"path": "pages/loginSso",
+		"style": {
+			"navigationBarTitleText": "登录"
+		}
+	},{
+		"path": "pages/login",
+		"style": {
+			"navigationBarTitleText": "登录"
+		}
+	},{
+		"path": "pages/register",
+		"style": {
+			"navigationBarTitleText": "注册"
+		}
+	}, {
+		"path": "pages/index",
+		"style": {
+			"navigationBarTitleText": "若依移动端框架",
+			"navigationStyle": "custom"
+		}
+	}, {
+		"path": "pages/work/index",
+		"style": {
+			"navigationBarTitleText": "工作台"
+		}
+	}, {
+		"path": "pages/mine/index",
+		"style": {
+			"navigationBarTitleText": "我的"
+		}
+	}, {
+		"path": "pages/mine/avatar/index",
+		"style": {
+			"navigationBarTitleText": "修改头像"
+		}
+	}, {
+		"path": "pages/mine/info/index",
+		"style": {
+			"navigationBarTitleText": "个人信息"
+		}
+	}, {
+		"path": "pages/mine/info/edit",
+		"style": {
+			"navigationBarTitleText": "编辑资料"
+		}
+	}, {
+		"path": "pages/mine/pwd/index",
+		"style": {
+			"navigationBarTitleText": "修改密码"
+		}
+	}, {
+		"path": "pages/mine/setting/index",
+		"style": {
+			"navigationBarTitleText": "应用设置"
+		}
+	}, {
+		"path": "pages/mine/help/index",
+		"style": {
+			"navigationBarTitleText": "常见问题"
+		}
+	}, {
+		"path": "pages/mine/about/index",
+		"style": {
+			"navigationBarTitleText": "关于我们"
+		}
+	}, {
+		"path": "pages/common/webview/index",
+		"style": {
+			"navigationBarTitleText": "浏览网页"
+		}
+	}, {
+		"path": "pages/common/textview/index",
+		"style": {
+			"navigationBarTitleText": "浏览文本"
+		}
+	}, {
+		"path": "pages/trade/shoe-style/ShoeStyleView",
+		"style": {
+			"navigationBarTitleText": "查看外贸",
+			"enablePullDownRefresh": false,
+			"app-plus": {
+				"softinputMode": "adjustResize"
+			}
+		}
+	}, {
+		"path": "pages/trade/shoe-style/index",
+		"style": {
+			"navigationBarTitleText": "样品",
+			"enablePullDownRefresh": false
+		}
+	}
+	// {
+	// 	"path": "pages/trade/quotation/QuotationAdd",
+	// 	"style": {
+	// 		"navigationBarTitleText": "新增报价单",
+	// 		"enablePullDownRefresh": false
+	// 	}
+	// }, {
+	// 	"path": "pages/trade/quotation/index",
+	// 	"style": {
+	// 		"navigationBarTitleText": "报价单",
+	// 		"enablePullDownRefresh": false
+	// 	}
+	// }, {
+	// 	"path": "pages/trade/quotation/QuotationView",
+	// 	"style": {
+	// 		"navigationBarTitleText": "查看报价单",
+	// 		"enablePullDownRefresh": false,
+	// 		"app-plus": {
+	// 			"softinputMode": "adjustResize"
+	// 		}
+	// 	}
+	],
+	"tabBar": {
+		"color": "#000000",
+		"selectedColor": "#000000",
+		"borderStyle": "white",
+		"backgroundColor": "#ffffff",
+		"list": [{
+				"pagePath": "pages/trade/shoe-style/index",
+				"iconPath": "static/images/tabbar/home.png",
+				"selectedIconPath": "static/images/tabbar/home_.png",
+				"text": "样品"
+			}, {
+				"pagePath": "pages/trade/quotation/index",
+				"iconPath": "static/images/tabbar/work.png",
+				"selectedIconPath": "static/images/tabbar/work_.png",
+				"text": "报价单"
+			}
+
+		]
+	},
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "RuoYi",
+		"navigationBarBackgroundColor": "#FFFFFF"
+	},
+	"condition": { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [{
+			"name": "", //模式名称
+			"path": "", //启动页面,必选
+			"query": "" //启动参数,在页面的onLoad函数里面得到
+		}]
+	}
+}

+ 43 - 0
pages/common/textview/index.vue

@@ -0,0 +1,43 @@
+<template>
+  <view>
+    <uni-card class="view-title" :title="title">
+      <text class="uni-body view-content">{{ content }}</text>
+    </uni-card>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        title: '',
+        content: ''
+      }
+    },
+    onLoad(options) {
+      this.title = options.title
+      this.content = options.content
+      uni.setNavigationBarTitle({
+        title: options.title
+      })
+    }
+  }
+</script>
+
+<style scoped>
+  page {
+    background-color: #ffffff;
+  }
+
+  .view-title {
+    font-weight: bold;
+  }
+
+  .view-content {
+    font-size: 26rpx;
+    padding: 12px 5px 0;
+    color: #333;
+    line-height: 24px;
+    font-weight: normal;
+  }
+</style>

+ 34 - 0
pages/common/webview/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <view v-if="params.url">
+    <web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        params: {},
+        webviewStyles: {
+          progress: {
+            color: "#FF3333"
+          }
+        }
+      }
+    },
+    props: {
+      src: {
+        type: [String],
+        default: null
+      }
+    },
+    onLoad(event) {
+      this.params = event
+      if (event.title) {
+        uni.setNavigationBarTitle({
+          title: event.title
+        })
+      }
+    }
+  }
+</script>

+ 435 - 0
pages/index.vue

@@ -0,0 +1,435 @@
+<template>
+	<view>
+		<view class="bg-white padding">
+
+			<view class="flex justify-between ">
+
+				<uni-easyinput prefixIcon="bottom" suffixIcon="search" v-model="queryfrom.styleNum" placeholder="搜索工厂款号"
+					@iconClick="iconClick" @confirm="getData(1)">
+				</uni-easyinput>
+				<view style="padding: 4px;width: 50px;height: 40px;">
+					<button @click="chooseFileClick" type="primary" size="mini" class="mini-btn"
+						style="padding:0px;width: 100%;">导入</button>
+				</view>
+			</view>
+			<view class="flex" v-if="searchShow">
+				<view class="flex-sub padding-left-xs padding-top-xs">
+					<uni-easyinput v-model="queryfrom.custName" placeholder="搜索客人名称" @confirm="getData(1)">
+					</uni-easyinput>
+				</view>
+				<!-- 	<view class="flex-sub padding-left-xs padding-top-xs">
+
+					<uni-easyinput v-model="queryfrom.styleNum" placeholder="搜索工厂款号">
+					</uni-easyinput>
+				</view> -->
+			</view>
+			<!-- <view class="flex" v-if="searchShow">
+				<view class="flex-sub padding-left-xs padding-top-xs">
+					<uni-easyinput v-model="queryfrom.custName" placeholder="搜索客人名称">
+					</uni-easyinput>
+				</view>
+			 	<view class="flex-sub padding-left-xs padding-top-xs">
+					<uni-easyinput v-model="queryfrom.color" placeholder="搜索颜色">
+					</uni-easyinput>
+				</view> 
+			</view> -->
+			<view class="flex justify-between padding-top-sm" v-if="searchShow">
+				<button class="mini-btn" type="default" size="mini" @click="searchShow = !searchShow">
+					<text class="cuIcon-fold" style="margin-right: 5px;"></text>收回
+				</button>
+				<button class="mini-btn" type="primary" size="mini" @click="getData(1)">搜索</button>
+			</view>
+		</view>
+		<view class="bg-white ">
+			<uni-table ref="table" :loading="loading" border stripe="true" emptyText="暂无更多数据">
+				<uni-tr>
+					<uni-th v-for="(item,index) in column" :key="index" :width="item.width" :align="item.align"
+						style="padding:0px" :fixed="item.fixed">
+						<template v-if="item.label=='帮面材料'||item.label=='大底材料'||item.label=='包装材料'">
+
+							<view style="display:inline-block;width: 100%;">
+								<view style="border-bottom:1px solid #eee;">
+									{{item.label}}
+								</view>
+								<view style="width: 100%;">开始日期</view>
+							</view>
+						</template>
+						<template v-else-if="item.label=='冲裁'||item.label=='针车'||item.label=='成型'">
+
+							<view style="display:inline-block;width: 100%;">
+								<view style="border-bottom:1px solid #eee;">
+									{{item.label}}
+								</view>
+								<view style="width: 100%;">
+									<view style="width: 25%;display: inline-block;">加工类型</view>
+									<view style="width: 37.5%;display: inline-block;">开始日期</view>
+									<view style="width: 37.5%;display: inline-block;">结束日期</view>
+								</view>
+							</view>
+						</template>
+						<template v-else-if="item.label=='配套'">
+							<view style="display:inline-block;width: 100%;">
+								<view style="border-bottom:1px solid #eee;">
+									{{item.label}}
+								</view>
+								<view style="width: 100%;">
+									<span style="width: 50%;display: inline-block;">开始日期</span>
+									<span style="width: 50%;display: inline-block;">结束日期</span>
+								</view>
+							</view>
+						</template>
+						<template v-else>{{item.label}}</template>
+
+					</uni-th>
+				</uni-tr>
+				<uni-tr v-for="(item, index) in tableData" :key="index">
+					<uni-td v-for="(items,indexs) in column" :key="indexs" :width="items.width" :align="items.align">
+						<!-- endTime type -->
+						<template v-if="items.label=='主图'">
+							<image class="slot-image" :src="item[items.name]" mode="aspectFit"
+								style="max-width:75px;max-height:35px;">
+						</template>
+						<template v-else-if="items.label=='业务备注'">
+							<uni-tooltip :content="item[items.name]" placement="top" v-if="item[items.name]">点击查看</uni-tooltip>
+						</template>
+						<template v-else-if="items.label=='备注'">
+							<uni-tooltip :content="item.sched.remark" placement="top" v-if="item.sched.remark">点击查看</uni-tooltip>
+						</template>
+						<template v-else-if="items.label=='帮面材料'||items.label=='大底材料'||items.label=='包装材料'">
+							{{item[items.name+'startTime']||''}}
+						</template>
+						<template v-else-if="items.label=='确认样提供'">
+							<uni-tooltip :content="formatDate(item.shoeFactory.sampleTime)" placement="top"
+								v-if="item.shoeFactory.sampleTime">{{item.shoeFactory.sampleFlag?'是':'否'}}</uni-tooltip>
+						</template>
+						<template v-else-if="items.label=='色卡提供'">
+							<uni-tooltip :content="formatDate(item.shoeFactory.colorCardTime)" placement="top"
+								v-if="item.shoeFactory.colorCardTime">{{item.shoeFactory.colorCardFlag?'是':'否'}}</uni-tooltip>
+						</template>
+						<template v-else-if="items.label=='是否技转'">
+							{{item.shoeFactory.skillTransferFlag?'是':item.shoeFactory.skillTransferFlag===false?'否' :''}}
+						</template>
+						<template v-else-if="items.label=='款式标记'">
+							{{item[items.name]==0?'新款':'旧款'}}
+						</template>
+						<template v-else-if="items.label=='延期'">
+							<span style="color: #F56C6C;">{{judgePostpone(item)}}</span>
+						</template>
+						<template v-else-if="items.label=='是否审核'">
+							<template v-if="!item.sched">
+								<uni-tag type="default" :inverted="true" text="暂无排程"></uni-tag>
+							</template>
+							<template v-else-if="item.sched && item.sched.audit">
+								<uni-tag type="success" :inverted="true" text="已审"></uni-tag>
+							</template>
+							<template v-else-if="item.sched && !item.sched.audit">
+								<uni-tag type="warning" :inverted="true" text="待审"></uni-tag>
+							</template>
+						</template>
+
+						<!-- 配套 -->
+						<template v-else-if="items.label=='冲裁'||items.label=='针车'||items.label=='成型'">
+
+							<view style="display:inline-block;height: 100%;width: 100%;">
+								<view style="width: 25%;display: inline-block;">{{item[items.name+'type']||' '}}</view>
+								<view style="width: 37.5%;display: inline-block;">{{item[items.name+'startTime']||' '}}</view>
+								<view style="width: 37.5%;display: inline-block;">{{item[items.name+'endTime']||' '}}</view>
+							</view>
+						</template>
+						<template v-else-if="items.label=='配套'">
+							<view style="display:inline-block;height: 100%;width: 100%;">
+								<view style="width: 50%;display: inline-block;">{{item[items.name+'startTime']||' '}}</view>
+								<view style="width: 50%;display: inline-block;">{{item[items.name+'endTime']||' '}}</view>
+							</view>
+						</template>
+						<template v-else>{{item[items.name]||''}}</template>
+					</uni-td>
+				</uni-tr>
+			</uni-table>
+
+			<!-- <zb-table :show-header="true" :columns="column" :stripe="true" :fit="false" @cellClick="cellClick"
+				:summary-method="getSummaries" @toggleRowSelection="toggleRowSelection" @toggleAllSelection="toggleAllSelection"
+				:border="true" @edit="buttonEdit" @dele="dele" :data="tableData"></zb-table> -->
+		</view>
+		<view style="height: 40px;">
+
+		</view>
+		<view class="uni-pagination-box down-button"><uni-pagination show-icon :page-size="queryfrom.pageSize"
+				:current="queryfrom.pageNum" :total="total" @change="change" /></view>
+	</view>
+</template>
+
+<script>
+	import { listManuOrder, } from '@/api/order/schedule.js'
+	import { formatDate, formatDateMinute } from '@/utils/date.js'
+	import config from '@/config'
+	import { toast, showConfirm, tansParams } from '@/utils/common'
+	import { getToken } from '@/utils/auth'
+	import jweixin from 'weixin-js-sdk'
+	const baseUrl = config.baseUrl
+	export default {
+		data() {
+			return {
+				getDataApi: listManuOrder,
+				tableData: [],
+				// 数据总量
+				total: 0,
+				loading: false,
+				queryfrom: {
+					pageSize: 15,
+					// 每页数据量
+					pageNum: 1,
+					// 当前页
+					facId: '',
+					styleNum: '',
+					color: '',
+					version: ''
+				},
+				procOption: [],
+				searchShow: false,
+				picker: [],
+				column: [
+					// { type: 'selection', fixed: true, width: 50 },
+					// { name: 'id', type: 'index', label: '序号', width: 53, align: 'center' },
+					{ name: 'picture', label: '主图', width: 75, align: 'center' },
+					{ name: 'styleNum', label: '工厂款号', width: 90, align: 'center' },
+					{ name: 'version', label: '版本号', width: 55, align: 'center' },
+					{ name: 'color', label: '中文颜色', width: 70, align: 'center' },
+					{ name: 'custNum', label: '客户款号', width: 110, align: 'center' },
+					{ name: 'qtyTotal', label: '订单数量', width: 65, align: 'center' },
+					{ name: 'id', label: 'ID', width: 30, align: 'center' },
+					{ name: 'entryDate', label: '下单日期', width: 90, sorter: true, emptyString: '', align: 'center' },
+					{ name: 'factoryName', label: '生产工厂', width: 60, align: 'center', emptyString: '' },
+					{ name: 'facHandDate', label: '工厂交期', width: 90, sorter: true, emptyString: '', align: 'center' },
+					{ name: 'custName', label: '客户名称', fixed: false, width: 65, emptyString: '--', align: 'center' },
+					{ name: 'manuNum', label: '指令号', sorter: false, align: 'center', width: 100, },
+					{ name: 'styleFlag', label: '款式标记', width: 60, align: 'center', filters: { 0: '旧款', 1: '新款' } },
+					{ name: 'shoeLastNum', label: '楦头编号', width: 110, align: 'center', emptyString: '' },
+					{ name: 'outsoleModelNum', label: '大底编号', width: 95, align: 'center', emptyString: '' },
+					{ name: 'outsoleModelFac', label: '大底厂家', width: 60, align: 'center', emptyString: '' },
+					{ name: 'remark', label: '业务备注', width: 60, align: 'center', emptyString: '' },
+					{ name: '确认样提供', label: '确认样提供', width: 75, align: 'center' },
+					{ name: '色卡提供', label: '色卡提供', width: 70, align: 'center' },
+					{ name: '是否技转', label: '是否技转', width: 60, align: 'center' },
+					{ name: '帮面', label: '帮面材料', width: 90, align: 'center', },
+					{ name: '大底', label: '大底材料', width: 90, align: 'center' },
+					{ name: '包装', label: '包装材料', width: 90, align: 'center' },
+					{ name: '冲裁', label: '冲裁', width: 240, align: 'center' },
+					{ name: '配套', label: '配套', width: 180, align: 'center' },
+					{ name: '针车', label: '针车', width: 240, align: 'center' },
+					{ name: '成型', label: '成型', width: 240, align: 'center' },
+					{ name: 'remark', label: '备注', width: 60, align: 'center' },
+					{ name: 'postpone', label: '延期', width: 60, align: 'center' },
+					{ name: 'audit', label: '是否审核', width: 60, align: 'center' },
+					// {
+					// 	name: 'operation',
+					// 	type: 'operation',
+					// 	label: '操作',
+					// 	renders: [{
+					// 			name: '编辑',
+					// 			func: 'edit' // func 代表子元素点击的事件 父元素接收的事件 父元素 @edit
+					// 		},
+					// 		{
+					// 			name: '删除',
+					// 			type: 'warn',
+					// 			func: 'dele'
+					// 		},
+					// 	]
+					// },
+				],
+			}
+		},
+		onLoad() {
+			this.picker = this.$store.state.user.factoryOption
+			this.procOption = this.$store.state.user.procOption
+			console.log(this.procOption)
+			this.selectedIndexs = []
+			this.getData(1)
+		},
+		methods: {
+			// 微信聊天选择文件
+			chooseFileClick() {
+				wx.chooseMessageFile({
+					count: 10,
+					type: 'all', //all,video,image,file
+					success: res => {
+						// /manu/sched/imp
+						let header = { 'Authorization': 'Bearer ' + getToken() }
+						uni.uploadFile({
+							url: baseUrl + '/manu/sched/imp', //仅为示例,非真实的接口地址
+							filePath: res.tempFiles[0].path,
+							header: header,
+							name: 'file',
+							formData: {},
+							complete: function(uploadFileRes) {
+								let result = JSON.parse(uploadFileRes.data)
+								console.log(result)
+								if (result.code === 500) {
+									toast(result.msg)
+								}
+								if (result.code === 200) {
+									toast('上传成功')
+								}
+							}
+						})
+					},
+				})
+			},
+			cellClick(row, index, column) {
+				if (column.name === 'remark' || column.name === '')
+					uni.showToast({
+						icon: 'none',
+						duration: 3000,
+						title: '点击' + column.label
+					})
+				console.log('点击单元格', row, index, column)
+			},
+			rowClick(row, index) {
+				uni.showToast({
+					icon: 'none',
+					duration: 3000,
+					title: '单击某行'
+				})
+				console.log('单击某行', row, index)
+			},
+			PickerChange(e) {
+
+				console.log('e', e.detail)
+				this.queryfrom.facId = e.detail.value[0].value
+			},
+			iconClick(type) {
+				if (type === 'prefix') {
+					this.searchShow = !this.searchShow
+				} else { this.getData(1) }
+				// uni.showToast({
+				// 	title: `点击了${type==='prefix'?'左侧':'右侧'}的图标`,
+				// 	icon: 'none'
+				// })
+			},
+			// 分页触发
+			change(e) {
+				// this.$refs.table.clearSelection()
+				this.selectedIndexs.length = 0
+				console.log(e.current)
+				this.getData(e.current)
+			},
+			formatDate(time) {
+				return formatDate(time)
+			},
+			judgePostpone(item) {
+				return formatDate(item.facHandDate) < (item['成型endTime'] ? formatDate(item['成型endTime']) : formatDate(
+					new Date())) ? '延期' : ''
+			},
+			// 获取数据
+			getData(pageCurrent, value = '') {
+				// this.loading = true;
+				// this.pageCurrent = pageCurrent
+				// this.request({
+				// 	pageSize: this.pageSize,
+				// 	pageCurrent: pageCurrent,
+				// 	value: value,
+				// 	success: res => {
+				// 		// console.log('data', res);
+				// 		this.tableData = res.data
+				// 		this.total = res.total
+				// 		this.loading = false
+				// 	}
+				// })
+				this.queryfrom.pageNum = pageCurrent
+
+				// uni.showLoading({ title: '加载中' })
+				this.getDataApi(this.queryfrom).then(res => {
+					uni.hideLoading()
+					this.loading = false
+					console.log(res.rows)
+					if (res.code === 200) {
+						this.tableData = res.rows.map(item => {
+							item.picture = item.shoeStyle.mainPicture ? item.shoeStyle.mainPicture.filePath : ''
+							item.entryDate = formatDate(item.entryDate)
+							item.factoryName = item.factory.name
+							item.facHandDate = formatDate(item.facHandDate)
+							item.custName = item.custName
+							item.styleFlag = item.shoeStyle.styleFlag
+							item.styleNum = item.shoeStyle.styleNum
+							item.version = item.shoeStyle.version
+							item.color = item.shoeStyle.color
+							item.shoeLastNum = item.shoeStyle.shoeLastNum
+							item.outsoleModelNum = item.shoeStyle.outsoleModelNum
+							item.outsoleModelFac = item.shoeStyle.outsoleModelFac
+							// item.shoeremark = item.shoeStyle.remark
+							item.sched && item.sched.detList.map(detItem => {
+								this.procOption.map(procItem => {
+									if (detItem.procId === procItem.id) {
+										item[procItem.procName + 'startTime'] = formatDate(detItem.startTime)
+										item[procItem.procName + 'endTime'] = formatDate(detItem.endTime)
+										item[procItem.procName + 'type'] = detItem.procType
+									}
+								})
+							})
+							// console.log(item)
+							return item
+						})
+						this.total = res.total
+						console.log(this.tableData)
+					}
+				}).catch(err => {})
+			},
+		}
+	}
+</script>
+
+<style>
+	.table-thead {
+		background-color: #FFFAF2 !important;
+		position: sticky;
+		left: 0;
+		top: 0;
+		z-index: 20;
+	}
+
+	/deep/ .uni-table-tr {
+		overflow: visible;
+		background-color: #fff;
+	}
+
+	//固定表头第一列
+	/deep/ .uni-table-tr .uni-table-th:first-child {
+		position: sticky;
+		left: 0;
+		top: 0;
+		background-color: #fff;
+		z-index: 10;
+	}
+
+	//固定表头第一列(需计算第一列宽度,我这里是200rpx)
+	/deep/ .uni-table-tr .uni-table-th:nth-child(2) {
+		position: sticky;
+		left: 75px;
+		top: 0;
+		background-color: #fff;
+		z-index: 10;
+	}
+
+	//冻结thead第一列
+	/deep/ .uni-table-tr .uni-table-td:first-child {
+		position: sticky;
+		left: 0;
+		top: 0;
+		background-color: #fff;
+		z-index: 10;
+	}
+
+	//冻结thead第二列(需计算第一列宽度)
+	/deep/ .uni-table-tr .uni-table-td:nth-child(2) {
+		position: sticky;
+		left: 75px;
+		top: 0;
+		background-color: #fff;
+		z-index: 10;
+	}
+
+	.uni-group {
+		display: flex;
+		align-items: center;
+	}
+</style>

+ 208 - 0
pages/login.vue

@@ -0,0 +1,208 @@
+<template>
+	<view class="normal-login-container">
+		<view class="logo-content align-center justify-center flex">
+			<image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
+			</image>
+			<text class="title">办公小工具登录</text>
+		</view>
+		<view class="login-form-content">
+			<view class="input-item flex align-center">
+				<view class="iconfont icon-user icon"></view>
+				<input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
+			</view>
+			<view class="input-item flex align-center">
+				<view class="iconfont icon-password icon"></view>
+				<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
+			</view>
+			<view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
+				<view class="iconfont icon-code icon"></view>
+				<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
+				<view class="login-code">
+					<image :src="codeUrl" @click="getCode" class="login-code-img"></image>
+				</view>
+			</view>
+			<view class="action-btn">
+				<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
+			</view>
+			<view class="reg text-center" v-if="register">
+				<text class="text-grey1">没有账号?</text>
+				<text @click="handleUserRegister" class="text-blue">立即注册</text>
+			</view>
+			<view class="xieyi text-center">
+				<text class="text-grey1">登录即代表同意</text>
+				<text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
+				<text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import { getCodeImg } from '@/api/login'
+
+	export default {
+		data() {
+			return {
+				codeUrl: '',
+				captchaEnabled: true,
+				// 用户注册开关
+				register: false,
+				globalConfig: getApp().globalData.config,
+				loginForm: {
+					// username: "admin",
+					// password: "admin123",
+					username: '',
+					password: '',
+					code: '',
+					uuid: ''
+				}
+			}
+		},
+		created() {
+			this.getCode()
+		},
+		methods: {
+			// 用户注册
+			handleUserRegister() {
+				this.$tab.redirectTo('/pages/register')
+			},
+			// 隐私协议
+			handlePrivacy() {
+				let site = this.globalConfig.appInfo.agreements[0]
+				this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+			},
+			// 用户协议
+			handleUserAgrement() {
+				let site = this.globalConfig.appInfo.agreements[1]
+				this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
+			},
+			// 获取图形验证码
+			getCode() {
+				getCodeImg().then(res => {
+					this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
+					if (this.captchaEnabled) {
+						this.codeUrl = 'data:image/gif;base64,' + res.img
+						this.loginForm.uuid = res.uuid
+					}
+				})
+			},
+			// 登录方法
+			async handleLogin() {
+				if (this.loginForm.username === '') {
+					this.$modal.msgError('请输入您的账号')
+				} else if (this.loginForm.password === '') {
+					this.$modal.msgError('请输入您的密码')
+				} else if (this.loginForm.code === '' && this.captchaEnabled) {
+					this.$modal.msgError('请输入验证码')
+				} else {
+					this.$modal.loading('登录中,请耐心等待...')
+					this.pwdLogin()
+				}
+			},
+			// 密码登录
+			async pwdLogin() {
+				this.$store.dispatch('Login', this.loginForm).then(() => {
+					this.$modal.closeLoading()
+					this.loginSuccess()
+				}).catch(() => {
+					if (this.captchaEnabled) {
+						this.getCode()
+					}
+				})
+			},
+			// 登录成功后,处理函数
+			loginSuccess(result) {
+				// 设置用户信息
+				this.$store.dispatch('GetInfo').then(res => {
+					var options = uni.getStorageSync('options')
+					if (options) {
+						this.$tab.reLaunch('/pages/trade/shoe-style/ShoeStyleView')
+					} else { //如果没有上一页返回首页
+						this.$tab.reLaunch('/pages/trade/shoe-style/index')
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #ffffff;
+	}
+
+	.normal-login-container {
+		width: 100%;
+
+		.logo-content {
+			width: 100%;
+			font-size: 21px;
+			text-align: center;
+			padding-top: 15%;
+
+			image {
+				border-radius: 4px;
+			}
+
+			.title {
+				margin-left: 10px;
+			}
+		}
+
+		.login-form-content {
+			text-align: center;
+			margin: 20px auto;
+			margin-top: 15%;
+			width: 80%;
+
+			.input-item {
+				margin: 20px auto;
+				background-color: #f5f6f7;
+				height: 45px;
+				border-radius: 20px;
+
+				.icon {
+					font-size: 38rpx;
+					margin-left: 10px;
+					color: #999;
+				}
+
+				.input {
+					width: 100%;
+					font-size: 14px;
+					line-height: 20px;
+					text-align: left;
+					padding-left: 15px;
+				}
+
+			}
+
+			.login-btn {
+				margin-top: 40px;
+				height: 45px;
+			}
+
+			.reg {
+				margin-top: 15px;
+			}
+
+			.xieyi {
+				color: #333;
+				margin-top: 20px;
+			}
+
+			.login-code {
+				height: 38px;
+				float: right;
+
+				.login-code-img {
+					height: 38px;
+					position: absolute;
+					margin-left: 10px;
+					width: 200rpx;
+				}
+			}
+		}
+	}
+</style>

+ 111 - 0
pages/loginSso.vue

@@ -0,0 +1,111 @@
+<template>
+	<div id="loader-wrapper">
+		<div id="loader"></div>
+		<div class="loader-section section-left"></div>
+		<div class="loader-section section-right"></div>
+		<div class="load_title">sso单点登录中,请耐心等待</div>
+	</div>
+</template>
+
+<script>
+	import {
+		getCodeImg
+	} from '@/api/login'
+	import {
+		setSsoAdminToken,
+		getOpenToken,
+		openWindowSso,
+		ssoLogout,
+		getSsoAdminToken,
+		setEnv,
+		removeEnv,
+		setToken,
+		getToken,
+		isLoginSso
+	} from '@/utils/auth';
+	export default {
+		data() {
+			return {
+				codeUrl: '',
+				ssoCode: ''
+			}
+		},
+		onLoad(query) {
+			if(!isLoginSso){
+				uni.redirectTo({
+					url: '/pages/login'
+				})
+				return false
+			}
+			// console.log(query, 3333)
+			this.ssoCode = query.ssoCode
+			setSsoAdminToken(this.ssoCode);
+			this.loginSso()
+		},
+		methods: {
+
+			params() {
+				var query = location.search.match(new RegExp("[\?\&][^\?\&]+=[^\?\&]+", "g"));
+				console.log(query, 'query')
+				query = query || '';
+				var result = {};
+				for (var i = 0; i < query.length; i++) {
+					var item = query[i].substring(1).split('=');
+					result[item[0]] = item[1];
+				}
+				return result;
+			},
+			loginSso() {
+				// var route = useRoute();
+				// const ssoCode = route.query.ssoCode;
+
+				if (getSsoAdminToken() && getToken()) {
+					var options = uni.getStorageSync('options')
+					if (options) {
+						uni.redirectTo({
+							url: '/pages/trade/shoe-style/ShoeStyleView'
+						})
+					} else { //如果没有上一页返回首页
+						uni.redirectTo({
+							url: '/pages/trade/shoe-style/index'
+						})
+					}
+				};
+				if (!this.ssoCode) {
+					if (!localStorage.getItem('ssoLogout')) {
+						localStorage.removeItem('ssoLogout');
+						setEnv();
+					};
+					ssoLogout();
+					openWindowSso();
+					return;
+				};
+				// 请求头
+
+				getOpenToken().then(res => {
+					removeEnv()
+					setToken(res.data)
+					var options = uni.getStorageSync('options')
+					if (options) {
+						this.$tab.reLaunch('/pages/trade/shoe-style/ShoeStyleView')
+					} else { //如果没有上一页返回首页
+						this.$tab.reLaunch('/pages/trade/shoe-style/index')
+					}
+				}).catch(err => {
+					console.log('获取token失效');
+					removeEnv();
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	#loader-wrapper .load_title span {
+		font-weight: normal;
+		font-style: italic;
+		font-size: 13px;
+		color: #FFF;
+		opacity: 0.5;
+	}
+</style>

+ 75 - 0
pages/mine/about/index.vue

@@ -0,0 +1,75 @@
+<template>
+  <view class="about-container">
+    <view class="header-section text-center">
+      <image style="width: 150rpx;height: 150rpx;" src="/static/logo200.png" mode="widthFix">
+      </image>
+      <uni-title type="h2" title="若依移动端"></uni-title>
+    </view>
+
+    <view class="content-section">
+      <view class="menu-list">
+        <view class="list-cell list-cell-arrow">
+          <view class="menu-item-box">
+            <view>版本信息</view>
+            <view class="text-right">v{{version}}</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow">
+          <view class="menu-item-box">
+            <view>官方邮箱</view>
+            <view class="text-right">ruoyi@xx.com</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow">
+          <view class="menu-item-box">
+            <view>服务热线</view>
+            <view class="text-right">400-999-9999</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow">
+          <view class="menu-item-box">
+            <view>公司网站</view>
+            <view class="text-right">
+              <uni-link :href="url" :text="url" showUnderLine="false"></uni-link>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <view class="copyright">
+      <view>Copyright &copy; 2022 ruoyi.vip All Rights Reserved.</view>
+    </view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        url: getApp().globalData.config.appInfo.site_url,
+        version: getApp().globalData.config.appInfo.version
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  page {
+    background-color: #f8f8f8;
+  }
+
+  .copyright {
+    margin-top: 50rpx;
+    text-align: center;
+    line-height: 60rpx;
+    color: #999;
+  }
+
+  .header-section {
+    display: flex;
+    padding: 30rpx 0 0;
+    flex-direction: column;
+    align-items: center;
+  }
+</style>

+ 631 - 0
pages/mine/avatar/index.vue

@@ -0,0 +1,631 @@
+<template>
+	<view class="container">
+		<view class="page-body uni-content-info">
+			<view class='cropper-content'>
+				<view v-if="isShowImg" class="uni-corpper" :style="'width:'+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
+					<view class="uni-corpper-content" :style="'width:'+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
+						<image :src="imageSrc" :style="'width:'+cropperW+'px;height:'+cropperH+'px'"></image>
+						<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
+						    :style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
+							<view class="uni-cropper-view-box">
+								<view class="uni-cropper-dashed-h"></view>
+								<view class="uni-cropper-dashed-v"></view>
+								<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
+								<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
+								<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
+								<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class='cropper-config'>
+				<button type="primary reverse" @click="getImage" style='margin-top: 30rpx;'> 选择头像 </button>
+				<button type="warn" @click="getImageInfo" style='margin-top: 30rpx;'> 提交 </button>
+			</view>
+			<canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; width:'+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
+		</view>
+	</view>
+</template>
+
+<script>
+  import config from '@/config'
+  import store from "@/store"
+  import { uploadAvatar } from "@/api/system/user"
+  
+  const baseUrl = config.baseUrl
+	let sysInfo = uni.getSystemInfoSync()
+	let SCREEN_WIDTH = sysInfo.screenWidth
+	let PAGE_X, // 手按下的x位置
+		PAGE_Y, // 手按下y的位置 
+		PR = sysInfo.pixelRatio, // dpi
+		T_PAGE_X, // 手移动的时候x的位置
+		T_PAGE_Y, // 手移动的时候Y的位置
+		CUT_L, // 初始化拖拽元素的left值
+		CUT_T, // 初始化拖拽元素的top值
+		CUT_R, // 初始化拖拽元素的
+		CUT_B, // 初始化拖拽元素的
+		CUT_W, // 初始化拖拽元素的宽度
+		CUT_H, //  初始化拖拽元素的高度
+		IMG_RATIO, // 图片比例
+		IMG_REAL_W, // 图片实际的宽度
+		IMG_REAL_H, // 图片实际的高度
+		DRAFG_MOVE_RATIO = 1, //移动时候的比例,
+		INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
+		DRAW_IMAGE_W = sysInfo.screenWidth // 设置生成的图片宽度
+
+	export default {
+		/**
+		 * 页面的初始数据
+		 */
+		data() {
+			return {
+				imageSrc: store.getters.avatar,
+				isShowImg: false,
+				// 初始化的宽高
+				cropperInitW: SCREEN_WIDTH,
+				cropperInitH: SCREEN_WIDTH,
+				// 动态的宽高
+				cropperW: SCREEN_WIDTH,
+				cropperH: SCREEN_WIDTH,
+				// 动态的left top值
+				cropperL: 0,
+				cropperT: 0,
+
+				transL: 0,
+				transT: 0,
+
+				// 图片缩放值
+				scaleP: 0,
+				imageW: 0,
+				imageH: 0,
+
+				// 裁剪框 宽高
+				cutL: 0,
+				cutT: 0,
+				cutB: SCREEN_WIDTH,
+				cutR: '100%',
+				qualityWidth: DRAW_IMAGE_W,
+				innerAspectRadio: DRAFG_MOVE_RATIO
+			}
+		},
+		/**
+		 * 生命周期函数--监听页面初次渲染完成
+		 */
+		onReady: function () {
+			this.loadImage()
+		},
+		methods: {
+			setData: function (obj) {
+				let that = this
+				Object.keys(obj).forEach(function (key) {
+					that.$set(that.$data, key, obj[key])
+				})
+			},
+			getImage: function () {
+				var _this = this
+				uni.chooseImage({
+					success: function (res) {
+						_this.setData({
+							imageSrc: res.tempFilePaths[0],
+						})
+						_this.loadImage()
+					},
+				})
+			},
+			loadImage: function () {
+				var _this = this
+
+				uni.getImageInfo({
+					src: _this.imageSrc,
+					success: function success(res) {
+						IMG_RATIO = 1 / 1
+						if (IMG_RATIO >= 1) {
+							IMG_REAL_W = SCREEN_WIDTH
+							IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
+						} else {
+							IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
+							IMG_REAL_H = SCREEN_WIDTH
+						}
+						let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
+						INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
+						// 根据图片的宽高显示不同的效果   保证图片可以正常显示
+						if (IMG_RATIO >= 1) {
+							let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2)
+							let cutB = cutT
+							let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2)
+							let cutR = cutL
+							_this.setData({
+								cropperW: SCREEN_WIDTH,
+								cropperH: SCREEN_WIDTH / IMG_RATIO,
+								// 初始化left right
+								cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
+								cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
+								cutL: cutL,
+								cutT: cutT,
+								cutR: cutR,
+								cutB: cutB,
+								// 图片缩放值
+								imageW: IMG_REAL_W,
+								imageH: IMG_REAL_H,
+								scaleP: IMG_REAL_W / SCREEN_WIDTH,
+								qualityWidth: DRAW_IMAGE_W,
+								innerAspectRadio: IMG_RATIO
+							})
+						} else {
+							let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2)
+							let cutR = cutL
+							let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2)
+							let cutB = cutT
+							_this.setData({
+								cropperW: SCREEN_WIDTH * IMG_RATIO,
+								cropperH: SCREEN_WIDTH,
+								// 初始化left right
+								cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
+								cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
+
+								cutL: cutL,
+								cutT: cutT,
+								cutR: cutR,
+								cutB: cutB,
+								// 图片缩放值
+								imageW: IMG_REAL_W,
+								imageH: IMG_REAL_H,
+								scaleP: IMG_REAL_W / SCREEN_WIDTH,
+								qualityWidth: DRAW_IMAGE_W,
+								innerAspectRadio: IMG_RATIO
+							})
+						}
+						_this.setData({
+							isShowImg: true
+						})
+						uni.hideLoading()
+					}
+				})
+			},
+			// 拖动时候触发的touchStart事件
+			contentStartMove(e) {
+				PAGE_X = e.touches[0].pageX
+				PAGE_Y = e.touches[0].pageY
+			},
+
+			// 拖动时候触发的touchMove事件
+			contentMoveing(e) {
+				var _this = this
+				var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
+				var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
+				// 左移
+				if (dragLengthX > 0) {
+					if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
+				} else {
+					if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
+				}
+
+				if (dragLengthY > 0) {
+					if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
+				} else {
+					if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
+				}
+				this.setData({
+					cutL: this.cutL - dragLengthX,
+					cutT: this.cutT - dragLengthY,
+					cutR: this.cutR + dragLengthX,
+					cutB: this.cutB + dragLengthY
+				})
+
+				PAGE_X = e.touches[0].pageX
+				PAGE_Y = e.touches[0].pageY
+			},
+
+			contentTouchEnd() {
+
+			},
+
+			// 获取图片
+			getImageInfo() {
+				var _this = this
+				uni.showLoading({
+					title: '图片生成中...',
+				})
+				// 将图片写入画布
+				const ctx = uni.createCanvasContext('myCanvas')
+				ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H)
+				ctx.draw(true, () => {
+					// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
+					var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W
+					var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H
+					var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W
+					var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H
+					uni.canvasToTempFilePath({
+						x: canvasL,
+						y: canvasT,
+						width: canvasW,
+						height: canvasH,
+						destWidth: canvasW,
+						destHeight: canvasH,
+						quality: 0.5,
+						canvasId: 'myCanvas',
+						success: function (res) {
+							uni.hideLoading()
+							let data = {name: 'avatarfile', filePath: res.tempFilePath}
+							uploadAvatar(data).then(response => {
+								store.commit('SET_AVATAR', baseUrl + response.imgUrl)
+								uni.showToast({ title: "修改成功", icon: 'success' })
+								uni.navigateBack()
+							})
+						}
+					})
+				})
+			},
+			// 设置大小的时候触发的touchStart事件
+			dragStart(e) {
+				T_PAGE_X = e.touches[0].pageX
+				T_PAGE_Y = e.touches[0].pageY
+				CUT_L = this.cutL
+				CUT_R = this.cutR
+				CUT_B = this.cutB
+				CUT_T = this.cutT
+			},
+
+			// 设置大小的时候触发的touchMove事件
+			dragMove(e) {
+				var _this = this
+				var dragType = e.target.dataset.drag
+				switch (dragType) {
+					case 'right':
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
+						if (CUT_R + dragLength < 0) dragLength = -CUT_R
+						this.setData({
+							cutR: CUT_R + dragLength
+						})
+						break
+					case 'left':
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
+						if (CUT_L - dragLength < 0) dragLength = CUT_L
+						if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
+						this.setData({
+							cutL: CUT_L - dragLength
+						})
+						break
+					case 'top':
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
+						if (CUT_T - dragLength < 0) dragLength = CUT_T
+						if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
+						this.setData({
+							cutT: CUT_T - dragLength
+						})
+						break
+					case 'bottom':
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
+						if (CUT_B + dragLength < 0) dragLength = -CUT_B
+						this.setData({
+							cutB: CUT_B + dragLength
+						})
+						break
+					case 'rightBottom':
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
+						var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
+
+						if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
+						let cutB = CUT_B + dragLengthY
+						let cutR = CUT_R + dragLengthX
+
+						this.setData({
+							cutB: cutB,
+							cutR: cutR
+						})
+						break
+					default:
+						break
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	/* pages/uni-cropper/index.wxss */
+
+	.uni-content-info {
+		/* position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		display: block;
+		align-items: center;
+		flex-direction: column; */
+	}
+
+	.cropper-config {
+		padding: 20rpx 40rpx;
+	}
+
+	.cropper-content {
+		min-height: 750rpx;
+		width: 100%;
+	}
+
+	.uni-corpper {
+		position: relative;
+		overflow: hidden;
+		-webkit-user-select: none;
+		-moz-user-select: none;
+		-ms-user-select: none;
+		user-select: none;
+		-webkit-tap-highlight-color: transparent;
+		-webkit-touch-callout: none;
+		box-sizing: border-box;
+	}
+
+	.uni-corpper-content {
+		position: relative;
+	}
+
+	.uni-corpper-content image {
+		display: block;
+		width: 100%;
+		min-width: 0 !important;
+		max-width: none !important;
+		height: 100%;
+		min-height: 0 !important;
+		max-height: none !important;
+		image-orientation: 0deg !important;
+		margin: 0 auto;
+	}
+	/* 移动图片效果 */
+
+	.uni-cropper-drag-box {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		cursor: move;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 1;
+	}
+	/* 内部的信息 */
+
+	.uni-corpper-crop-box {
+		position: absolute;
+		background: rgba(255, 255, 255, 0.3);
+		z-index: 2;
+	}
+
+	.uni-corpper-crop-box .uni-cropper-view-box {
+		position: relative;
+		display: block;
+		width: 100%;
+		height: 100%;
+		overflow: visible;
+		outline: 1rpx solid #69f;
+		outline-color: rgba(102, 153, 255, .75)
+	}
+	/* 横向虚线 */
+
+	.uni-cropper-dashed-h {
+		position: absolute;
+		top: 33.33333333%;
+		left: 0;
+		width: 100%;
+		height: 33.33333333%;
+		border-top: 1rpx dashed rgba(255, 255, 255, 0.5);
+		border-bottom: 1rpx dashed rgba(255, 255, 255, 0.5);
+	}
+	/* 纵向虚线 */
+
+	.uni-cropper-dashed-v {
+		position: absolute;
+		left: 33.33333333%;
+		top: 0;
+		width: 33.33333333%;
+		height: 100%;
+		border-left: 1rpx dashed rgba(255, 255, 255, 0.5);
+		border-right: 1rpx dashed rgba(255, 255, 255, 0.5);
+	}
+	/* 四个方向的线  为了之后的拖动事件*/
+
+	.uni-cropper-line-t {
+		position: absolute;
+		display: block;
+		width: 100%;
+		background-color: #69f;
+		top: 0;
+		left: 0;
+		height: 1rpx;
+		opacity: 0.1;
+		cursor: n-resize;
+	}
+
+	.uni-cropper-line-t::before {
+		content: '';
+		position: absolute;
+		top: 50%;
+		right: 0rpx;
+		width: 100%;
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+		bottom: 0;
+		height: 41rpx;
+		background: transparent;
+		z-index: 11;
+	}
+
+	.uni-cropper-line-r {
+		position: absolute;
+		display: block;
+		background-color: #69f;
+		top: 0;
+		right: 0rpx;
+		width: 1rpx;
+		opacity: 0.1;
+		height: 100%;
+		cursor: e-resize;
+	}
+
+	.uni-cropper-line-r::before {
+		content: '';
+		position: absolute;
+		top: 0;
+		left: 50%;
+		width: 41rpx;
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+		bottom: 0;
+		height: 100%;
+		background: transparent;
+		z-index: 11;
+	}
+
+	.uni-cropper-line-b {
+		position: absolute;
+		display: block;
+		width: 100%;
+		background-color: #69f;
+		bottom: 0;
+		left: 0;
+		height: 1rpx;
+		opacity: 0.1;
+		cursor: s-resize;
+	}
+
+	.uni-cropper-line-b::before {
+		content: '';
+		position: absolute;
+		top: 50%;
+		right: 0rpx;
+		width: 100%;
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+		bottom: 0;
+		height: 41rpx;
+		background: transparent;
+		z-index: 11;
+	}
+
+	.uni-cropper-line-l {
+		position: absolute;
+		display: block;
+		background-color: #69f;
+		top: 0;
+		left: 0;
+		width: 1rpx;
+		opacity: 0.1;
+		height: 100%;
+		cursor: w-resize;
+	}
+
+	.uni-cropper-line-l::before {
+		content: '';
+		position: absolute;
+		top: 0;
+		left: 50%;
+		width: 41rpx;
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+		bottom: 0;
+		height: 100%;
+		background: transparent;
+		z-index: 11;
+	}
+
+	.uni-cropper-point {
+		width: 5rpx;
+		height: 5rpx;
+		background-color: #69f;
+		opacity: .75;
+		position: absolute;
+		z-index: 3;
+	}
+
+	.point-t {
+		top: -3rpx;
+		left: 50%;
+		margin-left: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-tr {
+		top: -3rpx;
+		left: 100%;
+		margin-left: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-r {
+		top: 50%;
+		left: 100%;
+		margin-left: -3rpx;
+		margin-top: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-rb {
+		left: 100%;
+		top: 100%;
+		-webkit-transform: translate3d(-50%, -50%, 0);
+		transform: translate3d(-50%, -50%, 0);
+		cursor: n-resize;
+		width: 36rpx;
+		height: 36rpx;
+		background-color: #69f;
+		position: absolute;
+		z-index: 1112;
+		opacity: 1;
+	}
+
+	.point-b {
+		left: 50%;
+		top: 100%;
+		margin-left: -3rpx;
+		margin-top: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-bl {
+		left: 0%;
+		top: 100%;
+		margin-left: -3rpx;
+		margin-top: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-l {
+		left: 0%;
+		top: 50%;
+		margin-left: -3rpx;
+		margin-top: -3rpx;
+		cursor: n-resize;
+	}
+
+	.point-lt {
+		left: 0%;
+		top: 0%;
+		margin-left: -3rpx;
+		margin-top: -3rpx;
+		cursor: n-resize;
+	}
+	/* 裁剪框预览内容 */
+
+	.uni-cropper-viewer {
+		position: relative;
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+	}
+
+	.uni-cropper-viewer image {
+		position: absolute;
+		z-index: 2;
+	}
+</style>

+ 112 - 0
pages/mine/help/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <view class="help-container">
+    <view v-for="(item, findex) in list" :key="findex" :title="item.title" class="list-title">
+      <view class="text-title">
+        <view :class="item.icon"></view>{{ item.title }}
+      </view>
+      <view class="childList">
+        <view v-for="(child, zindex) in item.childList" :key="zindex" class="question" hover-class="hover"
+          @click="handleText(child)">
+          <view class="text-item">{{ child.title }}</view>
+          <view class="line" v-if="zindex !== item.childList.length - 1"></view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        list: [{
+            icon: 'iconfont icon-github',
+            title: '若依问题',
+            childList: [{
+              title: '若依开源吗?',
+              content: '开源'
+            }, {
+              title: '若依可以商用吗?',
+              content: '可以'
+            }, {
+              title: '若依官网地址多少?',
+              content: 'http://ruoyi.vip'
+            }, {
+              title: '若依文档地址多少?',
+              content: 'http://doc.ruoyi.vip'
+            }]
+          },
+          {
+            icon: 'iconfont icon-help',
+            title: '其他问题',
+            childList: [{
+              title: '如何退出登录?',
+              content: '请点击[我的] - [应用设置] - [退出登录]即可退出登录',
+            }, {
+              title: '如何修改用户头像?',
+              content: '请点击[我的] - [选择头像] - [点击提交]即可更换用户头像',
+            }, {
+              title: '如何修改登录密码?',
+              content: '请点击[我的] - [应用设置] - [修改密码]即可修改登录密码',
+            }]
+          }
+        ]
+      }
+    },
+    methods: {
+      handleText(item) {
+        this.$tab.navigateTo(`/pages/common/textview/index?title=${item.title}&content=${item.content}`)
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  page {
+    background-color: #f8f8f8;
+  }
+
+  .help-container {
+    margin-bottom: 100rpx;
+    padding: 30rpx;
+  }
+
+  .list-title {
+    margin-bottom: 30rpx;
+  }
+
+  .childList {
+    background: #ffffff;
+    box-shadow: 0px 0px 10rpx rgba(193, 193, 193, 0.2);
+    border-radius: 16rpx;
+    margin-top: 10rpx;
+  }
+
+  .line {
+    width: 100%;
+    height: 1rpx;
+    background-color: #F5F5F5;
+  }
+
+  .text-title {
+    color: #303133;
+    font-size: 32rpx;
+    font-weight: bold;
+    margin-left: 10rpx;
+
+    .iconfont {
+      font-size: 16px;
+      margin-right: 10rpx;
+    }
+  }
+
+  .text-item {
+    font-size: 28rpx;
+    padding: 24rpx;
+  }
+
+  .question {
+    color: #606266;
+    font-size: 28rpx;
+  }
+</style>

+ 198 - 0
pages/mine/index.vue

@@ -0,0 +1,198 @@
+<template>
+  <view class="mine-container" :style="{height: `${windowHeight}px`}">
+    <!--顶部个人信息栏-->
+    <view class="header-section">
+      <view class="flex padding justify-between">
+        <view class="flex align-center">
+          <view v-if="!avatar" class="cu-avatar xl round bg-white">
+            <view class="iconfont icon-people text-gray icon"></view>
+          </view>
+          <image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
+          </image>
+          <view v-if="!name" @click="handleToLogin" class="login-tip">
+            点击登录
+          </view>
+          <view v-if="name" @click="handleToInfo" class="user-info">
+            <view class="u_title">
+              用户名:{{ name }}
+            </view>
+          </view>
+        </view>
+        <view @click="handleToInfo" class="flex align-center">
+          <text>个人信息</text>
+          <view class="iconfont icon-right"></view>
+        </view>
+      </view>
+    </view>
+
+    <view class="content-section">
+      <view class="mine-actions grid col-4 text-center">
+        <view class="action-item" @click="handleJiaoLiuQun">
+          <view class="iconfont icon-friendfill text-pink icon"></view>
+          <text class="text">交流群</text>
+        </view>
+        <view class="action-item" @click="handleBuilding">
+          <view class="iconfont icon-service text-blue icon"></view>
+          <text class="text">在线客服</text>
+        </view>
+        <view class="action-item" @click="handleBuilding">
+          <view class="iconfont icon-community text-mauve icon"></view>
+          <text class="text">反馈社区</text>
+        </view>
+        <view class="action-item" @click="handleBuilding">
+          <view class="iconfont icon-dianzan text-green icon"></view>
+          <text class="text">点赞我们</text>
+        </view>
+      </view>
+
+      <view class="menu-list">
+        <view class="list-cell list-cell-arrow" @click="handleToEditInfo">
+          <view class="menu-item-box">
+            <view class="iconfont icon-user menu-icon"></view>
+            <view>编辑资料</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow" @click="handleHelp">
+          <view class="menu-item-box">
+            <view class="iconfont icon-help menu-icon"></view>
+            <view>常见问题</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow" @click="handleAbout">
+          <view class="menu-item-box">
+            <view class="iconfont icon-aixin menu-icon"></view>
+            <view>关于我们</view>
+          </view>
+        </view>
+        <view class="list-cell list-cell-arrow" @click="handleToSetting">
+          <view class="menu-item-box">
+            <view class="iconfont icon-setting menu-icon"></view>
+            <view>应用设置</view>
+          </view>
+        </view>
+      </view>
+
+    </view>
+  </view>
+</template>
+
+<script>
+  import storage from '@/utils/storage'
+  
+  export default {
+    data() {
+      return {
+        name: this.$store.state.user.name,
+        version: getApp().globalData.config.appInfo.version
+      }
+    },
+    computed: {
+      avatar() {
+        return this.$store.state.user.avatar
+      },
+      windowHeight() {
+        return uni.getSystemInfoSync().windowHeight - 50
+      }
+    },
+    methods: {
+      handleToInfo() {
+        this.$tab.navigateTo('/pages/mine/info/index')
+      },
+      handleToEditInfo() {
+        this.$tab.navigateTo('/pages/mine/info/edit')
+      },
+      handleToSetting() {
+        this.$tab.navigateTo('/pages/mine/setting/index')
+      },
+      handleToLogin() {
+        this.$tab.reLaunch('/pages/login')
+      },
+      handleToAvatar() {
+        this.$tab.navigateTo('/pages/mine/avatar/index')
+      },
+      handleLogout() {
+        this.$modal.confirm('确定注销并退出系统吗?').then(() => {
+          this.$store.dispatch('LogOut').then(() => {
+            this.$tab.reLaunch('/pages/trade/shoe-style/index')
+          })
+        })
+      },
+      handleHelp() {
+        this.$tab.navigateTo('/pages/mine/help/index')
+      },
+      handleAbout() {
+        this.$tab.navigateTo('/pages/mine/about/index')
+      },
+      handleJiaoLiuQun() {
+        this.$modal.showToast('QQ群:①133713780、②146013835')
+      },
+      handleBuilding() {
+        this.$modal.showToast('模块建设中~')
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  page {
+    background-color: #f5f6f7;
+  }
+
+  .mine-container {
+    width: 100%;
+    height: 100%;
+
+
+    .header-section {
+      padding: 15px 15px 45px 15px;
+      background-color: #3c96f3;
+      color: white;
+
+      .login-tip {
+        font-size: 18px;
+        margin-left: 10px;
+      }
+
+      .cu-avatar {
+        border: 2px solid #eaeaea;
+
+        .icon {
+          font-size: 40px;
+        }
+      }
+
+      .user-info {
+        margin-left: 15px;
+
+        .u_title {
+          font-size: 18px;
+          line-height: 30px;
+        }
+      }
+    }
+
+    .content-section {
+      position: relative;
+      top: -50px;
+
+      .mine-actions {
+        margin: 15px 15px;
+        padding: 20px 0px;
+        border-radius: 8px;
+        background-color: white;
+
+        .action-item {
+          .icon {
+            font-size: 28px;
+          }
+
+          .text {
+            display: block;
+            font-size: 13px;
+            margin: 8px 0px;
+          }
+        }
+      }
+    }
+  }
+</style>

+ 127 - 0
pages/mine/info/edit.vue

@@ -0,0 +1,127 @@
+<template>
+  <view class="container">
+    <view class="example">
+      <uni-forms ref="form" :model="user" labelWidth="80px">
+        <uni-forms-item label="用户昵称" name="nickName">
+          <uni-easyinput v-model="user.nickName" placeholder="请输入昵称" />
+        </uni-forms-item>
+        <uni-forms-item label="手机号码" name="phonenumber">
+          <uni-easyinput v-model="user.phonenumber" placeholder="请输入手机号码" />
+        </uni-forms-item>
+        <uni-forms-item label="邮箱" name="email">
+          <uni-easyinput v-model="user.email" placeholder="请输入邮箱" />
+        </uni-forms-item>
+        <uni-forms-item label="性别" name="sex" required>
+          <uni-data-checkbox v-model="user.sex" :localdata="sexs" />
+        </uni-forms-item>
+      </uni-forms>
+      <button type="primary" @click="submit">提交</button>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { getUserProfile } from "@/api/system/user"
+  import { updateUserProfile } from "@/api/system/user"
+
+  export default {
+    data() {
+      return {
+        user: {
+          nickName: "",
+          phonenumber: "",
+          email: "",
+          sex: ""
+        },
+        sexs: [{
+          text: '男',
+          value: "0"
+        }, {
+          text: '女',
+          value: "1"
+        }],
+        rules: {
+          nickName: {
+            rules: [{
+              required: true,
+              errorMessage: '用户昵称不能为空'
+            }]
+          },
+          phonenumber: {
+            rules: [{
+              required: true,
+              errorMessage: '手机号码不能为空'
+            }, {
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+              errorMessage: '请输入正确的手机号码'
+            }]
+          },
+          email: {
+            rules: [{
+              required: true,
+              errorMessage: '邮箱地址不能为空'
+            }, {
+              format: 'email',
+              errorMessage: '请输入正确的邮箱地址'
+            }]
+          }
+        }
+      }
+    },
+    onLoad() {
+      this.getUser()
+    },
+    onReady() {
+      this.$refs.form.setRules(this.rules)
+    },
+    methods: {
+      getUser() {
+        getUserProfile().then(response => {
+          this.user = response.data
+        })
+      },
+      submit(ref) {
+        this.$refs.form.validate().then(res => {
+          updateUserProfile(this.user).then(response => {
+            this.$modal.msgSuccess("修改成功")
+          })
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  page {
+    background-color: #ffffff;
+  }
+
+  .example {
+    padding: 15px;
+    background-color: #fff;
+  }
+
+  .segmented-control {
+    margin-bottom: 15px;
+  }
+
+  .button-group {
+    margin-top: 15px;
+    display: flex;
+    justify-content: space-around;
+  }
+
+  .form-item {
+    display: flex;
+    align-items: center;
+    flex: 1;
+  }
+
+  .button {
+    display: flex;
+    align-items: center;
+    height: 35px;
+    line-height: 35px;
+    margin-left: 10px;
+  }
+</style>

+ 58 - 0
pages/mine/info/index.vue

@@ -0,0 +1,58 @@
+<template>
+	<view class="container">
+		<uni-list :border="true">
+			<uni-list-item title="昵称" >
+				<view slot="footer" >
+					{{userinfo.nickname}}
+				</view>
+			</uni-list-item>
+			<uni-list-item title="手机号码" >
+				<view slot="footer" >
+					{{userinfo.phonenumber}}
+				</view>
+			</uni-list-item>
+			<uni-list-item title="部门" >
+				<view slot="footer" >
+					{{userinfo.deptName}}
+				</view>
+			</uni-list-item>
+			<uni-list-item title="身份证号码" >
+				<view slot="footer" >
+					{{userinfo.idCard}}
+				</view>
+			</uni-list-item>
+			<uni-list-item title="银行卡号" >
+				<view slot="footer" >
+					{{userinfo.accNo}}
+				</view>
+			</uni-list-item>
+			<uni-list-item title="开户行" >
+				<view slot="footer" >
+					{{userinfo.bank}}
+				</view>
+			</uni-list-item>
+		</uni-list>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				userinfo: this.$store.state.user.userinfo
+			}
+		},
+		onLoad() {
+			// console.log(this.userinfo, 'userinfo')
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #ffffff;
+	}
+</style>

+ 85 - 0
pages/mine/pwd/index.vue

@@ -0,0 +1,85 @@
+<template>
+  <view class="pwd-retrieve-container">
+    <uni-forms ref="form" :value="user" labelWidth="80px">
+      <uni-forms-item name="oldPassword" label="旧密码">
+        <uni-easyinput type="password" v-model="user.oldPassword" placeholder="请输入旧密码" />
+      </uni-forms-item>
+      <uni-forms-item name="newPassword" label="新密码">
+        <uni-easyinput type="password" v-model="user.newPassword" placeholder="请输入新密码" />
+      </uni-forms-item>
+      <uni-forms-item name="confirmPassword" label="确认密码">
+        <uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认新密码" />
+      </uni-forms-item>
+      <button type="primary" @click="submit">提交</button>
+    </uni-forms>
+  </view>
+</template>
+
+<script>
+  import { updateUserPwd } from "@/api/system/user"
+
+  export default {
+    data() {
+      return {
+        user: {
+          oldPassword: undefined,
+          newPassword: undefined,
+          confirmPassword: undefined
+        },
+        rules: {
+          oldPassword: {
+            rules: [{
+              required: true,
+              errorMessage: '旧密码不能为空'
+            }]
+          },
+          newPassword: {
+            rules: [{
+                required: true,
+                errorMessage: '新密码不能为空',
+              },
+              {
+                minLength: 6,
+                maxLength: 20,
+                errorMessage: '长度在 6 到 20 个字符'
+              }
+            ]
+          },
+          confirmPassword: {
+            rules: [{
+                required: true,
+                errorMessage: '确认密码不能为空'
+              }, {
+                validateFunction: (rule, value, data) => data.newPassword === value,
+                errorMessage: '两次输入的密码不一致'
+              }
+            ]
+          }
+        }
+      }
+    },
+    onReady() {
+      this.$refs.form.setRules(this.rules)
+    },
+    methods: {
+      submit() {
+        this.$refs.form.validate().then(res => {
+          updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
+            this.$modal.msgSuccess("修改成功")
+          })
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  page {
+    background-color: #ffffff;
+  }
+
+  .pwd-retrieve-container {
+    padding-top: 36rpx;
+    padding: 15px;
+  }
+</style>

+ 78 - 0
pages/mine/setting/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <view class="setting-container" :style="{height: `${windowHeight}px`}">
+    <view class="menu-list">
+      <view class="list-cell list-cell-arrow" @click="handleToPwd">
+        <view class="menu-item-box">
+          <view class="iconfont icon-password menu-icon"></view>
+          <view>修改密码</view>
+        </view>
+      </view>
+      <view class="list-cell list-cell-arrow" @click="handleToUpgrade">
+        <view class="menu-item-box">
+          <view class="iconfont icon-refresh menu-icon"></view>
+          <view>检查更新</view>
+        </view>
+      </view>
+      <view class="list-cell list-cell-arrow" @click="handleCleanTmp">
+        <view class="menu-item-box">
+          <view class="iconfont icon-clean menu-icon"></view>
+          <view>清理缓存</view>
+        </view>
+      </view>
+    </view>
+    <view class="cu-list menu">
+      <view class="cu-item item-box">
+        <view class="content text-center" @click="handleLogout">
+          <text class="text-black">退出登录</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        windowHeight: uni.getSystemInfoSync().windowHeight
+      }
+    },
+    methods: {
+      handleToPwd() {
+        this.$tab.navigateTo('/pages/mine/pwd/index')
+      },
+      handleToUpgrade() {
+        this.$modal.showToast('模块建设中~')
+      },
+      handleCleanTmp() {
+        this.$modal.showToast('模块建设中~')
+      },
+      handleLogout() {
+        this.$modal.confirm('确定注销并退出系统吗?').then(() => {
+          this.$store.dispatch('LogOut').then(() => {
+            this.$tab.reLaunch('/pages/trade/shoe-style/index')
+          })
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .page {
+    background-color: #f8f8f8;
+  }
+
+  .item-box {
+    background-color: #FFFFFF;
+    margin: 30rpx;
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+    padding: 10rpx;
+    border-radius: 8rpx;
+    color: #303133;
+    font-size: 32rpx;
+  }
+</style>

+ 196 - 0
pages/register.vue

@@ -0,0 +1,196 @@
+<template>
+  <view class="normal-login-container">
+    <view class="logo-content align-center justify-center flex">
+      <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
+      </image>
+      <text class="title">若依移动端注册</text>
+    </view>
+    <view class="login-form-content">
+      <view class="input-item flex align-center">
+        <view class="iconfont icon-user icon"></view>
+        <input v-model="registerForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
+      </view>
+      <view class="input-item flex align-center">
+        <view class="iconfont icon-password icon"></view>
+        <input v-model="registerForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
+      </view>
+      <view class="input-item flex align-center">
+        <view class="iconfont icon-password icon"></view>
+        <input v-model="registerForm.confirmPassword" type="password" class="input" placeholder="请输入重复密码" maxlength="20" />
+      </view>
+      <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
+        <view class="iconfont icon-code icon"></view>
+        <input v-model="registerForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
+        <view class="login-code"> 
+          <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
+        </view>
+      </view>
+      <view class="action-btn">
+        <button @click="handleRegister()" class="register-btn cu-btn block bg-blue lg round">注册</button>
+      </view>
+    </view>
+    <view class="xieyi text-center">
+      <text @click="handleUserLogin" class="text-blue">微信登录</text>
+    </view>
+  </view>
+</template>
+
+<script>
+  import { getCodeImg, register } from '@/api/login'
+
+  export default {
+    data() {
+      return {
+        codeUrl: "",
+        captchaEnabled: true,
+        globalConfig: getApp().globalData.config,
+        registerForm: {
+          username: "",
+          password: "",
+          confirmPassword: "",
+          code: "",
+          uuid: ''
+        }
+      }
+    },
+    created() {
+      this.getCode()
+    },
+    methods: {
+      // 用户登录
+      handleUserLogin() {
+        this.$tab.navigateTo(`/pages/login`)
+      },
+      // 获取图形验证码
+      getCode() {
+        getCodeImg().then(res => {
+          this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
+          if (this.captchaEnabled) {
+            this.codeUrl = 'data:image/gif;base64,' + res.img
+            this.registerForm.uuid = res.uuid
+          }
+        })
+      },
+      // 注册方法
+      async handleRegister() {
+        if (this.registerForm.username === "") {
+          this.$modal.msgError("请输入您的账号")
+        } else if (this.registerForm.password === "") {
+          this.$modal.msgError("请输入您的密码")
+        } else if (this.registerForm.confirmPassword === "") {
+          this.$modal.msgError("请再次输入您的密码")
+        } else if (this.registerForm.password !== this.registerForm.confirmPassword) {
+          this.$modal.msgError("两次输入的密码不一致")
+        } else if (this.registerForm.code === "" && this.captchaEnabled) {
+          this.$modal.msgError("请输入验证码")
+        } else {
+          this.$modal.loading("注册中,请耐心等待...")
+          this.register()
+        }
+      },
+      // 用户注册
+      async register() {
+        register(this.registerForm).then(res => {
+          this.$modal.closeLoading()
+          uni.showModal({
+          	title: "系统提示",
+          	content: "恭喜你,您的账号 " + this.registerForm.username + " 注册成功!",
+          	success: function (res) {
+          		if (res.confirm) {
+                uni.redirectTo({ url: `/pages/login` });
+          		}
+          	}
+          })
+        }).catch(() => {
+          if (this.captchaEnabled) {
+            this.getCode()
+          }
+        })
+      },
+      // 注册成功后,处理函数
+      registerSuccess(result) {
+        // 设置用户信息
+        this.$store.dispatch('GetInfo').then(res => {
+          this.$tab.reLaunch('/pages/trade/shoe-style/index')
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  page {
+    background-color: #ffffff;
+  }
+
+  .normal-login-container {
+    width: 100%;
+
+    .logo-content {
+      width: 100%;
+      font-size: 21px;
+      text-align: center;
+      padding-top: 15%;
+
+      image {
+        border-radius: 4px;
+      }
+
+      .title {
+        margin-left: 10px;
+      }
+    }
+
+    .login-form-content {
+      text-align: center;
+      margin: 20px auto;
+      margin-top: 15%;
+      width: 80%;
+
+      .input-item {
+        margin: 20px auto;
+        background-color: #f5f6f7;
+        height: 45px;
+        border-radius: 20px;
+
+        .icon {
+          font-size: 38rpx;
+          margin-left: 10px;
+          color: #999;
+        }
+
+        .input {
+          width: 100%;
+          font-size: 14px;
+          line-height: 20px;
+          text-align: left;
+          padding-left: 15px;
+        }
+
+      }
+
+      .register-btn {
+        margin-top: 40px;
+        height: 45px;
+      }
+
+      .xieyi {
+        color: #333;
+        margin-top: 20px;
+      }
+      
+      .login-code {
+        height: 38px;
+        float: right;
+      
+        .login-code-img {
+          height: 38px;
+          position: absolute;
+          margin-left: 10px;
+          width: 200rpx;
+        }
+      }
+    }
+  }
+
+</style>

+ 248 - 0
pages/sign/index.vue

@@ -0,0 +1,248 @@
+<template>
+<<<<<<< HEAD
+    <view class="signBox column-me">
+        <!-- 这个是自定义的title-可根据自己封装的title的作为调整 -->
+        <status-bar title="电子签名" :bgColor="null"></status-bar>
+        <view class="topHint">请绘制清晰可辨的签名并保存</view>
+        <canvas class="canvas flex1" :canvas-id="cid" :id="cid" @touchstart="touchstart" @touchmove="touchmove"
+            @touchend="touchend" :disable-scroll="true"></canvas>
+        <view class="btn margin-top10 margin-bottom10">
+            <view class="cancelBtn" @click="reWrite">重写</view>
+            <view class="saveBtn margin-left30" @click="save">保存</view>
+        </view>
+    </view>
+</template>
+
+<script>
+    export default {
+        components: {},
+        data() {
+            return {
+                line: [],
+                radius: 0,
+                taskId: '',
+                //以下与签名有关参数
+                dom: null,
+                cid: 'canvas', //画布id
+                Strokes: [],
+                showCanvasDialog: false,
+                canvasImg: '', //签名图片
+            }
+        },
+        onLoad(e) {
+            this.taskId = e.taskId
+        },
+        computed: {},
+        mounted: function() {
+            let that = this
+            this.initCanvas()
+        },
+        methods: {
+            initCanvas() {
+                let that = this
+                this.$nextTick(function() {
+                    this.dom = uni.createCanvasContext(this.cid, this);
+                    var query = wx.createSelectorQuery();
+                    query.select('#canvas').boundingClientRect();
+                    query.exec(function(res) {
+                        let widths = res[0].width
+                        let heights = res[0].height
+                        that.dom.rect(0, 0, widths, heights)
+                        that.dom.setFillStyle('#FFFFFF')
+                        that.dom.fill()
+                        that.dom.draw()
+                    })
+                });
+            },
+            touchstart(e) {
+                this.Strokes.push({
+                    imageData: null,
+                    style: {
+                        color: '#000000',
+                        lineWidth: '3',
+                    },
+                    points: [{
+                        x: e.touches[0].x,
+                        y: e.touches[0].y,
+                        type: e.type,
+                    }]
+                })
+                this.drawLine(this.Strokes[this.Strokes.length - 1], e.type);
+            },
+            touchmove(e) {
+                this.Strokes[this.Strokes.length - 1].points.push({
+                    x: e.touches[0].x,
+                    y: e.touches[0].y,
+                    type: e.type,
+                })
+                this.drawLine(this.Strokes[this.Strokes.length - 1], e.type);
+            },
+            touchend(e) {
+                if (this.Strokes[this.Strokes.length - 1].points.length < 2) { //当此路径只有一个点的时候
+                    this.Strokes.pop();
+                }
+            },
+            drawLine(StrokesItem, type) {
+                if (StrokesItem.points.length > 1) {
+                    this.dom.setLineCap('round')
+                    this.dom.setStrokeStyle(StrokesItem.style.color);
+                    this.dom.setLineWidth(StrokesItem.style.lineWidth);
+                    this.dom.moveTo(StrokesItem.points[StrokesItem.points.length - 2].x, StrokesItem.points[StrokesItem
+                        .points.length -
+                        2].y);
+                    this.dom.lineTo(StrokesItem.points[StrokesItem.points.length - 1].x, StrokesItem.points[StrokesItem
+                        .points.length -
+                        1].y);
+                    this.dom.stroke();
+                    this.dom.draw(true);
+                }
+            },
+            //重写签名
+            reWrite() {
+                this.Strokes = [];
+                this.dom.draw();
+                this.initCanvas()
+            },
+            // 保存图片
+            save() {
+                let that = this
+                uni.canvasToTempFilePath({
+                    canvasId: 'canvas',
+                    fileType: 'png',
+                    quality: 1, //图片质量
+                    success: function(res) {
+                        let imgs = [res.tempFilePath]
+                        that.$.upload_img(imgs, 0, res => {
+                            let imgUrl = res.data //签名图片
+                            let mediaUrl = that.$.get_data('mediaUrl') //采集图片
+                            if (that.$.isEmpty(mediaUrl)) {
+                                mediaUrl = ''
+                            }
+                            that.$.ajax("POST", "/customer/user/checkTask", {
+                                taskId: that.taskId,
+                                status: 1, //状态:1同意2拒绝    
+                                signImage: imgUrl,
+                                userVideo: mediaUrl,
+                            }, (res) => {
+                                if (res.code === 1000) {
+                                    that.$.ti_shi(res.message)
+                                    setTimeout(() => {
+                                        uni.$emit('signOk')
+                                        that.$.back()
+                                    }, 1000)
+                                } else {
+                                    that.$.ti_shi(res.message)
+                                }
+                            });
+                        })
+                    },
+                    fail(e) {
+                        console.log(e)
+                    }
+                })
+            }
+        }
+    }
+</script>
+
+<style scoped lang="less">
+    .signBox {
+        position: relative;
+        overflow: hidden;
+        background-color: #F6F6F6;
+        height: 100vh;
+        width: 100vw;
+
+        .canvas {
+            width: 100%;
+            background: #FFFFFF;
+        }
+
+        .topHint {
+            width: 100%;
+            height: 60rpx;
+            line-height: 60rpx;
+            font-size: 28rpx;
+            color: #6D7984;
+            text-align: center;
+            background: ;
+        }
+
+        .btn {
+            width: 100%;
+            height: 132rpx;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+
+            .saveBtn {
+                width: 300rpx;
+                height: 88rpx;
+                line-height: 88rpx;
+                background: #215AA0;
+                border-radius: 20rpx;
+                text-align: center;
+                font-size: 32rpx;
+                color: #FFFFFF;
+            }
+
+            .cancelBtn {
+                width: 298rpx;
+                height: 86rpx;
+                line-height: 86rpx;
+                background: #FFFFFF;
+                border-radius: 20rpx;
+                text-align: center;
+                font-size: 32rpx;
+                color: #202233;
+                border: 1px solid #BBC4CC;
+            }
+        }
+    }
+</style>
+=======
+	<view>
+		<signature :salaryId="salaryId" :showCanvas="showCanvas" @closeCanvas="closeCanvas"></signature>
+		<uni-popup ref="popup" type="dialog">
+			<uni-popup-dialog mode="input" message="成功消息" :duration="2000" :before-close="true" @close="close" @confirm="confirm"></uni-popup-dialog>
+		</uni-popup>
+	</view>
+</template>
+<script>
+import signature from './signMode/signMode.vue';
+export default {
+	components: {
+		signature
+	},
+	data() {
+		return {
+		//打开canvas绘制签名
+			showCanvas: true,
+			salaryId:'',
+			//是否展示操作菜单
+			completionSignPath: '' //签名
+		}
+	},
+	onLoad: function(options) {
+			this.salaryId=Number(options.id)
+			console.log(options, 'options')
+			
+			
+	},
+	methods: {
+			//隐藏canvas签名组件
+			closeCanvas(e) {
+				uni.navigateBack({ delta: 1 })
+				// this.showCanvas = false;
+				console.log(e,'eeee')
+				if (e) {
+					this.completionSignPath = e
+				}
+			},
+			sign() {
+				this.showCanvas = true;
+			}
+		}
+}
+</script>
+>>>>>>> d5d543f6014ac2bbe7c450bec75cf372ae8284be

+ 632 - 0
pages/sign/signMode/signMode.vue

@@ -0,0 +1,632 @@
+<template>
+<<<<<<< HEAD
+    <view class="main-content" v-if="isShow">
+        <!-- 签字canvas -->
+        <block v-if="showCanvas">
+            <canvas
+                class="mycanvas" 
+                id="mycanvas" 
+                canvas-id="mycanvas" 
+                @touchstart="touchstart" 
+                @touchmove="touchmove" 
+                @touchend="touchend"
+                disable-scroll="true"
+            ></canvas>
+            <!-- 旋转canvas -->
+            
+        </block>
+        <block class="" v-else>
+            <image :src="imgurl" mode="" class="sign-img"></image>
+        </block>
+        <canvas
+            class="rotatCanvas"
+            id="rotatCanvas"
+            :style="{ 'z-index': -1, width: `${screenWidth}px`, height: `${(screenWidth * screenWidth) / screenHeight}px` }"
+            canvas-id="rotatCanvas"
+        ></canvas>
+        <view class="button-line">
+            <view class="save-button" @tap.stop="finish">保存</view>
+            <view class="clear-button" @tap.stop="clear">清除</view>
+            <view class="cancel-button" @tap.stop="hide">关闭</view>
+        </view>
+        <view class="mask" v-if="showModal" @tap.stop>
+            <view class="kw-modal flex align-items-center justify-content-center">
+                <view class="kw-modal-content">
+                    <view class="flex justify-content-end font-size-34 lightgray">
+                        <text class="iconfont icon-guanbi" @tap="close"></text>
+                    </view>
+                    <view class="flex justify-content-center font-size-38 font-600 kw-modal-title">
+                        {{title}}
+                    </view>
+                    <view class="kw-modal-btnbox flex justify-content-between">
+                        <view @tap="cancel" class="kw-modal-btn">{{cancelText}}</view>
+                        <view @tap="confirm" class="kw-modal-btn">{{confirmText}}</view>
+                    </view>
+                </view>
+            </view>
+        </view>
+        <view class="mask" v-if="showToast">
+            <view class="sign-toast flex align-items-center justify-content-center">
+                <view class="toast-box">请先签名</view>
+            </view>
+        </view>
+        
+    </view>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            ctx: '', //绘图图像
+            points: [], //路径点集合
+            screenWidth: '',
+            screenHeight: '',
+            isRotatShow:false,
+            showModal:false,
+            showToast:false,
+            startX:'',
+            startY:'',
+            moveX:'',
+            moveY:'',
+            imgurl:'',
+            showCanvas:true,
+            title:'提示框',
+            cancelText:'取消',
+            confirmText:'确认',
+        };
+    },
+    props:{
+        isShow:{
+            type:Boolean,
+            default:true
+        }
+    },
+    mounted() {
+        this.createCanvas();
+        uni.getSystemInfo({
+            success: e => {
+                this.screenWidth = e.screenWidth;
+                this.screenHeight = e.screenHeight - 110;
+                console.log(e,'e')
+            }
+        });
+    },
+    methods: {
+        show() {
+            this.clear();
+            this.isShow = true;
+        },
+        hide() {
+            this.$emit('close',false)
+            this.showCanvas = true
+        },
+        close(){
+            this.showCanvas = true
+            this.showModal = false
+        },
+        //取消保存
+        cancel(){
+            this.close()
+            //清除画布
+            this.clear()
+        },
+        confirm(){
+            this.rotat(this.imgurl);
+        },
+        save(){
+            this.showCanvas = false
+            console.log(this.moveX,'moveX')
+            console.log(this.moveY,'moveY')
+            if(!this.moveX&&!this.moveY){
+                this.showToast = true
+                setTimeout(()=>{
+                    this.showToast = false
+                    this.showCanvas = true
+                },1500)
+                return false
+            }
+            this.showModal = true
+            this.title = '确认签字?一旦确认,不能修改'
+        },
+        //创建并显示画布
+        createCanvas() {
+            this.showCanvas = true;
+            this.ctx = uni.createCanvasContext('mycanvas', this); //创建绘图对象
+            //设置画笔样式
+            this.ctx.lineWidth = 2;
+            this.ctx.lineCap = 'round';
+            this.ctx.lineJoin = 'round';
+        },
+        //触摸开始,获取到起点
+        touchstart(e) {
+            let startX = e.changedTouches[0].x;
+            let startY = e.changedTouches[0].y;
+            let startPoint = {
+                X: startX,
+                Y: startY
+            };
+            this.points.push(startPoint);
+            //每次触摸开始,开启新的路径
+            this.ctx.beginPath();
+        },
+        //触摸移动,获取到路径点
+        touchmove(e) {
+            this.moveX = e.changedTouches[0].x;
+            this.moveX = e.changedTouches[0].y;
+            let moveX = e.changedTouches[0].x;
+            let moveY = e.changedTouches[0].y;
+            let movePoint = {
+                X: moveX,
+                Y: moveY
+            };
+            this.points.push(movePoint); //存点
+            let len = this.points.length;
+            if (len >= 2) {
+                this.draw(); //绘制路径
+            }
+        },
+        // 触摸结束,将未绘制的点清空防止对后续路径产生干扰
+        touchend() {
+            this.points = [];
+        },
+        draw() {
+            let point1 = this.points[0];
+            let point2 = this.points[1];
+            this.points.shift();
+            this.ctx.moveTo(point1.X, point1.Y);
+            this.ctx.lineTo(point2.X, point2.Y);
+            this.ctx.stroke();
+            this.ctx.draw(true);
+        },
+        //清空画布
+        clear() {
+            this.ctx.clearRect(0, 0, this.screenWidth, this.screenHeight);
+            this.ctx.draw(true);
+            this.moveX = '';
+            this.moveY = '';
+            this.showCanvas = true
+        },
+        //完成绘画并保存到本地
+        finish() {
+            uni.canvasToTempFilePath(
+                {
+                    canvasId: 'mycanvas',
+                    success: res => {
+                        this.imgurl = res.tempFilePath
+                        this.save()
+                    },
+                    complete: com => {}
+                },
+                this
+            );
+        },
+        // 将图片选装
+        rotat(e) {
+            // this.isRotatShow = true
+            // this.showCanvas = true
+            let rotatCtx = uni.createCanvasContext('rotatCanvas', this); //创建绘图对象
+            // 重新定位中心点
+            rotatCtx.translate(0, (this.screenWidth * this.screenWidth) / this.screenHeight);
+            // rotatCtx.translate(0, 0);
+            // 将画布逆时针旋转90度
+            rotatCtx.rotate((270 * Math.PI) / 180);
+            // 将签字图片绘制进入Canvas
+            rotatCtx.drawImage(e, 0, 0, (this.screenWidth * this.screenWidth) / this.screenHeight, this.screenWidth);
+            // 保存后旋转后的结果
+            rotatCtx.draw(true);
+            setTimeout(() => {
+                // 生成图片并回调
+                uni.canvasToTempFilePath(
+                    {
+                        canvasId: 'rotatCanvas',
+                        success: val => {
+                            console.log('tempFilePath', val.tempFilePath)
+                            this.showCanvas = false
+                            this.$emit('savesign', {tempFilePath: val.tempFilePath ,flag: true} );
+                            setTimeout(() => {
+                                this.hide();
+                            }, 500);
+                        },
+                        complete: com => {
+                            // console.log(com);
+                        }
+                    },
+                    this
+                );
+            }, 500);
+        }
+    }
+};
+</script>
+<style lang="scss" scoped>
+.main-content {
+    width: 100vw;
+    height: 100vh;
+    background-color: #ffffff;
+    z-index: 9999;
+    overflow: hidden;
+    max-height:100vh;
+}
+.mycanvas {
+    width: 100vw;
+    height: calc(100vh - 120px);
+    background-color: #efefef;
+    position: fixed;
+    left: 0rpx;
+    top: 0rpx;
+    z-index: 2;
+}
+.sign-img{
+    width: 100vw;
+    height: calc(100vh - 110px);
+}
+.rotatCanvas{
+    background-color: red;
+}
+.button-line {
+    transform: rotate(90deg);
+    position: fixed;
+    bottom: -130rpx;
+    left: 260rpx;
+    align-items: center;
+    justify-content: space-between;
+    z-index: 999;
+}
+.button-style {
+    color: #ffffff;
+    width: 100px;
+    height: 120rpx;
+    text-align: center;
+    line-height: 120rpx;
+    border-radius: 10rpx;
+    margin-bottom: 40rpx;
+    font-size: 34rpx
+}
+.save-button {
+    @extend .button-style;
+    background-color: #02b340;
+    height: 140rpx;
+    line-height: 140rpx;
+}
+.clear-button {
+    @extend .button-style;
+    background-color: #ffa500;
+    height: 140rpx;
+    line-height: 140rpx;
+}
+.cancel-button {
+    @extend .button-style;
+    background-color: #e10b2b;
+}
+    .mask{
+        width: 100vw;
+        height: 100vh;
+        background: rgba(0,0,0,0.8) ;
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 999;
+    }
+    .kw-modal,.sign-toast{
+        width: 50vw;
+        height: calc(100vh - 210px);
+        transform: rotate(90deg);
+        position: absolute;
+        top: 0;
+        left: 0;
+        text-align: center;
+        z-index: 999;
+    }
+    .kw-modal-content{
+        width: 690rpx;
+        // height: 400rpx;
+        background: #efefef;
+        border-radius: 30rpx;
+        padding: 38rpx 30rpx 70rpx;
+        .kw-modal-title{
+            margin-top: 22rpx;
+        }
+        .kw-modal-tips{
+            margin-top: 20rpx;
+        }
+        .kw-modal-inp{
+            margin-top: 50rpx;
+            .kw-inp{
+                border: 1rpx solid #D9D9D9;
+                border-radius: 4rpx;
+                height: 70rpx;
+                line-height: 70rpx;
+                padding: 0 30rpx;
+            }
+            .inp-title{
+                margin-right: 20rpx;
+            }
+        }
+        .kw-modal-btnbox{
+            margin-top: 100rpx;
+            display: flex;
+            justify-content: space-around;
+            .kw-modal-btn{
+                width: 300rpx;
+                height: 84rpx;
+                background: #D9D9D9;
+                border-radius: 60rpx;
+                line-height: 84rpx;
+                text-align: center;
+                font-size: 30rpx;
+                &:last-child{
+                    color: #FFFFFF;
+                    background: #59A3FF;
+                }
+            }
+        }
+    }
+    .toast-box{
+        padding: 15rpx 30rpx;
+        // background-color: rgba(0, 0, 0, .7);
+        // color: #fff;
+        background-color: #ffffff;
+        color: #ffa500;
+        border-radius: 8rpx;
+        font-size: 30rpx;
+    }
+=======
+	<view class="signature-box">
+		<!-- 签名 -->
+		<view class="signature" v-show="showCanvas">
+			<canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove"
+				@touchend="touchend"></canvas>
+		<!-- 	<view style="padding: 5px;
+    color: red;" class="text-sm colorred">注意:请用横屏签名</view> -->
+			<view class="footer">
+
+				<button @click="finish" type="primary">保存
+				</button>
+				<button @click="clear" type="default">清除
+				</button>
+				<button @click="close" type="warn">关闭
+				</button>
+			</view>
+		</view>
+
+		<!-- 签完名后生成的图片 -->
+		<!-- <view v-show="SignatureImg" class="SignatureImg">
+			<image :src="SignatureImg" mode=""></image>
+		</view> -->
+		<!-- 清除签完名后生成的图片 -->
+		<!-- <button v-show="SignatureImg" @click="obliterate" type="error" :plain="true" :ripple="true"
+			ripple-bg-color="#909399" size="medium">清除签名</button> -->
+	</view>
+</template>
+<script>
+	import {
+		sign
+	} from '@/api/workman.js'
+
+	import {
+		pathToBase64
+	} from '@/utils/jssdk_image_tools.js'
+	var x = 20;
+	var y = 20;
+	export default {
+		data() {
+			return {
+				//绘图图像
+				ctx: '',
+				//路径点集合
+				points: [],
+				//签名图片
+				SignatureImg: '',
+				hasSign: false
+			};
+		},
+		props: {
+			salaryId: {
+				type: [Number, String],
+				default: 0
+			},
+			showCanvas: {
+				type: Boolean,
+				default: false
+			},
+		},
+		created() {
+			console.log(this.salaryId, 'options333')
+
+		},
+		methods: {
+			//清除签名的图片
+			open() {
+				this.$refs.popup.open()
+			},
+			/**
+			 * 点击取消按钮触发
+			 * @param {Object} done
+			 */
+			close() {
+				// TODO 做一些其他的事情,before-close 为true的情况下,手动执行 close 才会关闭对话框
+				// ...
+				this.$refs.popup.close()
+			},
+			obliterate() {
+				if (this.SignatureImg) {
+					this.SignatureImg = '';
+				}
+				this.close();
+			},
+			//关闭并清空画布
+			close() {
+				uni.navigateBack({
+					delta: 1
+				})
+				this.clear();
+			},
+			//创建并显示画布
+			createCanvas() {
+				this.ctx = uni.createCanvasContext('mycanvas', this); //创建绘图对象
+				this.ctx.setFillStyle('#000000')
+				this.ctx.fillStyle = '#000000'
+				//设置画笔样式
+				this.ctx.lineWidth = 4;
+				this.ctx.lineCap = 'round';
+				this.ctx.lineJoin = 'round';
+				console.log(this.ctx)
+			},
+			//触摸开始,获取到起点
+			touchstart(e) {
+				let startX = e.changedTouches[0].x;
+				let startY = e.changedTouches[0].y;
+				let startPoint = {
+					X: startX,
+					Y: startY
+				};
+				this.points.push(startPoint);
+				//每次触摸开始,开启新的路径
+				this.ctx.beginPath();
+			},
+			//触摸移动,获取到路径点
+			touchmove(e) {
+				let moveX = e.changedTouches[0].x;
+				let moveY = e.changedTouches[0].y;
+				let movePoint = {
+					X: moveX,
+					Y: moveY
+				};
+				this.points.push(movePoint); //存点
+				let len = this.points.length;
+				if (len >= 2) {
+					this.draw(); //绘制路径
+				}
+			},
+			// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
+			touchend() {
+				this.points = [];
+			},
+			//绘制笔迹
+			draw() {
+				let point1 = this.points[0];
+				let point2 = this.points[1];
+				this.points.shift();
+				this.ctx.moveTo(point1.X, point1.Y);
+				this.ctx.lineTo(point2.X, point2.Y);
+				this.ctx.stroke();
+				this.ctx.draw(true);
+				this.hasSign = true
+			},
+			//清空画布
+			clear() {
+				this.hasSign = false
+				let that = this;
+				uni.getSystemInfo({
+					success: function(res) {
+						let canvasw = res.windowWidth;
+						let canvash = res.windowHeight;
+						that.ctx.clearRect(0, 0, canvasw, canvash);
+						that.ctx.draw(true);
+					}
+				});
+			},
+			//完成绘画并保存到本地
+			finish() {
+				if (!this.hasSign) {
+					uni.showToast({
+						title: '签名为空不能保存',
+						icon: 'none',
+						duration: 2000
+					})
+					return
+				}
+				let that = this;
+				uni.canvasToTempFilePath({
+					canvasId: 'mycanvas',
+					success: function(res) {
+						if (!res || !res.tempFilePath) {
+							console.log(res.tempFilePath);
+							that.SignatureImg = res.tempFilePath;
+							that.$emit('closeCanvas', that.SignatureImg);
+							that.close();
+						} else {
+							//用来解决安卓真机获取到的是canvas图片的临时路径,转成base64格式
+							pathToBase64(res.tempFilePath).then(re => {
+								uni.setStorageSync('signaTureImg', re)
+								console.log(re, 'signaTureImg')
+								uni.showLoading({
+									title: '签名中'
+								})
+								sign({
+									signId: that.salaryId,
+									pictureData: re
+								}).then(res => {
+									uni.hideLoading()
+									that.$modal.confirm('签名成功','',false).then(() => {
+										uni.navigateBack()
+									})
+								}).catch(err => {
+									uni.hideLoading()
+									
+								})
+								// that.SignatureImg = re;
+								// that.$emit('closeCanvas', that.SignatureImg);
+								// 
+							})
+						}
+					}
+				});
+			}
+		},
+		mounted() {
+			this.createCanvas();
+		}
+	};
+</script>
+<style lang="less" scoped>
+	.signature-box {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		background: #fff;
+
+		// height: calc(100vh-44rpx);
+		//签名模块
+		.signature {
+			position: fixed;
+			top: 10px;
+			left: 2%;
+			z-index: 999;
+			width: 96%;
+
+			//canvas
+			.mycanvas {
+				width: 100%;
+				// height: calc(100vh - 200upx);
+				height: calc(100vh - 60vh);
+				background-color: #fff;
+				border-radius: 10px 10px 0 0;
+			}
+			//底部按钮
+			.footer {
+				height: 130upx;
+				display: flex;
+				justify-content: space-around;
+				align-items: center;
+				background-color: #fff;
+				border-radius: 0 0 10px 10px;
+				border-top: 1px solid #a7a7a733;
+			}
+
+			::v-deep .footer uni-button {
+				font-size: 16px;
+				padding: 8rpx 50rpx;
+			}
+		}
+
+		//生成的图片
+		.SignatureImg {
+			image {
+				width: 750rpx;
+				height: 750rpx;
+			}
+		}
+	}
+>>>>>>> d5d543f6014ac2bbe7c450bec75cf372ae8284be
+</style>

+ 220 - 0
pages/trade/shoe-style/ShoeStyleView.vue

@@ -0,0 +1,220 @@
+<template>
+	<view class="padding">
+		<uni-section title="款式信息" type="line">
+			<!-- 		<uni-list>
+				<uni-list-item link @click="ViewImage(data.pice)">
+					<template v-slot:header>
+						<view class="slot-box">
+							<image class="slot-image img" :src="data.pice" mode="widthFix"></image>
+							<image class="slot-image img" :src="data.foto" mode="widthFix"></image>
+						</view>
+					</template>
+					
+					<template v-slot:body>
+						<text class="slot-box slot-text">
+							<text style="display: block;">{{data.styleNum}}</text>
+							<text style="display: block;font-size: 12px;color: #909399;">
+								版本:{{data.version}}</text>
+							<text style="display: block;font-size: 12px;color: #909399;">
+								颜色:{{data.color? data.color: ''}} {{data.enColor? data.enColor: ''}}</text>
+						</text>
+					</template>
+				</uni-list-item>
+			</uni-list> -->
+			<uni-grid :column="2" :highlight="true" :showBorder="false" :square="false" style="height: auto;">
+				<uni-grid-item v-for="(item, index) in pics" :index="index" :key="index">
+					<view class="grid-item-box" style="background-color: #fff;">
+						<image class="slot-image img" :src="item" mode="widthFix" @click="ViewImage(index)"></image>
+					</view>
+				</uni-grid-item>
+			</uni-grid>
+
+			<uni-list>
+				<uni-list-item title="款号" :rightText="data.styleNum" />
+				<uni-list-item title="颜色" :rightText="data.version + '-' +data.color" />
+				<uni-list-item title="尺码" :rightText="data.size" />
+				<uni-list-item title="码段" :rightText="data.outsoleSegment" />
+				<uni-list-item class="fob" title="FOB价" :rightText="data.fob" />
+				<uni-list-item title="备注" :rightText="data.remark" />
+			</uni-list>
+		</uni-section>
+		<view style="height: 30rpx;"></view>
+
+		<uni-list>
+			<uni-list-item title="面料" :rightText="data.upper" />
+			<uni-list-item title="内里" :rightText="data.insole" />
+			<uni-list-item title="面衬" :rightText="data.lining" />
+			<uni-list-item title="楦头" :rightText="data.lastNumber" />
+
+		</uni-list>
+		<view style="height: 30rpx;"></view>
+
+		<uni-list>
+
+			<uni-list-item title="大底" :rightText="data.outsole" />
+			<uni-list-item title="大底编号" :rightText="data.outsoleNumber" />
+			<uni-list-item title="大底厂家" :rightText="data.outsoleFactory" />
+			<uni-list-item title="日期" :rightText="formatDate(data.createTime)" />
+		</uni-list>
+		<view style="height: 30rpx;"></view>
+
+		<uni-list  v-if="checkRole(['admin','SalesManager'])">
+			<uni-list-item class="outPrice" title="大底价格参考" :rightText="data.outsolePrice" />
+			<uni-list-item class="outPrice" title="材料价格参考" :rightText="data.referPrice" />
+		</uni-list>
+
+		<!-- 	<uni-section title="鞋底图片" type="line">
+			<uni-grid :column="1" :highlight="true" :showBorder="false" :square="false" style="height: auto;">
+				<uni-grid-item style="padding: 8px;">
+					<image class="slot-image img" :src="data.foto" mode="widthFix" @click="ViewImage(1)"></image>
+				</uni-grid-item>
+			</uni-grid>
+		</uni-section> -->
+
+		<!-- 	<view style="margin-top: 10px;text-align: center;">
+			<button class="bottom" size="mini" type="primary" @click="onBackward">返回样品页</button>
+		</view> -->
+	</view>
+</template>
+
+<script>
+	import {
+		getShoeStyle,
+		listShoeStyle
+	} from '@/api/trade/shoe-style.js'
+	import {
+		formatDate,
+		formatDateMinute
+	} from '@/utils/date.js'
+	import {
+		getToken,
+		getTokens
+	} from '@/utils/auth'
+	import {
+		showConfirm,
+		toast
+	} from '@/utils/common'
+	import {
+		checkPermi,
+		checkRole
+	} from '@/utils/permission.js'
+	export default {
+		data() {
+			return {
+				formatDate,
+				getDataApi: getShoeStyle,
+				checkPermi,
+				checkRole,
+				pics: [],
+				data: {}
+			}
+		},
+		// onLoad: function(option) {
+
+		// },
+		onShow(options) {
+			let pages = getCurrentPages();
+			// 数组中索引最大的页面--当前页面
+			let currentPage = pages[pages.length - 1];
+			// 打印出当前页面中的 options
+			var options = currentPage.options
+			console.log(currentPage, 'currentPage.options')
+			if (options.styleNum && options.version) {
+				uni.setStorageSync('options', options)
+			} else {
+				options = uni.getStorageSync('options')
+			}
+			if (!getToken()) {
+				uni.navigateTo({
+					url: '/pages/login'
+				})
+				// this.$tab.reLaunch('/pages/login')
+			}
+			if (options.data) {
+				const id = options.data
+				this.getData(id)
+			} else if (options.styleNum) {
+				this.getData2(options)
+			}
+		},
+		methods: {
+			onBackward() {
+				wx.switchTab({
+					url: './index'
+				})
+			},
+			ViewImage(idx) {
+				const pics = [this.data.foto, this.data.pice]
+				uni.previewImage({
+					urls: pics,
+					current: idx
+				})
+			},
+			getData(id) {
+				uni.showLoading({
+					title: '加载中'
+				})
+				this.getDataApi(id).then(res => {
+					uni.hideLoading()
+					console.log(res)
+					if (res.code === 200) {
+						this.pics = [res.data.foto, res.data.pice]
+						this.data = res.data
+					}
+				}).catch(err => {
+					uni.hideLoading()
+				})
+			},
+			getData2(item) {
+				uni.showLoading({
+					title: '加载中'
+				})
+				listShoeStyle(item).then(res => {
+					uni.setStorageSync('options', '')
+					if (res.rows && res.rows.length > 0) {
+						this.pics = [];
+						if (res.rows[0].foto) {
+							this.pics.push(res.rows[0].foto)
+						};
+						if (res.rows[0].pice) {
+							this.pics.push(res.rows[0].pice)
+						};
+						this.data = res.rows[0]
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: '没有当前信息'
+						})
+					}
+					uni.hideLoading()
+				}).catch(err => {
+					uni.hideLoading()
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.img {
+		width: 100%;
+		height: 100%;
+		margin-right: 10px;
+	}
+
+
+	.f-text {
+		line-height: 38px;
+	}
+
+	.ivu-form-item {
+		margin-bottom: 1px;
+	}
+
+	.fob {
+				background: #faf78ce8 !important;
+	}
+	.outPrice{
+		background: #fdddc6e8 !important;
+	}
+</style>

+ 216 - 0
pages/trade/shoe-style/index.vue

@@ -0,0 +1,216 @@
+<template>
+	<view>
+		<view class="top-button">
+			<page-head :showQutation="showQutation" ref="pageHead" @headGetData="headGetData"></page-head>
+		</view>
+		<view class="bg-white" :style="{'paddingTop':$refs.pageHead&&$refs.pageHead.searchShow ? '170px' : '50px'}"
+			style="padding-bottom: 40px;">
+			<uni-list v-for="(item,index) in tableData" :key="index">
+				<uni-list-item showArrow link @click="rowClick(item)"
+					:to="isQuotation ? '' : './ShoeStyleView?' + 'styleNum=' + item.styleNum + '&' + 'version=' + item.version">
+					<!-- :to="isQuotation ? '' : './ShoeStyleView?data='+ encodeURIComponent()" -->
+					<template v-slot:header>
+						<view class="slot-box">
+							<view style="display: block;width: 135px;">
+								<view v-if="isQuotation" style="float: left;margin-top: -5px;width: 23px;">
+									<uni-data-checkbox multiple v-model="item.quotation" :localdata="[{text: '',value: 0}]" />
+								</view>
+								<image class="slot-image img" :src="item.foto" mode="widthFix"></image>
+							</view>
+						</view>
+					</template>
+					<template v-slot:body>
+						<text class="slot-box slot-text">
+							<text style="display: block;">{{item.styleNum}} {{item.color}} {{item.version}}</text>
+							<text style="display: block;font-size: 12px;color: #909399;">
+								面料:{{item.upper? item.upper: ''}}</text>
+							<text style="display: block;font-size: 12px;color: #909399;">
+								大底:{{item.outsole? item.outsole: ''}}</text>
+						</text>
+					</template>
+				</uni-list-item>
+			</uni-list>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		listShoeStyle,
+		getSign,
+		SHOE_STYLE_QUERY
+	} from '@/api/trade/shoe-style.js'
+	export default {
+		name: 'Index',
+		props: {
+			showQutation: {
+				type: Boolean,
+				default: true
+			},
+		},
+		data() {
+			return {
+				getDataApi: listShoeStyle,
+				getSign: getSign,
+				tableData: [],
+				// 数据总量
+				total: 0,
+				totalPages: null,
+				loading: false,
+				queryfrom: Object.assign({}, SHOE_STYLE_QUERY, {
+					// 每页数据量
+					pageSize: 15,
+					// 当前页
+					pageNum: 1
+				}),
+				procOption: [],
+				picker: [],
+				// -报价
+				isQuotation: false, // 是否勾选,开始报价
+				selects: [], // 选中行
+			}
+		},
+		onLoad() {
+			// this.getConfig()
+			this.picker = this.$store.state.user.factoryOption
+			this.procOption = this.$store.state.user.procOption
+			console.log(this.procOption)
+			this.selectedIndexs = []
+			this.getData()
+		},
+		onReachBottom() {
+			this.bottomload()
+		},
+		methods: {
+			//判断还有无,下一页数据
+			//判断当前的页码是否大于等于  总页数
+			bottomload() {
+				if (this.queryfrom.pageNum >= this.totalPages) {
+					//没有下一页数据
+					uni.showToast({ title: '没有下一页数据', })
+				} else {
+					//还有下一页
+					this.queryfrom.pageNum++
+					this.getData()
+				}
+			},
+			rowClick(row, index) {
+				if (this.isQuotation) {
+					if (row.quotation.length == 0) {
+						row.quotation = [0]
+						this.selects.push(row)
+					} else {
+						row.quotation = []
+						this.selects = this.selects.filter(it => it.id != row.id)
+					}
+					this.$emit('selects', this.selects)
+				};
+			},
+			// 分页触发
+			change(e) {
+				// this.$refs.table.clearSelection()
+				this.selectedIndexs.length = 0
+				this.getData(e.current)
+			},
+			headGetData(val) {
+				console.log('headGetData')
+				this.queryfrom = Object.assign(this.queryfrom, val)
+				this.tableData = []
+				this.getData(1)
+			},
+			// 获取数据
+			getData(pageCurrent, value = '') {
+				this.loading = true
+				this.pageCurrent = pageCurrent ? pageCurrent : this.queryfrom.pageNum
+				this.queryfrom.pageNum = this.pageCurrent
+				uni.showLoading({ title: '加载中' })
+				this.getDataApi(this.queryfrom).then(res => {
+					uni.hideLoading()
+					this.loading = false
+					if (res.code === 200 && res.rows && res.rows.length > 0) {
+						res.rows = res.rows.map(item => {
+							let obj = this.selects.find(it => it.id == item.id)
+							if (obj) {
+								item.quotation = [0]
+							} else {
+								item.quotation = []
+							}
+							item.styleId = item.id
+							return item
+						})
+						const total = res.total
+						//计算总页数----总共几页 = Math.ceil( 总条数 / 一页条数)
+						this.totalPages = Math.ceil(total / this.queryfrom.pageSize)
+						this.tableData = [...this.tableData, ...res.rows]
+					}
+				}).catch(err => {
+					uni.hideLoading()
+					this.loading = false
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	/* 	.import-btn {
+		padding: 0px;
+		width: 100%;
+		height: 36px;
+		text-align: center;
+		line-height: 36px;
+		background-color: #409EFF;
+		color: aliceblue;
+	} */
+
+	.chat-custom-right {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: space-between;
+		align-items: flex-end;
+	}
+
+	.chat-custom-text {
+		font-size: 12px;
+		color: #999;
+	}
+
+	.img {
+		width: 100px;
+		height: 100%;
+		margin-right: 10px;
+	}
+
+	.container {
+		width: 100%;
+		min-height: 100vh;
+		display: flex;
+		flex-direction: column;
+
+	}
+
+	/* 	.down-button {
+		z-index: 10;
+		position: fixed;
+		padding: 5px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #fff;
+	} */
+
+	.top-button {
+		z-index: 10;
+		position: fixed;
+		/* padding: 5px; */
+		top: 0px;
+		width: 100%;
+		height: 50px;
+		background-color: #fff;
+		padding: 5px;
+		border-bottom: 1px #ddd solid;
+	}
+</style>

+ 183 - 0
pages/work/index.vue

@@ -0,0 +1,183 @@
+<template>
+  <view class="work-container">
+    <!-- 轮播图 -->
+    <uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
+      <swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
+        <swiper-item v-for="(item, index) in data" :key="index">
+          <view class="swiper-item" @click="clickBannerItem(item)">
+            <image :src="item.image" mode="aspectFill" :draggable="false" />
+          </view>
+        </swiper-item>
+      </swiper>
+    </uni-swiper-dot>
+
+    <!-- 宫格组件 -->
+    <uni-section title="系统管理" type="line"></uni-section>
+    <view class="grid-body">
+      <uni-grid :column="4" :showBorder="false" @change="changeGrid">
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="person-filled" size="30"></uni-icons>
+            <text class="text">用户管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="staff-filled" size="30"></uni-icons>
+            <text class="text">角色管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="color" size="30"></uni-icons>
+            <text class="text">菜单管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="settings-filled" size="30"></uni-icons>
+            <text class="text">部门管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="heart-filled" size="30"></uni-icons>
+            <text class="text">岗位管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="bars" size="30"></uni-icons>
+            <text class="text">字典管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="gear-filled" size="30"></uni-icons>
+            <text class="text">参数设置</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="chat-filled" size="30"></uni-icons>
+            <text class="text">通知公告</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item>
+          <view class="grid-item-box">
+            <uni-icons type="wallet-filled" size="30"></uni-icons>
+            <text class="text">日志管理</text>
+          </view>
+        </uni-grid-item>
+      </uni-grid>
+    </view>
+  </view>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        current: 0,
+        swiperDotIndex: 0,
+        data: [{
+            image: '/static/images/banner/banner01.jpg'
+          },
+          {
+            image: '/static/images/banner/banner02.jpg'
+          },
+          {
+            image: '/static/images/banner/banner03.jpg'
+          }
+        ]
+      }
+    },
+    methods: {
+      clickBannerItem(item) {
+        console.info(item)
+      },
+      changeSwiper(e) {
+        this.current = e.detail.current
+      },
+      changeGrid(e) {
+        this.$modal.showToast('模块建设中~')
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  /* #ifndef APP-NVUE */
+  page {
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    background-color: #fff;
+    min-height: 100%;
+    height: auto;
+  }
+
+  view {
+    font-size: 14px;
+    line-height: inherit;
+  }
+
+  /* #endif */
+
+  .text {
+    text-align: center;
+    font-size: 26rpx;
+    margin-top: 10rpx;
+  }
+
+  .grid-item-box {
+    flex: 1;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 15px 0;
+  }
+
+  .uni-margin-wrap {
+    width: 690rpx;
+    width: 100%;
+    ;
+  }
+
+  .swiper {
+    height: 300rpx;
+  }
+
+  .swiper-box {
+    height: 150px;
+  }
+
+  .swiper-item {
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    height: 300rpx;
+    line-height: 300rpx;
+  }
+
+  @media screen and (min-width: 500px) {
+    .uni-swiper-dot-box {
+      width: 400px;
+      /* #ifndef APP-NVUE */
+      margin: 0 auto;
+      /* #endif */
+      margin-top: 8px;
+    }
+
+    .image {
+      width: 100%;
+    }
+  }
+</style>

+ 49 - 0
permission - 副本.js

@@ -0,0 +1,49 @@
+import { getToken,isLoginSso,removeToken,getSsoAdminToken } from '@/utils/auth'
+
+// 登录页面
+const loginPage = "/pages/login"
+  
+// 页面白名单
+const whiteList = [
+  '/pages/login', '/pages/register', '/pages/common/webview/index', '/pages/loginSso',
+]
+
+// 检查地址白名单
+function checkWhite(url) {
+  const path = url.split('?')[0]
+  return whiteList.indexOf(path) !== -1
+}
+// 页面跳转验证拦截器
+let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
+list.forEach(item => {
+  uni.addInterceptor(item, {
+    invoke(to) {
+		console.log(isLoginSso,'isLoginSso')
+		  // 启用单点登录后没有ssoToken清除当前token
+      if (!getSsoAdminToken() && isLoginSso) {
+        removeToken()
+      };
+      if (getToken()) {
+        if (to.url === loginPage) {
+          uni.reLaunch({ url: "/" })
+        }
+        return true
+      } else if(isLoginSso){
+		  console.log(777)
+		  uni.reLaunch({  url: '/pages/loginSso'})
+		   return false
+	  }else {
+        if (checkWhite(to.url)) {
+			console.log(6666)
+          return true
+        }
+		console.log(8888)
+        uni.reLaunch({ url: loginPage })
+        return false
+      }
+    },
+    fail(err) {
+      console.log(err)
+    }
+  })
+})

+ 48 - 0
permission.js

@@ -0,0 +1,48 @@
+import { getToken,isLoginSso,removeToken,getSsoAdminToken } from '@/utils/auth'
+// 登录页面
+let loginPage = "/pages/login"
+// 页面白名单
+let whiteList = [
+  '/pages/login', '/pages/register', '/pages/common/webview/index','/pages/loginSso'
+]
+if(isLoginSso){
+	loginPage= "/pages/loginSso"
+}
+// 检查地址白名单
+function checkWhite(url) {
+  const path = url.split('?')[0]
+  return whiteList.indexOf(path) !== -1
+}
+// 页面跳转验证拦截器
+let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
+list.forEach(item => {
+  uni.addInterceptor(item, {
+    invoke(to) {
+		console.log(isLoginSso,to.url,'isLoginSso')
+				  // 启用单点登录后没有ssoToken清除当前token
+		if (!getSsoAdminToken() && isLoginSso) {
+		  removeToken()
+		};
+      if (getToken()) {
+        if (to.url === loginPage) {
+          uni.reLaunch({ url: "/" })
+        }
+        return true
+      } else {
+		  if(to.url=='/pages/login' &&isLoginSso){
+		  	 uni.reLaunch({ url: "/pages/loginSso" })
+		  	 return false
+		  }
+        if (checkWhite(to.url)) {
+          return true
+        }
+		
+        uni.reLaunch({ url: loginPage })
+        return false
+      }
+    },
+    fail(err) {
+      console.log(err)
+    }
+  })
+})

+ 60 - 0
plugins/auth.js

@@ -0,0 +1,60 @@
+import store from '@/store'
+
+function authPermission(permission) {
+  const all_permission = "*:*:*"
+  const permissions = store.getters && store.getters.permissions
+  if (permission && permission.length > 0) {
+    return permissions.some(v => {
+      return all_permission === v || v === permission
+    })
+  } else {
+    return false
+  }
+}
+
+function authRole(role) {
+  const super_admin = "admin"
+  const roles = store.getters && store.getters.roles
+  if (role && role.length > 0) {
+    return roles.some(v => {
+      return super_admin === v || v === role
+    })
+  } else {
+    return false
+  }
+}
+
+export default {
+  // 验证用户是否具备某权限
+  hasPermi(permission) {
+    return authPermission(permission)
+  },
+  // 验证用户是否含有指定权限,只需包含其中一个
+  hasPermiOr(permissions) {
+    return permissions.some(item => {
+      return authPermission(item)
+    })
+  },
+  // 验证用户是否含有指定权限,必须全部拥有
+  hasPermiAnd(permissions) {
+    return permissions.every(item => {
+      return authPermission(item)
+    })
+  },
+  // 验证用户是否具备某角色
+  hasRole(role) {
+    return authRole(role)
+  },
+  // 验证用户是否含有指定角色,只需包含其中一个
+  hasRoleOr(roles) {
+    return roles.some(item => {
+      return authRole(item)
+    })
+  },
+  // 验证用户是否含有指定角色,必须全部拥有
+  hasRoleAnd(roles) {
+    return roles.every(item => {
+      return authRole(item)
+    })
+  }
+}

+ 14 - 0
plugins/index.js

@@ -0,0 +1,14 @@
+import tab from './tab'
+import auth from './auth'
+import modal from './modal'
+
+export default {
+  install(Vue) {
+    // 页签操作
+    Vue.prototype.$tab = tab
+    // 认证对象
+    Vue.prototype.$auth = auth
+    // 模态框对象
+    Vue.prototype.$modal = modal
+  }
+}

+ 75 - 0
plugins/modal.js

@@ -0,0 +1,75 @@
+export default {
+  // 消息提示
+  msg(content) {
+    uni.showToast({
+      title: content,
+      icon: 'none'
+    })
+  },
+  // 错误消息
+  msgError(content) {
+    uni.showToast({
+      title: content,
+      icon: 'error'
+    })
+  },
+  // 成功消息
+  msgSuccess(content) {
+    uni.showToast({
+      title: content,
+      icon: 'success'
+    })
+  },
+  // 隐藏消息
+  hideMsg(content) {
+    uni.hideToast()
+  },
+  // 弹出提示
+  alert(content, title) {
+    uni.showModal({
+      title: title || '系统提示',
+      content: content,
+      showCancel: false
+    })
+  },
+  // 确认窗体
+  confirm(content, title,showCancel) {
+    return new Promise((resolve, reject) => {
+      uni.showModal({
+        title: title || '系统提示',
+        content: content,
+        cancelText: '取消',
+        confirmText: '确定',
+		showCancel:showCancel==false?false:true,
+        success: function(res) {
+          if (res.confirm) {
+            resolve(res.confirm)
+          }
+        }
+      })
+    })
+  },
+  // 提示信息
+  showToast(option) {
+    if (typeof option === "object") {
+      uni.showToast(option)
+    } else {
+      uni.showToast({
+        title: option,
+        icon: "none",
+        duration: 2500
+      })
+    }
+  },
+  // 打开遮罩层
+  loading(content) {
+    uni.showLoading({
+      title: content,
+      icon: 'none'
+    })
+  },
+  // 关闭遮罩层
+  closeLoading() {
+    uni.hideLoading()
+  }
+}

+ 30 - 0
plugins/tab.js

@@ -0,0 +1,30 @@
+export default {
+  // 关闭所有页面,打开到应用内的某个页面
+  reLaunch(url) {
+    return uni.reLaunch({
+      url: url
+    })
+  },
+  // 跳转到tabBar页面,并关闭其他所有非tabBar页面
+  switchTab(url) {
+    return uni.switchTab({
+      url: url
+    })
+  },
+  // 关闭当前页面,跳转到应用内的某个页面
+  redirectTo(url) {
+    return uni.redirectTo({
+      url: url
+    })
+  },
+  // 保留当前页面,跳转到应用内的某个页面
+  navigateTo(url) {
+    return uni.navigateTo({
+      url: url
+    })
+  },
+  // 关闭当前页面,返回上一页面或多级页面
+  navigateBack() {
+    return uni.navigateBack()
+  }
+}

BIN
static/favicon.ico


+ 90 - 0
static/font/iconfont.css

@@ -0,0 +1,90 @@
+@font-face {
+  font-family: "iconfont";
+  src: url('@/static/font/iconfont.ttf') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  display: inline-block;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-user:before {
+  content: "\e7ae";
+}
+
+.icon-password:before {
+  content: "\e8b2";
+}
+
+.icon-code:before {
+  content: "\e699";
+}
+
+.icon-setting:before {
+  content: "\e6cc";
+}
+
+.icon-share:before {
+  content: "\e739";
+}
+
+.icon-edit:before {
+  content: "\e60c";
+}
+
+.icon-version:before {
+  content: "\e63f";
+}
+
+.icon-service:before {
+  content: "\e6ff";
+}
+
+.icon-friendfill:before {
+  content: "\e726";
+}
+
+.icon-community:before {
+  content: "\e741";
+}
+
+.icon-people:before {
+  content: "\e736";
+}
+
+.icon-dianzan:before {
+  content: "\ec7f";
+}
+
+.icon-right:before {
+  content: "\e7eb";
+}
+
+.icon-logout:before {
+  content: "\e61d";
+}
+
+.icon-help:before {
+  content: "\e616";
+}
+
+.icon-github:before {
+  content: "\e628";
+}
+
+.icon-aixin:before {
+  content: "\e601";
+}
+
+.icon-clean:before {
+  content: "\e607";
+}
+
+.icon-refresh:before {
+  content: "\e604";
+}
+

BIN
static/font/iconfont.ttf


BIN
static/images/banner/banner01.jpg


BIN
static/images/banner/banner02.jpg


BIN
static/images/banner/banner03.jpg


BIN
static/images/profile.jpg


BIN
static/images/sgin.png


BIN
static/images/star-active.png


BIN
static/images/star.png


BIN
static/images/tabbar/home.png


BIN
static/images/tabbar/home_.png


BIN
static/images/tabbar/mine.png


BIN
static/images/tabbar/mine_.png


BIN
static/images/tabbar/work.png


BIN
static/images/tabbar/work_.png


+ 20 - 0
static/index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+	<head>
+		<meta charset="utf-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+		  <meta name="renderer" content="webkit">
+		<title><%= htmlWebpackPlugin.options.title %></title>
+    <link rel="shortcut icon" type="image/x-icon" href="<%= BASE_URL %>static/favicon.ico">
+		<script>
+			var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
+			document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+		</script>
+		<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
+	</head>
+	<body>
+		<noscript>
+			<strong>本站点必须要开启JavaScript才能运行.</strong>
+		</noscript>
+		<div id="app"></div>
+</html>

BIN
static/logo.png


BIN
static/logo200.png


File diff suppressed because it is too large
+ 3956 - 0
static/scss/colorui.css


+ 99 - 0
static/scss/global.scss

@@ -0,0 +1,99 @@
+.text-center {
+	text-align: center;
+}
+.pb-10{
+	padding-bottom: 20rpx;
+}
+.font-13 {
+	font-size: 13px;
+}
+
+.font-12 {
+	font-size: 12px;
+}
+
+.font-11 {
+	font-size: 11px;
+}
+
+.text-grey1 {
+	color: #888;
+}
+.text-grey2 {
+	color: #aaa;
+}
+
+.list-cell-arrow::before {
+    content: ' ';
+    height: 10px;
+    width: 10px;
+    border-width: 2px 2px 0 0;
+    border-color: #c0c0c0;
+    border-style: solid;
+    -webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
+    transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
+    position: absolute;
+    top: 50%;
+    margin-top: -6px;
+    right: 30rpx;
+  }
+  
+  .list-cell {
+    position: relative;
+    width: 100%;
+    box-sizing: border-box;
+    background-color: #fff;
+    color: #333;
+    padding: 26rpx 30rpx;
+  }
+  
+  .list-cell:first-child {
+    border-radius: 8rpx 8rpx 0 0;
+  }
+  
+  .list-cell:last-child {
+    border-radius: 0 0 8rpx 8rpx;
+  }
+  
+  .list-cell::after {
+    content: '';
+    position: absolute;
+    border-bottom: 1px solid #eaeef1;
+    -webkit-transform: scaleY(0.5) translateZ(0);
+    transform: scaleY(0.5) translateZ(0);
+    transform-origin: 0 100%;
+    bottom: 0;
+    right: 0;
+    left: 0;
+    pointer-events: none;
+  }
+  .red{
+	  color: red;
+  }
+  .mr-2{
+	  margin-right: 2px;
+  }
+  .menu-list {
+    margin: 15px 15px;
+  
+    .menu-item-box {
+      width: 100%;
+      display: flex;
+      align-items: center;
+  
+      .menu-icon {
+        color: #007AFF;
+        font-size: 16px;
+        margin-right: 5px;
+      }
+      
+      .text-right {
+        margin-left: auto;
+        margin-right: 34rpx;
+        color: #999;
+      }
+    }
+  }
+.pb-0{
+	padding-bottom: 0;
+}

+ 11 - 0
static/scss/index.scss

@@ -0,0 +1,11 @@
+// global
+/* #ifdef H5 */
+	uni-page-head {
+		display: none;
+	}
+/* #endif */
+@import "./global.scss";
+// color-ui
+@import "@/static/scss/colorui.css";
+// iconfont
+@import "@/static/font/iconfont.css";

+ 8 - 0
store/getters.js

@@ -0,0 +1,8 @@
+const getters = {
+  token: state => state.user.token,
+  avatar: state => state.user.avatar,
+  name: state => state.user.name,
+  roles: state => state.user.roles,
+  permissions: state => state.user.permissions
+}
+export default getters

+ 15 - 0
store/index.js

@@ -0,0 +1,15 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import user from '@/store/modules/user'
+import getters from './getters'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+  modules: {
+    user
+  },
+  getters
+})
+
+export default store

+ 98 - 0
store/modules/user.js

@@ -0,0 +1,98 @@
+import config from '@/config'
+import storage from '@/utils/storage'
+import constant from '@/utils/constant'
+import { login, logout, getInfo } from '@/api/login'
+import { getToken, setToken, removeToken } from '@/utils/auth'
+
+const baseUrl = config.baseUrl
+
+const user = {
+  state: {
+    token: getToken(),
+    name: storage.get(constant.name),
+    avatar: storage.get(constant.avatar),
+    roles: storage.get(constant.roles),
+    permissions: storage.get(constant.permissions)
+  },
+
+  mutations: {
+    SET_TOKEN: (state, token) => {
+      state.token = token
+    },
+    SET_NAME: (state, name) => {
+      state.name = name
+      storage.set(constant.name, name)
+    },
+    SET_AVATAR: (state, avatar) => {
+      state.avatar = avatar
+      storage.set(constant.avatar, avatar)
+    },
+    SET_ROLES: (state, roles) => {
+      state.roles = roles
+      storage.set(constant.roles, roles)
+    },
+    SET_PERMISSIONS: (state, permissions) => {
+      state.permissions = permissions
+      storage.set(constant.permissions, permissions)
+    }
+  },
+
+  actions: {
+    // 登录
+    Login({ commit }, userInfo) {
+      const username = userInfo.username.trim()
+      const password = userInfo.password
+      const code = userInfo.code
+      const uuid = userInfo.uuid
+      return new Promise((resolve, reject) => {
+        login(username, password, code, uuid).then(res => {
+          setToken(res.token)
+          commit('SET_TOKEN', res.token)
+          resolve()
+        }).catch(error => {
+          reject(error)
+        })
+      })
+    },
+
+    // 获取用户信息
+    GetInfo({ commit, state }) {
+      return new Promise((resolve, reject) => {
+        getInfo().then(res => {
+          const user = res.user
+          const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : baseUrl + user.avatar
+          const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
+          if (res.roles && res.roles.length > 0) {
+            commit('SET_ROLES', res.roles)
+            commit('SET_PERMISSIONS', res.permissions)
+          } else {
+            commit('SET_ROLES', ['ROLE_DEFAULT'])
+          }
+          commit('SET_NAME', username)
+          commit('SET_AVATAR', avatar)
+          resolve(res)
+        }).catch(error => {
+          reject(error)
+        })
+      })
+    },
+
+    // 退出系统
+    LogOut({ commit, state }) {
+      return new Promise((resolve, reject) => {
+        logout(state.token).then(() => {
+          commit('SET_TOKEN', '')
+          commit('SET_ROLES', [])
+          commit('SET_PERMISSIONS', [])
+          removeToken()
+          storage.clean()
+          resolve()
+        }).catch(error => {
+          reject(error)
+        })
+      })
+    }
+  }
+}
+
+export default user

+ 64 - 0
uni.scss

@@ -0,0 +1,64 @@
+/**
+ * uni-app内置的常用样式变量
+ */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#e5e5e5;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;

+ 111 - 0
utils/auth.js

@@ -0,0 +1,111 @@
+
+import request from '@/utils/request';
+import config from '@/config'
+const TokenKey = 'App-Token'
+export const isLoginSso = config.VITE_SSO_LOGIN 
+
+export function getToken() {
+  return uni.getStorageSync(TokenKey)
+}
+
+export function setToken(token) {
+  return uni.setStorageSync(TokenKey, token)
+}
+
+export function removeToken() {
+  return uni.removeStorageSync(TokenKey)
+}
+const SYS_CODE = 'XXLSSO';
+// 单点登录Token
+const SsoTokenKey = 'Sso-Admin-Token';
+// 获取单点登录Token
+export function getSsoAdminToken() {
+    return uni.getStorageSync(SsoTokenKey);
+};
+// 设置单点登录Token
+export function setSsoAdminToken(token) {
+    return uni.setStorageSync(SsoTokenKey, token);
+};
+// 删除单点登录Token
+export function removeSsoAdminToken() {
+    return uni.removeStorageSync(SsoTokenKey);
+};
+
+// 当前环境
+// const VITE_APP_ENV = import.meta.env.VITE_APP_ENV;
+const VITE_APP_ENV = 'beta'
+function getEnv() {
+    // let jumpEnv = 'http://localhost:88';
+    // let curEnv = 'http://localhost:80/pages';
+    // let suffix = 'localhost';
+    // if (VITE_APP_ENV == 'production') {
+    //     // 生产环境
+      let  jumpEnv = 'https://sso.huaxiazhizao.com';
+      let  curEnv = 'https://tools-m.huaxiazhizao.com/pages';
+      let  suffix = '.huaxiazhizao.com';
+    // } else if (VITE_APP_ENV == 'beta') {
+    //     // 测试环境
+    //     jumpEnv = 'https://sso.huabaosmart.cn';
+    //     curEnv = 'https://sundry.huabaosmart.cn';
+    //     suffix = '.huabaosmart.cn';
+    // };
+    return { jumpEnv, curEnv, suffix };
+};
+/**
+ * 获取当前用户 Token
+ * @param {*} SSO_CODE 
+ * @param {*} noMessage 
+ * @returns 
+ */
+export function getOpenToken() {
+    return request({
+        url: '/open/ex_login',
+        method: 'get',
+        params: { sysCode: SYS_CODE, token: getSsoAdminToken() },
+        noMessage: false
+    });
+};
+export function ssoLogout() {
+    document.cookie = "ssoLogout=true;path=/;domain=" + getEnv().suffix;
+};
+// 打开单点登录页面
+export function openWindowSso() {
+    // 清除单点登录Token
+    removeSsoAdminToken();
+    // 清除Token
+    removeToken();
+    // 登录失效跳转到单点登录页面
+    window.open(getEnv().jumpEnv, '_self');
+};
+
+// 系统退出
+export function toolsLogout() {
+    Cookies.set('tools-logout', true);
+};
+
+// 设置跳转 url
+export function setEnv() {
+    document.cookie = "ssoLogin=" + getEnv().curEnv + ";path=/;domain=" + getEnv().suffix;
+};
+
+// 删除定点跳转cookie
+export function removeEnv() {
+    var date = new Date();
+    date.setTime(date.getTime() - 500000);
+    document.cookie = "ssoLogin=' ';expires=" + date.toUTCString() + "path=/;domain=" + getEnv().suffix;
+};
+
+// 请求头
+// let search = window.location.search;
+// if (search && search.length > 1) {
+//   let arr = search.split('=')
+//   if (arr[0] === '?token') {
+//     let token = arr[1];
+//     Cookies.set('TokenKey', token);
+//     // setToken(token)    // 将token值按照子系统的方式保存下来,cookie或者localStorage均可
+//     window.location.href = window.location.origin
+//   }
+// }
+
+
+

+ 55 - 0
utils/common.js

@@ -0,0 +1,55 @@
+/**
+* 显示消息提示框
+* @param content 提示的标题
+*/
+export function toast(content) {
+  uni.showToast({
+    icon: 'none',
+    title: content
+  })
+}
+
+/**
+* 显示模态弹窗
+* @param content 提示的标题
+*/
+export function showConfirm(content,showCancel) {
+  return new Promise((resolve, reject) => {
+    uni.showModal({
+      title: '提示',
+      content: content,
+      cancelText: '取消',
+      confirmText: '确定',
+	  showCancel:true||showCancel,
+      success: function(res) {
+        resolve(res)
+      }
+    })
+  })
+}
+
+/**
+* 参数处理
+* @param params 参数
+*/
+export function tansParams(params) {
+  let result = ''
+  for (const propName of Object.keys(params)) {
+    const value = params[propName]
+    var part = encodeURIComponent(propName) + "="
+    if (value !== null && value !== "" && typeof (value) !== "undefined") {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+            let params = propName + '[' + key + ']'
+            var subPart = encodeURIComponent(params) + "="
+            result += subPart + encodeURIComponent(value[key]) + "&"
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + "&"
+      }
+    }
+  }
+  return result
+}

+ 8 - 0
utils/constant.js

@@ -0,0 +1,8 @@
+const constant = {
+   avatar: 'vuex_avatar',
+   name: 'vuex_name',
+   roles: 'vuex_roles',
+   permissions: 'vuex_permissions'
+ }
+
+ export default constant

+ 119 - 0
utils/date.js

@@ -0,0 +1,119 @@
+/**
+ * 日期时间格式化
+ * @param {date} time 需要转换的时间
+ * @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
+ */
+export function formatTime(time, fmt) {
+    if (!time) return ''
+    else {
+			// time=time.replace(/\-/g,'\/')
+        const date = typeof (time) === 'object' ? ('format' in time ? time.toDate() : time) : new Date(time)
+        if (date.getFullYear() == 1753 && date.getMonth() + 1 == 1 && date.getDate() == 1) {
+            return ''
+        }
+        const o = {
+            'M+': date.getMonth() + 1,
+            'd+': date.getDate(),
+            'H+': date.getHours(),
+            'm+': date.getMinutes(),
+            's+': date.getSeconds(),
+            'q+': Math.floor((date.getMonth() + 3) / 3),
+            S: date.getMilliseconds(),
+        }
+        if (/(y+)/.test(fmt))
+            fmt = fmt.replace(
+                RegExp.$1,
+                (date.getFullYear() + '').substr(4 - RegExp.$1.length)
+            )
+        for (const k in o) {
+            if (new RegExp('(' + k + ')').test(fmt)) {
+                fmt = fmt.replace(
+                    RegExp.$1,
+                    RegExp.$1.length === 1 ?
+                        o[k] :
+                        ('00' + o[k]).substr(('' + o[k]).length)
+                )
+            }
+        }
+        return fmt
+    }
+}
+
+// 日期筛选器 05-28
+export function formatDayDate(time) {
+    return formatTime(time, 'yy-MM-dd')
+}
+
+// 日期筛选器 2020-05-28
+export function formatDate(time) {
+    return formatTime(time, 'yyyy-MM-dd')
+}
+
+// 日期时间筛选器 2020-05-28 20:30
+export function formatDateTime(time) {
+    return formatTime(time, 'yyyy-MM-dd HH:mm:ss')
+}
+
+// 日期时间筛选器 2020-05-28 20:30
+export function formatDateMinute(time) {
+    return formatTime(time, 'yyyy-MM-dd HH:mm')
+}
+
+/**
+ * 格式化毫秒时间
+ */
+export function formatMilliSeconds(time) {
+    let span = time / 1000.0
+    let seconds = parseInt(span % 60.0)
+    span = parseInt(span / 60.0)
+    let minutes = parseInt(span % 60.0)
+    span = parseInt(span / 60.0)
+    let hours = parseInt(span % 24.0)
+    let days = parseInt(span / 24.0)
+    let res = ''
+    if (days > 0)
+        res += days + '天'
+    if (hours > 0)
+        res += hours + '时'
+    if (minutes > 0)
+        res += minutes + '分'
+    if (seconds > 0)
+        res += seconds + '秒'
+    return res
+}
+
+export function getWeekDataList(data) {
+    //根据日期获取本周周一~周日的年-月-日
+    var weekList = []
+    var date = new Date(data)
+    //判断本日期是否为周日,获取本周一日期
+    if(date.getDay()=='0'){
+        date.setDate(date.getDate() -6)
+    }else {
+        date.setDate(date.getDate() - date.getDay() + 1)
+    }
+    var myDate=date.getDate()
+    var myMonth=date.getMonth() + 1
+    if(date.getDate()<10){
+        myDate= '0'+ myDate
+    }
+    if(date.getMonth() + 1<10){
+        myMonth='0'+myMonth
+    }
+    weekList.push(date.getFullYear() + '-' + myMonth+ '-' + myDate)
+    // 获取周二以后日期
+    for(var i=0;i<6;i++) {
+        date.setDate(date.getDate() + 1)
+        myDate=date.getDate()
+        myMonth=date.getMonth() + 1
+        if(date.getDate()<10){
+            myDate= '0'+ myDate
+        }
+        if(date.getMonth() + 1<10){
+            myMonth='0'+myMonth
+        }
+        weekList.push(date.getFullYear() + '-' + myMonth+ '-' +myDate)
+    }
+    console.log(weekList)
+    return weekList
+}

+ 6 - 0
utils/errorCode.js

@@ -0,0 +1,6 @@
+export default {
+  '401': '认证失败,无法访问系统资源',
+  '403': '当前操作没有权限',
+  '404': '访问资源不存在',
+  'default': '系统未知错误,请反馈给管理员'
+}

File diff suppressed because it is too large
+ 0 - 0
utils/jweixin.js


+ 51 - 0
utils/permission.js

@@ -0,0 +1,51 @@
+import store from '@/store'
+
+/**
+ * 字符权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkPermi(value) {
+  if (value && value instanceof Array && value.length > 0) {
+    const permissions = store.getters && store.getters.permissions
+    const permissionDatas = value
+    const all_permission = "*:*:*"
+
+    const hasPermission = permissions.some(permission => {
+      return all_permission === permission || permissionDatas.includes(permission)
+    })
+
+    if (!hasPermission) {
+      return false
+    }
+    return true
+  } else {
+    console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
+    return false
+  }
+}
+
+/**
+ * 角色权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkRole(value) {
+  if (value && value instanceof Array && value.length > 0) {
+    const roles = store.getters && store.getters.roles
+    const permissionRoles = value
+    const super_admin = "admin"
+
+    const hasRole = roles.some(role => {
+      return super_admin === role || permissionRoles.includes(role)
+    })
+
+    if (!hasRole) {
+      return false
+    }
+    return true
+  } else {
+    console.error(`need roles! Like checkRole="['admin','editor']"`)
+    return false
+  }
+}

+ 74 - 0
utils/request.js

@@ -0,0 +1,74 @@
+import store from '@/store'
+import config from '@/config'
+import { getToken } from '@/utils/auth'
+import errorCode from '@/utils/errorCode'
+import { toast, showConfirm, tansParams } from '@/utils/common'
+
+let timeout = 10000
+const baseUrl = config.baseUrl
+
+const request = config => {
+  // 是否需要设置 token
+  const isToken = (config.headers || {}).isToken === false
+  config.header = config.header || {}
+    console.log(getToken(),isToken,'9999')
+  if (getToken() && !isToken) {
+    config.header['Authorization'] = 'Bearer ' + getToken()
+  }
+  // get请求映射params参数
+  if (config.params) {
+    let url = config.url + '?' + tansParams(config.params)
+    url = url.slice(0, -1)
+    config.url = url
+  }
+  return new Promise((resolve, reject) => {
+    uni.request({
+        method: config.method || 'get',
+        timeout: config.timeout ||  timeout,
+        url: config.baseUrl || baseUrl + config.url,
+        data: config.data,
+        header: config.header,
+        dataType: 'json'
+      }).then(response => {
+        let [error, res] = response
+        if (error) {
+          toast('后端接口连接异常')
+          reject('后端接口连接异常')
+          return
+        }
+        const code = res.data.code || 200
+        const msg = errorCode[code] || res.data.msg || errorCode['default']
+        if (code === 401) {
+          showConfirm('登录状态已过期,请重新登录!').then(res => {
+            if (res.confirm) {
+              store.dispatch('LogOut').then(res => {
+                uni.reLaunch({ url: '/pages/login' })
+              })
+            }
+          })
+          reject('无效的会话,或者会话已过期,请重新登录。')
+        } else if (code === 500) {
+          toast(msg)
+          reject('500')
+        } else if (code !== 200) {
+          toast(msg)
+          reject(code)
+        }
+        resolve(res.data)
+      })
+      .catch(error => {
+        let { message } = error
+        if (message === 'Network Error') {
+          message = '后端接口连接异常'
+        } else if (message.includes('timeout')) {
+          message = '系统接口请求超时'
+        } else if (message.includes('Request failed with status code')) {
+          message = '系统接口' + message.substr(message.length - 3) + '异常'
+        }
+        toast(message)
+        reject(error)
+      })
+  })
+}
+
+export default request

+ 32 - 0
utils/storage.js

@@ -0,0 +1,32 @@
+import constant from './constant'
+
+// 存储变量名
+let storageKey = 'storage_data'
+
+// 存储节点变量名
+let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions]
+
+const storage = {
+  set: function(key, value) {
+    if (storageNodeKeys.indexOf(key) != -1) {
+      let tmp = uni.getStorageSync(storageKey)
+      tmp = tmp ? tmp : {}
+      tmp[key] = value
+      uni.setStorageSync(storageKey, tmp)
+    }
+  },
+  get: function(key) {
+    let storageData = uni.getStorageSync(storageKey) || {}
+    return storageData[key] || ""
+  },
+  remove: function(key) {
+    let storageData = uni.getStorageSync(storageKey) || {}
+    delete storageData[key]
+    uni.setStorageSync(storageKey, storageData)
+  },
+  clean: function() {
+    uni.removeStorageSync(storageKey)
+  }
+}
+
+export default storage

+ 70 - 0
utils/upload.js

@@ -0,0 +1,70 @@
+import store from '@/store'
+import config from '@/config'
+import { getToken } from '@/utils/auth'
+import errorCode from '@/utils/errorCode'
+import { toast, showConfirm, tansParams } from '@/utils/common'
+
+let timeout = 10000
+const baseUrl = config.baseUrl
+
+const upload = config => {
+  // 是否需要设置 token
+  const isToken = (config.headers || {}).isToken === false
+  config.header = config.header || {}
+  if (getToken() && !isToken) {
+    config.header['Authorization'] = 'Bearer ' + getToken()
+  }
+  // get请求映射params参数
+  if (config.params) {
+    let url = config.url + '?' + tansParams(config.params)
+    url = url.slice(0, -1)
+    config.url = url
+  }
+  return new Promise((resolve, reject) => {
+      uni.uploadFile({
+        timeout: config.timeout || timeout,
+        url: baseUrl + config.url,
+        filePath: config.filePath,
+        name: config.name || 'file',
+        header: config.header,
+        formData: config.formData,
+        success: (res) => {
+          let result = JSON.parse(res.data)
+          const code = result.code || 200
+          const msg = errorCode[code] || result.msg || errorCode['default']
+          if (code === 200) {
+            resolve(result)
+          } else if (code == 401) {
+            showConfirm("登录状态已过期,您可以继续留在该页面,或者重新登录?").then(res => {
+              if (res.confirm) {
+                store.dispatch('LogOut').then(res => {
+                  uni.reLaunch({ url: '/pages/login/login' })
+                })
+              }
+            })
+            reject('无效的会话,或者会话已过期,请重新登录。')
+          } else if (code === 500) {
+            toast(msg)
+            reject('500')
+          } else if (code !== 200) {
+            toast(msg)
+            reject(code)
+          }
+        },
+        fail: (error) => {
+          let { message } = error
+          if (message == 'Network Error') {
+            message = '后端接口连接异常'
+          } else if (message.includes('timeout')) {
+            message = '系统接口请求超时'
+          } else if (message.includes('Request failed with status code')) {
+            message = '系统接口' + message.substr(message.length - 3) + '异常'
+          }
+          toast(message)
+          reject(error)
+        }
+      })
+  })
+}
+
+export default upload

Some files were not shown because too many files changed in this diff