工作台

This commit is contained in:
唐明明
2022-12-26 09:31:55 +08:00
parent f7d357f738
commit 1f3f6b230a
218 changed files with 19796 additions and 0 deletions

2
.env Normal file
View File

@@ -0,0 +1,2 @@
HAST_URL = ''

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/unpackage
/node_modules

20
.hbuilderx/launch.json Normal file
View File

@@ -0,0 +1,20 @@
{
// launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version" : "0.0",
"configurations" : [
{
"app-plus" : {
"launchtype" : "local"
},
"default" : {
"launchtype" : "local"
},
"type" : "uniCloud"
},
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

13
App.vue Normal file
View File

@@ -0,0 +1,13 @@
<script></script>
<style lang="scss">
@import "uview-ui/index.scss";
@import "@/static/iconfont.css";
.content{
background: #f8f8f8;
min-height: 100vh;
padding: 0 0 1rpx;
box-sizing: border-box;
}
</style>

169
apis/index.js Normal file
View File

@@ -0,0 +1,169 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
*/
import store from '@/store'
import router from '../router'
// 基础配置
const config = {
apiUrl : 'http://douhuo.douhuofalv.com/api/',
timeout : 60000
}
let loginHintState = false
// 网络请求
const request = (parameter, hideLoding = true) => {
// 检查url配置
if(parameter.url === 'undefined' || parameter.url === ''){
uni.showToast({
title: '请求地址不能为空',
icon : 'none'
})
return
}
// 注入header
config.header = {
'Accept': 'application/json',
'Authorization': store.getters.getToken || uni.getStorageSync('token')
}
// 加载提示
if(!hideLoding) uni.showLoading({
title: '加载中',
mask : true
});
// 请求实例
return new Promise((resolve, reject) => {
uni.request({
url : config.apiUrl + parameter.url,
timeout : config.timeout,
header : config.header || {},
data : parameter.data || {},
method : parameter.method || 'GET',
success : res => {
if (res.header.Authorization){
updateToken('token', res.header.Authorization)
}
if(res.statusCode === 200){
uni.hideLoading()
const resolveData = res.data
if(resolveData.status_code === 200) {
resolve(resolveData.data)
return
}
if(resolveData.status_code === 401) {
loginHint()
return
}
reject(resolveData)
return
}
errToast(res.statusCode)
},
fail(err) {
uni.showToast({
title: '网络错误,请检查您设备网络状态',
icon : 'none'
})
}
})
})
}
// 文件上传
const uploading = (paths, formData, url) => {
uni.showLoading({
title: '上传中',
mask : true
});
// 注入header
config.header = {
'Accept': 'application/json',
'Authorization': store.getters.getToken || ''
}
// 上传图片
return new Promise((resolve, reject) => {
uni.uploadFile({
url : config.apiUrl + (url || 'storage/uploads'),
files : paths,
header : config.header || {},
formData: formData || {},
success : res=>{
if(res.statusCode === 200){
uni.hideLoading()
let updData = JSON.parse(res.data)
if(updData.status_code === 200){
resolve(updData.data)
return
}
reject(updData)
return
}
errToast(res.statusCode)
}
})
})
}
// 处理一些http请求错误提示
const errToast = (code) => {
switch (code){
case 404:
uni.showToast({
title: code + '接口不存在,请联系系统管理员',
icon : 'none'
})
break;
case 405:
uni.showToast({
title: code + '请检查接口请求方式错误',
icon : 'none'
})
break;
case 500:
uni.showToast({
title: code + '服务端错误,请检查服务器信息',
icon : 'none'
})
break;
}
}
// 更新token
const updateToken = (token) => {
store.commit('setToken', token)
// 清除退出登录标识
uni.removeStorageSync('isnew')
}
// 处理登录提示
const loginHint = () => {
if( loginHintState ) return
if(!loginHintState) loginHintState = true
updateToken('')
uni.showModal({
title: '登录提示',
content: '您的登录信息已过期,请重新登录',
confirmColor: '#8b64fd',
showCancel:false,
success: res=> {
loginHintState = false
if (res.confirm) {
uni.reLaunch({
url:'/pages/auth/auth'
})
}
}
})
}
export {
request,
uploading,
config
}

View File

@@ -0,0 +1,49 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 账户
*/
import { request } from '../index'
// 火力值账户
const score = (data) =>{
return request({
url : "user/account/score",
data
})
}
// 活力值变动
const log = data => {
return request({
url : "user/account/score",
data
})
}
// 业绩账户
const cash = data => {
return request({
url: "perf/lists",
data
})
}
// 奖金账户
const balance = data => {
return request({
url: "user/account/balance",
data
})
}
export {
score,
log,
cash,
balance
}

View File

@@ -0,0 +1,21 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 地址信息
*/
import { request } from '../index'
// 城市列表
const region = data => {
return request({
url : 'region/all',
data
})
}
export {
region
}

61
apis/interfaces/auth.js Normal file
View File

@@ -0,0 +1,61 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 鉴权
*/
import { request } from '../index'
// 用户名密码登录
const auth = (data) =>{
return request({
url : "user/auth/login",
method : "POST",
data
})
}
// 用户注册
const register = data => {
return request({
url : "user/auth/register",
method : "POST",
data
})
}
// 图形验证码
const captcha = () => {
return request({
url : "user/auth/captcha",
method : "POST"
})
}
// 获取短信验证码
const verifyCaptcha = data => {
return request({
url : "user/auth/verify_captcha",
method : "POST",
data
})
}
// 重置密码
const resetPassword = data => {
return request({
url : "user/auth/reset_password",
method : "POST",
data
})
}
export {
auth,
register,
captcha,
verifyCaptcha,
resetPassword
}

View File

@@ -0,0 +1,67 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 业务
*/
import { request } from '../index'
// 主业务类型
const business = () =>{
return request({
url: "business/index",
})
}
// 获取主业务机构
const institution = id =>{
return request({
url: "business/" + id + "/institution",
})
}
// 获取机构表单数据
const institutionType = id => {
return request({
url: "business/institution/" + id + "/type",
})
}
// 搜索办理业务用户
const availableUser = (type, value) => {
if(type === 'mobile'){
return request({
url : "user/relations/child_by_mobile",
data: {
mobile: value
}
})
}
if(type === 'name'){
return request({
url : "user/relations/child_by_name",
data: {
name: value
}
})
}
}
// 提交用户办理信息
const submitStore = data => {
return request({
url : "business/store",
method : "POST",
data
})
}
export {
business,
institution,
institutionType,
availableUser,
submitStore
}

View File

@@ -0,0 +1,47 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 商学院
*/
import { request } from '../index'
// 考试评测列表
const evaluations = () => {
return request({
url : "evaluations",
})
}
// 考试题列表
const questions = id => {
return request({
url : "evaluations/" + id + "/questions",
})
}
// 提交答案
const answers = (id, data) => {
return request({
url : "evaluations/" + id + "/answers",
method : "POST",
data
})
}
// 考试答案解析
const report = id => {
return request({
url : "evaluations/" + id + "/report"
})
}
export {
evaluations,
questions,
answers,
report
}

38
apis/interfaces/mailed.js Normal file
View File

@@ -0,0 +1,38 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 邮寄材料
*/
import { request } from '../index'
// 获取物流公司列表
const express = () => {
return request({
url : 'express',
})
}
// 获取订单邮寄地址
const orderAddress = id => {
return request({
url : 'business/' + id + '/address'
})
}
// 提交邮寄物品
const submitExpresses = (id, data) => {
return request({
url : 'business/' + id + '/expresses',
method : 'POST',
data
})
}
export {
express,
orderAddress,
submitExpresses
}

155
apis/interfaces/order.js Normal file
View File

@@ -0,0 +1,155 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 订单管理
*/
import { request } from '../index'
// 订单列表
const lists = data => {
return request({
url : 'app/orders',
data
})
}
// 配置服务包
const service = orderId => {
return request({
url : 'business/' + orderId + '/service',
method : 'POST'
})
}
// 添加服务包
const serviceAdd = (orderId, items) => {
return request({
url : 'business/' + orderId + '/service/calculate',
method : 'POST',
data : {
items
}
})
}
// 删除服务包
const serviceRemove = (id, data) => {
return request({
url : 'business/' + id + '/service/remove',
method : 'POST',
data
})
}
// 完成分配
const serviceOver = orderId => {
return request({
url : 'business/' + orderId + '/service/over',
method : 'POST',
})
}
// 订单详情
const info = orderId => {
return request({
url : 'app/orders/' + orderId
})
}
// 订单资料完善情况
const perfect = orderId => {
return request({
url : 'app/orders/' + orderId + '/data',
})
}
// 订单基础资料信息
const perfectBase = orderId => {
return request({
url : 'business/' + orderId + '/user/base'
})
}
// 提交基础资料信息
const updPerfectBase = (orderId, data) => {
return request({
url : 'business/' + orderId + '/user/base',
method : 'POST',
data
})
}
// 订单机构资料
const baseBase = baseId => {
return request({
url : 'business/' + baseId + '/user/bank'
})
}
// 更新机构资料
const updBaseBase = (baseId, data) => {
return request({
url : 'business/' + baseId + '/user/bank',
method : 'POST',
data
})
}
// 待补差价订单
const ordersDiffs = data => {
return request({
url : 'app/orders/diffs'
})
}
// 待修改订单
const ordersEditorders = data => {
return request({
url : 'app/orders/editorders'
})
}
// 个人订单签约
const orderSign = (id, data) => {
return request({
url : 'business/' + id + '/sign_url',
data
})
}
// 查询订单签约状态
const getOrderSignStatus = id => {
return request({
url: 'business/' + id + '/sign_status'
})
}
// 机构预估方案
const getSchemes = id => {
return request({
url: 'business/' + id + '/item_scheme'
})
}
// 支付订单
export {
lists,
service,
serviceAdd,
serviceRemove,
serviceOver,
info,
perfect,
perfectBase,
updPerfectBase,
baseBase,
updBaseBase,
ordersDiffs,
ordersEditorders,
orderSign,
getOrderSignStatus,
getSchemes
}

28
apis/interfaces/pay.js Normal file
View File

@@ -0,0 +1,28 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 收银台
*/
import { request } from '../index'
// 抖火币支付
const coinPay = orderId => {
return request({
url : 'pay/order/' + orderId + '/score',
})
}
// 抖火币补差价支付
const diffCoinPay = orderId => {
return request({
url : 'pay/diff/' + orderId + '/score'
})
}
export {
coinPay,
diffCoinPay
}

View File

@@ -0,0 +1,59 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 转让订单管理
*/
import { request } from '../index'
// 订单列表
const lists = data => {
return request({
url : 'app/transfers',
data
})
}
// 可转让对象
const levels = id => {
return request({
url: 'app/transfer/' + id + '/levels',
})
}
// 转让
const transfer = (id, level) => {
return request({
url : 'app/' + id + '/transfer',
data: {
level
},
method: 'POST'
})
}
// 接收订单
const transferAgree = id => {
return request({
url : 'app/' + id + '/agree',
method: 'POST'
})
}
// 拒绝接收
const transferRefuse = id => {
return request({
url : 'app/' + id + '/refuse',
method: 'POST'
})
}
export {
lists,
levels,
transfer,
transferAgree,
transferRefuse
}

View File

@@ -0,0 +1,17 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 上传图片
*/
import { uploading as upd } from '../index'
const uploads = (paths, fromData) => {
return upd(paths, fromData)
}
export {
uploads
}

84
apis/interfaces/user.js Normal file
View File

@@ -0,0 +1,84 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 用户
*/
import { request } from '../index'
// 我的下级用户
const relations = data => {
return request({
url : 'user/relations',
data
})
}
// 我的邀请码
const code = () => {
return request({
url : 'user/invite',
})
}
// 用户信息
const info = () => {
return request({
url : 'app/user/info'
})
}
// 更新用户资料
const updInfo = (key, value) => {
return request({
url : 'user/setting/' + key,
method : 'PUT',
data : {
value
}
})
}
// 用户认证状态
const certified = () => {
return request({
url : 'user/certified'
})
}
// 用户认证
const certification = data => {
return request({
url : 'user/certification',
method : 'POST',
data
})
}
// 获取身份证认证信息
const identityOcr = () => {
return request({
url : 'user/certification'
})
}
// 获取签名地址
const eSigns = data => {
return request({
url : 'e-signs/authorize/psn',
data
})
}
export {
relations,
code,
info,
updInfo,
certified,
certification,
identityOcr,
eSigns
}

28
apis/interfaces/work.js Normal file
View File

@@ -0,0 +1,28 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
* moduleName: 工作台
*/
import { request } from '../index'
// 工作台首页
const index = () => {
return request({
url : 'app/user',
})
}
// 会员权益
const rights = () => {
return request({
url : 'app/rights'
})
}
export {
index,
rights
}

View File

@@ -0,0 +1,20 @@
<template>
<view>
选择组件
</view>
</template>
<script>
export default {
name:"octcheckbox",
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

32
components/oct-input.vue Normal file
View File

@@ -0,0 +1,32 @@
<template>
<view>
<input type="text" placeholder="输入框" @blur="blurInput">
</view>
</template>
<script>
export default {
name:"octinput",
data() {
return {
};
},
props: {
InputKey: {
type: String,
default: ''
}
},
methods: {
// 触发信息给父组件
blurInput(e){
this.$emit('onValue', e.detail.value)
}
}
}
</script>
<style lang="scss">
</style>

38
components/oct-picker.vue Normal file
View File

@@ -0,0 +1,38 @@
<template>
<view>
<picker mode="selector" :range="range" range-key="title">
<view class=""></view>
</picker>
</view>
</template>
<script>
export default {
data() {
return {
};
},
props: {
range: {
type : Array,
default : () => {
return []
}
},
id: {
type : Number,
default : ''
}
},
watch(){
id: (val, old) => {
console.log(val, old)
}
}
}
</script>
<style lang="scss">
</style>

20
components/oct-radio.vue Normal file
View File

@@ -0,0 +1,20 @@
<template>
<view>
单选组件
</view>
</template>
<script>
export default {
name:"octradio",
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,20 @@
<template>
<view>
文本域组件
</view>
</template>
<script>
export default {
name:"octtextarea",
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

22
main.js Normal file
View File

@@ -0,0 +1,22 @@
import App from './App'
import Vue from 'vue'
import uView from "uview-ui";
import store from './store'
import { router, RouterMount } from 'router'
import Mylink from './node_modules/uni-simple-router/dist/link.vue'
Vue.component('my-link',Mylink)
Vue.use(uView)
Vue.use(router)
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()

117
manifest.json Normal file
View File

@@ -0,0 +1,117 @@
{
"name" : "抖火",
"appid" : "__UNI__C305C03",
"description" : "",
"versionName" : "1.0.3",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"safearea" : {
"bottom" : {
"offset" : "none"
}
},
/* */
"modules" : {
"Barcode" : {},
"Camera" : {}
},
/* */
"distribute" : {
/* android */
"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\"/>"
],
"schemes" : "doufire"
},
/* ios */
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {
"ad" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}

568
package-lock.json generated Normal file
View File

@@ -0,0 +1,568 @@
{
"name": "dou_fire",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "dou_fire",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"uni-read-pages": "^1.0.5",
"uni-simple-router": "^2.0.7",
"uview-ui": "^2.0.31",
"vue-canvas-poster": "^1.2.1",
"vuex": "^4.0.2"
}
},
"node_modules/@babel/parser": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
"integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz",
"integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz",
"integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.45",
"@vue/compiler-dom": "3.2.45",
"@vue/compiler-ssr": "3.2.45",
"@vue/reactivity-transform": "3.2.45",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
"source-map": "^0.6.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz",
"integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"node_modules/@vue/devtools-api": {
"version": "6.4.5",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
"integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
},
"node_modules/@vue/reactivity": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz",
"integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==",
"peer": true,
"dependencies": {
"@vue/shared": "3.2.45"
}
},
"node_modules/@vue/reactivity-transform": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz",
"integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.45",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz",
"integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz",
"integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==",
"peer": true,
"dependencies": {
"@vue/runtime-core": "3.2.45",
"@vue/shared": "3.2.45",
"csstype": "^2.6.8"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz",
"integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.2.45",
"@vue/shared": "3.2.45"
},
"peerDependencies": {
"vue": "3.2.45"
}
},
"node_modules/@vue/shared": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==",
"peer": true
},
"node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==",
"peer": true
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"node_modules/magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"peer": true,
"dependencies": {
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
"node_modules/postcss": {
"version": "8.4.20",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
}
],
"dependencies": {
"nanoid": "^3.3.4",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
"peer": true
},
"node_modules/uni-read-pages": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
"integrity": "sha512-GkrrZ0LX0vn9R5k6RKEi0Ez3Q3e2vUpjXQ8Z6/K/d28KudI9ajqgt8WEjQFlG5EPm1K6uTArN8LlqmZTEixDUA==",
"hasInstallScript": true
},
"node_modules/uni-simple-router": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz",
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
},
"node_modules/uview-ui": {
"version": "2.0.31",
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.31.tgz",
"integrity": "sha512-I/0fGuvtiKHH/mBb864SGYk+SJ7WaF32tsBgYgeBOsxlUp+Th+Ac2tgz2cTvsQJl6eZYWsKZ3ixiSXCAcxZ8Sw==",
"engines": {
"HBuilderX": "^3.1.0"
}
},
"node_modules/vue": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz",
"integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.2.45",
"@vue/compiler-sfc": "3.2.45",
"@vue/runtime-dom": "3.2.45",
"@vue/server-renderer": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"node_modules/vue-canvas-poster": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/vue-canvas-poster/-/vue-canvas-poster-1.2.1.tgz",
"integrity": "sha512-YY5ygbeQSqhiJyj6QXYgSRZ6Ywhvi1gVsfcvBIoCx4Yq9E/gAV32uOhnZz45qsklP86uGc9ypKJAXiX6Dzrdxw==",
"dependencies": {
"core-js": "^2.6.5",
"vue": "^2.6.10"
}
},
"node_modules/vue-canvas-poster/node_modules/@vue/compiler-sfc": {
"version": "2.7.14",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
"integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==",
"dependencies": {
"@babel/parser": "^7.18.4",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
}
},
"node_modules/vue-canvas-poster/node_modules/csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"node_modules/vue-canvas-poster/node_modules/vue": {
"version": "2.7.14",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.14.tgz",
"integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==",
"dependencies": {
"@vue/compiler-sfc": "2.7.14",
"csstype": "^3.1.0"
}
},
"node_modules/vuex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.11"
},
"peerDependencies": {
"vue": "^3.2.0"
}
}
},
"dependencies": {
"@babel/parser": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA=="
},
"@vue/compiler-core": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
"integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==",
"peer": true,
"requires": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"@vue/compiler-dom": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz",
"integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==",
"peer": true,
"requires": {
"@vue/compiler-core": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"@vue/compiler-sfc": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz",
"integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==",
"peer": true,
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.45",
"@vue/compiler-dom": "3.2.45",
"@vue/compiler-ssr": "3.2.45",
"@vue/reactivity-transform": "3.2.45",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
"source-map": "^0.6.1"
}
},
"@vue/compiler-ssr": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz",
"integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"@vue/devtools-api": {
"version": "6.4.5",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
"integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
},
"@vue/reactivity": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz",
"integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==",
"peer": true,
"requires": {
"@vue/shared": "3.2.45"
}
},
"@vue/reactivity-transform": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz",
"integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==",
"peer": true,
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.45",
"@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"@vue/runtime-core": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz",
"integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==",
"peer": true,
"requires": {
"@vue/reactivity": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"@vue/runtime-dom": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz",
"integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==",
"peer": true,
"requires": {
"@vue/runtime-core": "3.2.45",
"@vue/shared": "3.2.45",
"csstype": "^2.6.8"
}
},
"@vue/server-renderer": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz",
"integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==",
"peer": true,
"requires": {
"@vue/compiler-ssr": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"@vue/shared": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg==",
"peer": true
},
"core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
},
"csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==",
"peer": true
},
"estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
"integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
"peer": true,
"requires": {
"sourcemap-codec": "^1.4.8"
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
"postcss": {
"version": "8.4.20",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz",
"integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==",
"requires": {
"nanoid": "^3.3.4",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
},
"sourcemap-codec": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"peer": true
},
"uni-read-pages": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
"integrity": "sha512-GkrrZ0LX0vn9R5k6RKEi0Ez3Q3e2vUpjXQ8Z6/K/d28KudI9ajqgt8WEjQFlG5EPm1K6uTArN8LlqmZTEixDUA=="
},
"uni-simple-router": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/uni-simple-router/-/uni-simple-router-2.0.7.tgz",
"integrity": "sha512-8FKv5dw7Eoonm0gkO8udprrxzin0fNUI0+AvIphFkFRH5ZmP5ZWJ2pvnWzb2NiiqQSECTSU5VSB7HhvOSwD5eA=="
},
"uview-ui": {
"version": "2.0.31",
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-2.0.31.tgz",
"integrity": "sha512-I/0fGuvtiKHH/mBb864SGYk+SJ7WaF32tsBgYgeBOsxlUp+Th+Ac2tgz2cTvsQJl6eZYWsKZ3ixiSXCAcxZ8Sw=="
},
"vue": {
"version": "3.2.45",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz",
"integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==",
"peer": true,
"requires": {
"@vue/compiler-dom": "3.2.45",
"@vue/compiler-sfc": "3.2.45",
"@vue/runtime-dom": "3.2.45",
"@vue/server-renderer": "3.2.45",
"@vue/shared": "3.2.45"
}
},
"vue-canvas-poster": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/vue-canvas-poster/-/vue-canvas-poster-1.2.1.tgz",
"integrity": "sha512-YY5ygbeQSqhiJyj6QXYgSRZ6Ywhvi1gVsfcvBIoCx4Yq9E/gAV32uOhnZz45qsklP86uGc9ypKJAXiX6Dzrdxw==",
"requires": {
"core-js": "^2.6.5",
"vue": "^2.6.10"
},
"dependencies": {
"@vue/compiler-sfc": {
"version": "2.7.14",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
"integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==",
"requires": {
"@babel/parser": "^7.18.4",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
}
},
"csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"vue": {
"version": "2.7.14",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.14.tgz",
"integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==",
"requires": {
"@vue/compiler-sfc": "2.7.14",
"csstype": "^3.1.0"
}
}
}
},
"vuex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
"requires": {
"@vue/devtools-api": "^6.0.0-beta.11"
}
}
}
}

15
package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"dependencies": {
"uni-read-pages": "^1.0.5",
"uni-simple-router": "^2.0.7",
"uview-ui": "^2.0.31",
"vue-canvas-poster": "^1.2.1",
"vuex": "^4.0.2"
},
"name": "dou_fire",
"version": "1.0.0",
"main": "index.js",
"repository": "https://git.yuzhankeji.cn/TmOct5/dou_fire.git",
"author": "唐明明 <970899069@qq.com>",
"license": "MIT"
}

404
pages.json Normal file
View File

@@ -0,0 +1,404 @@
{
"pages": [{
"path": "pages/index/index",
"name": "Index",
"style": {
"navigationBarTitleText": "抖火法务咨询服务",
"navigationBarBackgroundColor": "#FFFFFF"
}
}, {
"path": "pages/college/index",
"name": "College",
"style": {
"navigationBarTitleText": "商学院",
"navigationStyle": "custom"
}
}, {
"path": "pages/work/index",
"name": "Work",
"style": {
"navigationBarTitleText": "工作台",
"navigationStyle": "custom"
}
}, {
"path": "pages/user/index",
"name": "User",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/auth/auth",
"name": "Auth",
"style": {
"navigationBarTitleText": "",
"disableScroll": false,
"navigationStyle": "custom",
"animationType": "slide-in-bottom"
}
}, {
"path": "pages/auth/registered",
"name": "Registered",
"style": {
"navigationBarTitleText": "注册",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/auth/resetPassword",
"name": "ResetPassword",
"style": {
"navigationBarTitleText": "重置密码",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/college/test",
"name": "CollegeTest",
"auth": true,
"style": {
"navigationBarTitleText": "考试",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/richText/richText",
"name": "RichText",
"style": {
"navigationBarTitleText": "-",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/create",
"name": "OrderCreate",
"auth": true,
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/orders",
"name": "Orders",
"auth": true,
"style": {
"navigationBarTitleText": "订单管理",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/service",
"name": "OrdersService",
"auth": true,
"style": {
"navigationBarTitleText": "分配服务包",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff",
"app-plus": {
"titleNView": {
"buttons": [{
"text": "添加",
"color": "#446EFE",
"fontSize": "32rpx",
"width": "120rpx"
}]
}
}
}
}, {
"path": "pages/work/available",
"name": "OrderAvailable",
"auth": true,
"style": {
"navigationBarTitleText": "搜索用户",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/generate",
"auth": true,
"name": "WorkGenerate",
"style": {
"navigationBarTitleText": "基础信息",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/user/info",
"auth": true,
"name": "UserInfo",
"style": {
"navigationBarTitleText": "编辑",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/user/code",
"auth": true,
"name": "UserCode",
"style": {
"navigationBarTitleText": "邀请二维码",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#1F25AE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/user/certification",
"auth": true,
"name": "UserCertification",
"style": {
"navigationBarTitleText": "实名认证",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/user/team",
"auth": true,
"name": "UserTeam",
"style": {
"navigationBarTitleText": "我的客户",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/user/set",
"auth": true,
"name": "UserSet",
"style": {
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/account/bonus",
"auth": true,
"name": "AccountBonus",
"style": {
"navigationBarTitleText": "奖金账户",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#926fff",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/account/cash",
"auth": true,
"name": "AccountCash",
"style": {
"navigationBarTitleText": "业绩账户",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/account/integral",
"auth": true,
"name": "AccountIntegral",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff",
"app-plus": {
"titleNView": {
"buttons": [{
"text": "充值记录",
"color": "#111",
"fontSize": "32rpx",
"width": "180rpx"
}]
}
}
}
}, {
"path": "pages/college/answer",
"auth": true,
"name": "CollegeAnswer",
"style": {
"navigationBarTitleText": "答题",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/college/testResults",
"auth": true,
"name": "CollegeResults",
"style": {
"navigationBarTitleText": "考试结果",
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": false
}
}, {
"path": "pages/account/logs",
"auth": true,
"name": "AccountLogs",
"style": {
"navigationBarTitleText": "账户记录",
"enablePullDownRefresh": false
}
}, {
"path": "pages/pay/pay",
"auth": true,
"name": "Pay",
"style": {
"navigationBarTitleText": "收银台",
"enablePullDownRefresh": false
}
}, {
"path": "pages/work/orderInfo",
"auth": true,
"name": "OrderInfo",
"style": {
"navigationBarTitleText": "详情",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/user/eSign",
"auth": true,
"name": "ESign",
"style": {
"navigationBarTitleText": "人脸认证",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#FFFFFF"
}
}, {
"path": "pages/work/perfectChoose",
"auth": true,
"name": "WorkPerfectChoose",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/work/perfectInstitutions",
"auth": true,
"name": "WorkPerfectInstitutions",
"style": {
"navigationBarTitleText": "机构信息",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/work/perfectBasis",
"auth": true,
"name": "WorkPerfectBasis",
"style": {
"navigationBarTitleText": "基础信息",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/transfers/lists",
"auth": true,
"name": "TransfersOrders",
"style": {
"navigationBarTitleText": "转让订单",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/modifyOrder",
"auth": true,
"name": "ModifyOrder",
"style": {
"navigationBarTitleText": "修改资料订单",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/poorOrder",
"auth": true,
"name": "PoorOrder",
"style": {
"navigationBarTitleText": "补差价订单",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/refundOrder",
"auth": true,
"name": "RefundOrder",
"style": {
"navigationBarTitleText": "退款订单",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#ffffff"
}
}, {
"path": "pages/work/mailed",
"auth": true,
"name": "MailedOrder",
"style": {
"navigationBarTitleText": "邮寄材料",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}, {
"path": "pages/work/mailedInfo",
"auth": true,
"name": "MailedOrderInfo",
"style": {
"navigationBarTitleText": "邮寄信息",
"enablePullDownRefresh": false
}
}, {
"path": "pages/work/schemes",
"auth": true,
"name": "OrderSchemes",
"style": {
"navigationBarTitleText": "预估方案",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#446EFE",
"navigationBarTextStyle": "white"
}
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "抖火",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"backgroundColor": "white",
"borderStyle": "white",
"color": "#999999",
"selectedColor": "#446EFE",
"list": [{
"iconPath": "static/icons/tabs_icon_00.png",
"selectedIconPath": "static/icons/tabs_show_00.png",
"pagePath": "pages/index/index",
"text": "服务包"
}, {
"iconPath": "static/icons/tabs_icon_01.png",
"selectedIconPath": "static/icons/tabs_show_01.png",
"pagePath": "pages/college/index",
"text": "商学院"
}, {
"iconPath": "static/icons/tabs_icon_02.png",
"selectedIconPath": "static/icons/tabs_show_02.png",
"pagePath": "pages/work/index",
"text": "工作台"
}, {
"iconPath": "static/icons/tabs_icon_03.png",
"selectedIconPath": "static/icons/tabs_show_03.png",
"pagePath": "pages/user/index",
"text": "我的"
}]
},
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"uniIdRouter": {}
}

188
pages/account/bonus.vue Normal file
View File

@@ -0,0 +1,188 @@
<template>
<view class="content">
<!-- 账户余额 -->
<view class="total" :style="'background-image: url(' + require('@/static/imgs/bonus_back.png') + ');'">
<view class="total-left">
<view class="total-value nowrap">{{total}}</view>
<view class="total-text nowrap">账户余额</view>
</view>
<view class="total-btn">提现</view>
</view>
<!-- 账户记录 -->
<view class="tabs">
<u-tabs
:list="tabs"
:scrollable="false"
:activeStyle="{color: '#906BFF', fontWeight: 'bold'}"
lineColor="#8E6AFF"
@click="onTabs"
></u-tabs>
</view>
<view class="logs">
<block v-if="list.length > 0">
<view class="log-flex" v-for="(item, index) in list" :key="index">
<view class="text">
<view class="type nowrap">xxx奖金收益</view>
<view class="time nowrap">2022-12-12 10:18</view>
</view>
<view class="price nowrap">+50000</view>
</view>
</block>
<block v-else>
<view class="list-null">
<u-empty
mode="history"
icon="http://cdn.uviewui.com/uview/empty/history.png"
text="暂无相关记录"
>
</u-empty>
</view>
</block>
</view>
<u-loadmore v-if="pagesShow" :status="status" />
</view>
</template>
<script>
import { balance } from '@/apis/interfaces/account.js'
export default {
data() {
return {
tabs: [
{ name: '奖金收益明细', value: '' },
{ name: '提现记录', value: '' },
],
total : '0.00',
list : [],
page : {
current : 1,
has_more: false,
},
pagesShow: false,
status : ''
};
},
created() {
this.getList()
},
methods: {
onTabs(e){
console.log(e)
console.log('这里需要之后处理提现记录')
},
getList(){
balance({
page: this.page.current
}).then(res => {
let { balance, logs } = res;
let atList = logs.page.current == 1 ? [] : this.list
this.total = balance
this.list = atList.concat(logs.data)
this.page = logs.page
this.pagesShow = false
})
}
},
onReachBottom() {
this.pagesShow = true;
if(this.page.has_more){
this.status = 'loading';
this.page.current++
this.getList()
return
}
this.status = 'nomore';
}
}
</script>
<style lang="scss">
// tabs
.tabs{
border-radius: 20rpx 20rpx 0 0;
padding: 5px 0;
margin: -54px 30rpx 0;
background: white;
position: relative;
z-index: 1;
border-bottom: solid 1rpx #F6F6F6;
}
// 账户余额
.total{
background-size: cover;
background-position: top center;
padding: 50rpx 30rpx 170rpx;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
.total-left{
width: calc( 100% - 200rpx );
}
.total-value{
font-weight: bold;
font-size: 60rpx;
font-family: Arial, Helvetica, sans-serif;
}
.total-text{
font-size: 30rpx;
opacity: .7;
line-height: 40rpx;
padding-top: 20rpx;
}
.total-btn{
background: white;
color: #8E6AFF;
line-height: 80rpx;
border-radius: 40rpx;
width: 170rpx;
font-weight: bold;
text-align: center;
}
}
// 记录空
.list-null{
height: 70vh;
display: flex;
align-items: center;
justify-content: center;
}
// 记录
.logs{
box-sizing: border-box;
background-color: white;
margin: 0 30rpx;
padding: 0 30rpx;
border-radius: 0 0 20rpx 20rpx;
.log-flex{
padding: 25rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
color: #666666;
border-top: solid 1rpx #F6F6F6;
&:first-child{
border-top: none;
}
.text{
width: calc(100% - 200rpx);
}
.price{
width: 200rpx;
text-align: right;
font-weight: bold;
color: #9675FF;
}
.type{
font-weight: bold;
font-size: 30rpx;
color: #666666;
}
.time{
font-size: 28rpx;
color: gray;
}
}
}
</style>

199
pages/account/cash.vue Normal file
View File

@@ -0,0 +1,199 @@
<template>
<view class="content">
<u-sticky bgColor="#446EFE">
<view class="type-tab">
<text :class="{'active': type == 'self' }" @click="onTabs('self')">个人业绩</text>/
<text :class="{'active': type == 'group' }" @click="onTabs('group')">团队业绩</text>
</view>
</u-sticky>
<!-- 账户余额 -->
<view class="total" :style="'background-image: url(' + require('@/static/imgs/cash_back.png') + ');'">
<view class="total-value nowrap">{{total}}</view>
<view class="total-text">个人总业绩</view>
</view>
<!-- 账户记录 -->
<view class="logs">
<view class="log-item">
<view class="tabs">
<u-tabs
:list="tabs"
:activeStyle="{'color': '#446EFE'}"
lineColor="#446EFE"
:scrollable="false"
@click="onDayTab"
></u-tabs>
</view>
<block v-if="list.length > 0">
<view class="log-flex" v-for="(item, index) in list" :key="index">
<view class="type nowrap">{{item.type}}</view>
<view class="perf nowrap">{{item.perf}}</view>
<view class="time nowrap">{{item.created_at}}</view>
</view>
</block>
<block v-else>
<view class="list-null">
<u-empty
mode="history"
icon="http://cdn.uviewui.com/uview/empty/history.png"
text="暂无相关账户记录"
>
</u-empty>
</view>
</block>
</view>
<u-loadmore v-if="pagesShow" :status="status" />
</view>
</view>
</template>
<script>
import { cash } from '@/apis/interfaces/account.js'
export default {
data() {
return {
tabs : [
{ name: '当月业绩', value: 'month'},
{ name: '当年业绩', value: 'year'}
],
dayType : 'month',
type : 'self',
total : '0.00',
list : [],
page : {
current : 1,
has_more: false,
},
pagesShow : false,
status : ''
};
},
created() {
this.getLog()
},
methods: {
onTabs(e){
if(this.type === e) return
this.type = e
this.page.current = 1
this.getLog()
},
// 选择日期
onDayTab(e){
if(this.dayType === e.value) return
this.dayType = e.value
this.page.current = 1
this.getLog()
},
// 获取列表
getLog(){
cash({
day : this.type,
type: this.dayType,
page: this.page.current
}).then(res => {
let { total, lists } = res;
let atList = lists.page.current == 1 ? [] : this.list
this.list = atList.concat(lists.data)
this.page = lists.page
this.pagesShow = false
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
},
onReachBottom() {
this.pagesShow = true;
if(this.page.has_more){
this.status = 'loading';
this.page.current++
this.getLog()
return
}
this.status = 'nomore';
}
}
</script>
<style lang="scss">
// 统计类型选择
.type-tab{
text-align: center;
padding-bottom: 20rpx;
color: white;
font-size: 30rpx;
text{
margin: 0 30rpx;
line-height: 70rpx;
&.active{
font-weight: bold;
font-size: 34rpx;
}
}
}
// 账户余额
.total{
margin: 30rpx 30rpx 0;
background-size: cover;
background-position: center;
border-radius: 20rpx;
padding: 50rpx 30rpx;
color: white;
.total-value{
font-weight: bold;
font-size: 60rpx;
font-family: Arial, Helvetica, sans-serif;
}
.total-text{
font-size: 30rpx;
opacity: .7;
line-height: 40rpx;
padding-top: 10rpx;
}
}
// 记录空
.list-null{
height: 50vh;
display: flex;
align-items: center;
justify-content: center;
}
// 记录
.logs{
padding: 30rpx;
box-sizing: border-box;
.log-item{
background: white;
padding: 10rpx 30rpx;
border-radius: 20rpx;
margin-bottom: 20rpx;
.tabs{
border-bottom: solid 1rpx #F6F6F6;
margin: 0 -30rpx 10rpx;
}
.log-flex{
padding: 5rpx 0;
display: flex;
justify-content: space-between;
line-height: 70rpx;
align-items: center;
font-size: 30rpx;
color: #666666;
.type{
width: 150rpx;
}
.time{
width: 300rpx;
text-align: right;
}
.perf{
width: calc( 100% - 450rpx);
text-align: center;
}
}
}
}
</style>

111
pages/account/integral.vue Normal file
View File

@@ -0,0 +1,111 @@
<template>
<view class="integral">
<image class="icon" src="@/static/icons/work_icon_22.png" mode="aspectFill"></image>
<view class="title">火力值</view>
<view class="score">{{score}}</view>
<view class="btns">
<button class="btns-item" size="mini" @click="onNav('AccountLogs', { type: 0 })">消费记录</button>
</view>
<view class="footer">抖火法律</view>
</view>
</template>
<script>
import { score } from '@/apis/interfaces/account.js'
export default {
data() {
return {
score: '0.00',
logs : [],
pages: {}
};
},
created() {
this.getScore()
},
methods: {
getScore(){
uni.showLoading({
title: '加载中...',
mask : true
})
score().then(res => {
this.score = res.score
this.logs = res.logs
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
onNav(name, p){
let params = p || {}
this.$Router.push({name, params})
}
},
onNavigationBarButtonTap() {
this.onNav('AccountLogs', { type: 1 })
}
}
</script>
<style lang="scss">
.integral{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
height: 100vh;
padding: 50rpx;
box-sizing: border-box;
.icon{
width: 128rpx;
height: 128rpx;
border-radius: 50%;
margin-bottom: 40rpx;
background: #f1f1f1;
}
.title{
font-size: 32rpx;
color: #111;
line-height: 50rpx;
}
.score{
padding-top: 20rpx;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
font-size: 86rpx;
}
.btns{
display: flex;
flex-direction: column;
height: 40vh;
justify-content: flex-end;
width: 100%;
.btns-item[size="mini"]{
width: 50vw;
height: 100rpx;
line-height: 100rpx;
padding: 0;
background: $main-color;
font-weight: bold;
color: white;
font-size: 32rpx;
&::after{
display: none;
}
&:last-child{
background-color: #f1f1f1;
margin-top: 30rpx;
color: $main-color;
}
}
}
.footer{
font-size: 28rpx;
color: gray;
padding-top: 10vh;
}
}
</style>

144
pages/account/logs.vue Normal file
View File

@@ -0,0 +1,144 @@
<template>
<view class="content">
<u-sticky bgColor="#f8f8f8">
<u-tabs
:current="current"
:list="tabs"
:scrollable="false"
lineColor="#446EFE"
@click="onTabs"
></u-tabs>
</u-sticky>
<!-- 账户记录 -->
<view class="logs" v-if="list.length > 0">
<view class="log-item" v-for="(item, index) in list" :key="index">
<view class="log-flex">
<view class="title nowrap">{{item.rule.title}}{{item.rule.remark}}</view>
<view class="price">{{item.amount}}</view>
</view>
<view class="log-flex">
<view class="time">{{item.created_at}}</view>
<view class="state">{{item.frozen.text}}</view>
</view>
</view>
<u-loadmore v-if="pagesShow" :status="status" />
</view>
<view v-else class="list-null">
<u-empty
mode="history"
icon="http://cdn.uviewui.com/uview/empty/history.png"
text="暂无相关账户记录"
>
</u-empty>
</view>
</view>
</template>
<script>
import { log } from '@/apis/interfaces/account.js'
export default {
data() {
return {
tabs : [
{ val: 'out', name: '消费记录' },
{ val: 'in', name: '充值记录' }
],
current : 0,
list : [],
page : {
current : 1,
has_more: false,
},
pagesShow : false,
status : ''
};
},
created() {
this.current = this.$Route.query.type
this.getLog()
},
methods: {
onTabs(e){
if(this.current === e.index) return
this.current = e.index
this.page.current = 1
this.getLog()
},
// 获取列表
getLog(){
log({
type: this.tabs[this.current].val,
page: this.page.current
}).then(res => {
let { logs } = res;
let atList = logs.page.current == 1 ? [] : this.list
this.list = atList.concat(logs.data)
this.page = logs.page
this.pagesShow = false
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
},
onReachBottom() {
this.pagesShow = true;
if(this.page.has_more){
this.status = 'loading';
this.page.current++
this.getLog()
return
}
this.status = 'nomore';
}
}
</script>
<style lang="scss">
// 记录空
.list-null{
height: 80vh;
display: flex;
align-items: center;
justify-content: center;
}
// 记录
.logs{
padding: 30rpx;
box-sizing: border-box;
.log-item{
background: white;
padding: 30rpx;
border-radius: 20rpx;
margin-bottom: 20rpx;
.log-flex{
padding: 5rpx 0;
display: flex;
justify-content: space-between;
line-height: 40rpx;
align-items: center;
.title{
font-weight: bold;
font-size: 32rpx;
width: calc(100% - 200rpx);
}
.price{
font-size: 32rpx;
width: 200rpx;
text-align: right;
font-weight: bold;
color: $main-color;
}
.time{
font-size: 28rpx;
color: gray;
}
.state{
font-size: 28rpx;
}
}
}
}
</style>

190
pages/auth/auth.vue Normal file
View File

@@ -0,0 +1,190 @@
<template>
<view class="auth-center">
<view class="login-left" @click="onBack()">
<u-icon name="close" color="#000" size="24"></u-icon>
</view>
<view class="login">
<view class="logo">
<image class="logo-src" src="@/static/imgs/logo.png"/>
</view>
<view class="hello">欢迎使用抖火法律</view>
<view class="input input-phone">
<label>+86</label>
<input type="number" v-model="phone" placeholder="请输入手机号码">
</view>
<view class="input">
<input type="safe-password" password v-model="password" placeholder="请输入密码">
</view>
<view class="btn">
<button :disabled="phone.length < 11 || password == '' || agreement.length == 0" @click="onAuth()">登录</button>
</view>
<view class="agreement">
<u-checkbox-group
v-model="agreement"
placement="row"
>
<u-checkbox shape="circle" name="agreement" activeColor="#446EFE"></u-checkbox>
我已阅读并同意
<my-link class="agreement-nav" :to="{name: 'richText', params: {id: 1}}">服务协议</my-link>
<my-link class="agreement-nav" :to="{name: 'richText', params: {id: 2}}">隐私权政策</my-link>
</u-checkbox-group>
</view>
</view>
<view class="footer">
<my-link class="footer-nav" :to="{ name: 'Registered' }">注册账号</my-link>
<my-link class="footer-nav" :to="{ name: 'ResetPassword' }">找回密码</my-link>
</view>
</view>
</template>
<script>
import { auth } from '@/apis/interfaces/auth.js'
export default {
data() {
return {
phone : '',
password : '',
agreement : []
};
},
methods: {
onAuth(){
uni.showLoading({
title: '登录中...'
})
auth({
username: this.phone,
password: this.password
}).then(res => {
// 存储登录凭证
this.$store.commit('setToken', res.token_type + ' ' + res.access_token);
this.onBack()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
onBack(){
try{
this.$Router.back()
}catch(e){
this.$Router.replaceAll({name: 'Index'})
}
}
}
}
</script>
<style lang="scss">
.auth-center{
position: relative;
background: white;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100vh;
box-sizing: border-box;
@extend .ios-bottom;
@extend .ios-top;
}
// 关闭登录
.login-left{
position: absolute;
right: $padding * 2;
top: $padding;
@extend .ios-top;
}
// 登录
.login{
padding: $padding * 2;
.logo{
padding-top: $padding * 2;
padding-bottom: $padding / 2;
.logo-src{
width: 98rpx;
height: 98rpx;
border-radius: $radius;
vertical-align: top;
}
}
.hello{
font-weight: bold;
font-size: 54rpx;
color: $text-color;
padding-bottom: $padding * 2;
}
.input{
border-bottom: solid 1rpx $border-color;
height: 100rpx;
line-height: 100rpx;
margin-bottom: $margin;
input{
height: 100rpx;
box-sizing: border-box;
font-size: 32rpx;
color: $text-color;
}
&.input-phone{
display: flex;
align-items: center;
label{
border-right: solid 1rpx $border-color;
padding: 0 $padding;
box-sizing: border-box;
width: 140rpx;
height: 50rpx;
line-height: 50rpx;
font-size: 32rpx;
color: $text-color;
}
input{
padding: 0 $padding;
flex: 1;
}
}
}
.btn{
button{
background: $main-color;
border-radius: $radius-lg;
height: 100rpx;
line-height: 100rpx;
color: white;
font-size: 38rpx;
&::after{
display: none;
}
&[disabled]{
opacity: .5;
}
}
}
.agreement{
padding-top: $padding * 2;
font-size: 30rpx;
color: $text-gray;
&-nav{
display: inline-block;
font-size: 30rpx;
color: $main-color;
}
}
}
// 底部
.footer{
padding: 50rpx 50rpx 100rpx;
height: 100rpx;
text-align: center;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
&-nav{
font-size: 30rpx;
margin: 0 $margin;
color: $text-gray;
}
}
</style>

282
pages/auth/registered.vue Normal file
View File

@@ -0,0 +1,282 @@
<template>
<view class="registered-content">
<view class="title">你好欢迎使用抖火法律</view>
<view class="submit-title">请填写账号信息</view>
<view class="from">
<view class="from-inpus from-input-phoen">
<label>+86</label>
<input type="number" v-model="username" placeholder="输入手机号码">
</view>
<view class="from-inpus">
<label>登录密码</label>
<input type="safe-password" password v-model="password" placeholder="设置登录密码">
</view>
<view class="from-inpus">
<label>确认密码</label>
<input type="safe-password" password v-model="confirmation" placeholder="请确认登录密码">
</view>
<view class="from-inpus from-input-code">
<label>验证码</label>
<input type="number" v-model="code" maxlength="4" placeholder="短信验证码">
<button :disabled="username.length < 11 || getSms" @click="getCode">{{sendCode}}</button>
</view>
</view>
<view class="button">
<button @click="onRegistered()">注册并登录</button>
</view>
<!-- 显示图形验证码 -->
<u-popup :show="captchaShow" mode="center" :round="10" closeable @close="captchaShow = false, captcha = ''">
<view class="captcha-lay">
<view class="captcha-title">图形验证</view>
<view class="captcha-img">
<image :src="captchaImg" mode="widthFix" @click="getCode()"></image>
</view>
<view class="captcha-input">
<input type="text" placeholder="请输入验证码" v-model="captcha" maxlength="10">
</view>
<button class="captcha-btn" @click="getPhoneCode">验证</button>
</view>
</u-popup>
</view>
</template>
<script>
var outTime;
import { register, captcha, verifyCaptcha } from '@/apis/interfaces/auth.js'
export default {
data() {
return {
username : '18245180131',
password : '',
confirmation: '',
code : '',
getSms : false,
sendCode : '获取验证码',
captcha : '',
captchaImg : '',
captchaKey : '',
captchaShow : false
};
},
methods: {
// 提交注册信息
onRegistered(){
uni.showLoading({
title: '提交中...',
mask : true
})
register({
username : this.username,
password : this.password,
password_confirmation : this.confirmation,
code : this.code
}).then(res => {
// 重置验证码与计时器
this.getSms = false;
this.sendCode = '获取验证码';
clearInterval(outTime);
// 存储登录凭证
this.$store.commit('setToken', res.token_type + ' ' + res.access_token);
try{
this.$Router.back(2)
} catch (err){
this.$Router.replaceAll({name: 'Index'})
}
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 弹出图形验证码
getCode(){
uni.showLoading({
title: '加载中...',
mask : true
})
captcha().then(res => {
let { img, key } = res
this.captchaImg = img
this.captchaKey = key
this.captchaShow = true
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 获取验证码
getPhoneCode() {
uni.showLoading({
title : '加载中...',
mask :true
})
let smsTime = 60;
verifyCaptcha({
mobileNo : this.username,
captcha : this.captcha,
captcha_key : this.captchaKey
}).then(res => {
uni.showToast({
title: res.message,
icon: "none",
});
this.captchaShow = false;
this.captcha = '';
this.getSms = true;
this.sendCode = smsTime + 's后重新获取';
outTime = setInterval(() => {
if (smsTime <= 1) {
this.getSms = false;
this.sendCode = '重新获取';
clearInterval(outTime);
return
}
this.sendCode = smsTime + 's后重新获取';
smsTime -= 1;
}, 1000);
}).catch((err) => {
uni.showToast({
title: err.message,
icon: "none",
});
});
}
}
}
</script>
<style lang="scss">
// 图形验证码
.captcha-lay{
padding: 30rpx;
width: 70vw;
box-sizing: border-box;
.captcha-title{
text-align: center;
font-size: 35rpx;
font-weight: bold;
line-height: 90rpx;
}
.captcha-img{
text-align: center;
padding-bottom: 30rpx;
image{
width: 300rpx;
}
}
.captcha-input{
input{
height: 100rpx;
border:solid 1rpx #ddd;
text-align: center;
line-height: 98rpx;
font-size: 34rpx;
padding: 0 30rpx;
box-sizing: border-box;
border-radius: $radius-lg;
background: transparent;
}
}
.captcha-btn{
margin-top: 30rpx;
background: $main-color;
color: white;
font-weight: normal;
font-size: 34rpx;
border-radius: $radius-lg;
height: 90rpx;
line-height: 90rpx;
&::after{
border: none;
}
}
}
// 注册
.registered-content{
padding: 50rpx;
.title{
padding-top: 3vh;
padding-bottom: 10rpx;
font-weight: bold;
font-size: 44rpx;
}
.submit-title{
font-size: 30rpx;
color: gray;
line-height: 40rpx;
}
// 注册单
.from{
margin-top: 80rpx;
}
.from-inpus{
@extend .border-solid;
display: flex;
align-items: center;
margin-bottom: 20rpx;
justify-content: space-between;
label{
width: 170rpx;
line-height: 100rpx;
font-size: 32rpx;
}
input{
width: calc(100% - 200rpx);
height: 100rpx;
line-height: 100rpx;
font-size: 32rpx;
}
}
.from-input-phoen{
label{
line-height: 60rpx;
height: 60rpx;
border-right: solid 1rpx $border-color;
}
}
.from-input-code{
button{
font-size: 32rpx;
width: 230rpx;
padding: 0;
height: 80rpx;
line-height: 80rpx;
border-radius: 0;
margin: 0;
border: none;
background: transparent;
color: $main-color;
&::after{
display: none;
}
&[disabled]{
opacity: .5;
}
}
input{
width: calc(100% - 460rpx);
}
}
// 按钮
.button{
padding-top: 50rpx;
button{
background: $main-color;
border-radius: $radius-lg;
height: 100rpx;
line-height: 100rpx;
color: white;
font-size: 38rpx;
&::after{
display: none;
}
&[disabled]{
opacity: .5;
}
}
}
}
</style>

View File

@@ -0,0 +1,284 @@
<template>
<view class="registered-content">
<view class="title">重置账户登录密码</view>
<view class="submit-title">请填写账号信息</view>
<view class="from">
<view class="from-inpus from-input-phoen">
<label>+86</label>
<input type="number" v-model="username" placeholder="输入手机号码">
</view>
<view class="from-inpus">
<label>新密码</label>
<input type="safe-password" password v-model="password" placeholder="设置新的登录密码">
</view>
<view class="from-inpus">
<label>确认密码</label>
<input type="safe-password" password v-model="confirmation" placeholder="请确认登录密码">
</view>
<view class="from-inpus from-input-code">
<label>验证码</label>
<input type="number" v-model="code" maxlength="4" placeholder="短信验证码">
<button :disabled="username.length < 11 || getSms" @click="getCode">{{sendCode}}</button>
</view>
</view>
<view class="button">
<button @click="onRegistered()">重置</button>
</view>
<!-- 显示图形验证码 -->
<u-popup :show="captchaShow" mode="center" :round="10" closeable @close="captchaShow = false, captcha = ''">
<view class="captcha-lay">
<view class="captcha-title">图形验证</view>
<view class="captcha-img">
<image :src="captchaImg" mode="widthFix" @click="getCode()"></image>
</view>
<view class="captcha-input">
<input type="text" placeholder="请输入验证码" v-model="captcha" maxlength="10">
</view>
<button class="captcha-btn" @click="getPhoneCode">验证</button>
</view>
</u-popup>
</view>
</template>
<script>
var outTime;
import { resetPassword, captcha, verifyCaptcha } from '@/apis/interfaces/auth.js'
export default {
data() {
return {
username : '',
password : '',
confirmation: '',
code : '',
getSms : false,
sendCode : '获取验证码',
captcha : '',
captchaImg : '',
captchaKey : '',
captchaShow : false
};
},
methods: {
// 提交修改信息
onRegistered(){
uni.showLoading({
title: '提交中...',
mask : true
})
resetPassword({
username : this.username,
password : this.password,
password_confirmation : this.confirmation,
code : this.code,
}).then(res => {
// 重置验证码与计时器
this.getSms = false;
this.sendCode = '获取验证码';
clearInterval(outTime);
uni.showModal({
title : "提示",
content : "登录密码已重置",
showCancel : false,
confirmColor: "#446EFE",
success : modalRes => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 弹出图形验证码
getCode(){
uni.showLoading({
title: '加载中...',
mask : true
})
captcha().then(res => {
let { img, key } = res
this.captchaImg = img
this.captchaKey = key
this.captchaShow = true
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 获取验证码
getPhoneCode() {
uni.showLoading({
title : '加载中...',
mask :true
})
let smsTime = 60;
verifyCaptcha({
mobileNo : this.username,
captcha : this.captcha,
captcha_key : this.captchaKey
}).then(res => {
uni.showToast({
title: res.message,
icon: "none",
});
this.captchaShow = false;
this.captcha = '';
this.getSms = true;
this.sendCode = smsTime + 's后重新获取';
outTime = setInterval(() => {
if (smsTime <= 1) {
this.getSms = false;
this.sendCode = '重新获取';
clearInterval(outTime);
return
}
this.sendCode = smsTime + 's后重新获取';
smsTime -= 1;
}, 1000);
}).catch((err) => {
uni.showToast({
title: err.message,
icon: "none",
});
});
}
}
}
</script>
<style lang="scss">
// 图形验证码
.captcha-lay{
padding: 30rpx;
width: 70vw;
box-sizing: border-box;
.captcha-title{
text-align: center;
font-size: 35rpx;
font-weight: bold;
line-height: 90rpx;
}
.captcha-img{
text-align: center;
padding-bottom: 30rpx;
image{
width: 300rpx;
}
}
.captcha-input{
input{
height: 100rpx;
border:solid 1rpx #ddd;
text-align: center;
line-height: 98rpx;
font-size: 34rpx;
padding: 0 30rpx;
box-sizing: border-box;
border-radius: $radius-lg;
background: transparent;
}
}
.captcha-btn{
margin-top: 30rpx;
background: $main-color;
color: white;
font-weight: normal;
font-size: 34rpx;
border-radius: $radius-lg;
height: 90rpx;
line-height: 90rpx;
&::after{
border: none;
}
}
}
// 注册
.registered-content{
padding: 50rpx;
.title{
padding-top: 3vh;
padding-bottom: 10rpx;
font-weight: bold;
font-size: 44rpx;
}
.submit-title{
font-size: 30rpx;
color: gray;
line-height: 40rpx;
}
// 注册单
.from{
margin-top: 80rpx;
}
.from-inpus{
@extend .border-solid;
display: flex;
align-items: center;
margin-bottom: 20rpx;
justify-content: space-between;
label{
width: 170rpx;
line-height: 100rpx;
font-size: 32rpx;
}
input{
width: calc(100% - 200rpx);
height: 100rpx;
line-height: 100rpx;
font-size: 32rpx;
}
}
.from-input-phoen{
label{
line-height: 60rpx;
height: 60rpx;
border-right: solid 1rpx $border-color;
}
}
.from-input-code{
button{
font-size: 32rpx;
width: 230rpx;
padding: 0;
height: 80rpx;
line-height: 80rpx;
border-radius: 0;
margin: 0;
border: none;
background: transparent;
color: $main-color;
&::after{
display: none;
}
&[disabled]{
opacity: .5;
}
}
input{
width: calc(100% - 460rpx);
}
}
// 按钮
.button{
padding-top: 50rpx;
button{
background: $main-color;
border-radius: $radius-lg;
height: 100rpx;
line-height: 100rpx;
color: white;
font-size: 38rpx;
&::after{
display: none;
}
&[disabled]{
opacity: .5;
}
}
}
}
</style>

443
pages/college/answer.vue Normal file
View File

@@ -0,0 +1,443 @@
<template>
<view class="content">
<!-- header -->
<u-sticky zIndex="10">
<view class="answer-header">
<view class="flex">
<view class="flex-item">答题进度<text>{{questionsIndex + 1}}</text>/{{questions.length}}</view>
<view class="flex-item">
剩余时间
<u-count-down class="flex-item-down" :time="Number(outTime) * 60 * 1000" format="mm:ss" @finish="answerNext('time')"></u-count-down>
</view>
</view>
<u-line-progress
inactiveColor="rgba(255,255,255,.5)"
:percentage="percentageVal"
activeColor="#fff"
></u-line-progress>
</view>
</u-sticky>
<!-- 答题卡 -->
<view class="block" v-if="questions.length > 0">
<block v-if="isShowAnswer">
<!-- 题目类型 -->
<view class="answer-type">
<text v-if="questions[questionsIndex].type == 1">单选题</text>
<text v-if="questions[questionsIndex].type == 2">多选题</text>
<text v-if="questions[questionsIndex].type == 3">判断题</text>
</view>
<!-- 题目 -->
<view class="answer-q">{{questions[questionsIndex].title}}</view>
<!-- 答案 -->
<view class="answer-list">
<!-- 对错/单选 -->
<block v-if="questions[questionsIndex].type == 1 || questions[questionsIndex].type == 3">
<radio-group @change="onAnswer">
<label
class="answer-item"
v-for="(item, index) in questions[questionsIndex].options"
:key="index"
:class="{'active': item.option_id == answerArr[questionsIndex].option_ids}"
>
<radio class="answer-checkbox" :value="item.option_id" />
<text class="answer-index">{{item.order.text}}.</text>
<view class="answer-text">{{item.title}}</view>
<view class="answer-icon">
<u-icon v-if="item.option_id == answerArr[questionsIndex].option_ids" name="checkbox-mark" size="38rpx" color="#446EFE"></u-icon>
</view>
</label>
</radio-group>
</block>
<!-- 多选题 -->
<block v-if="questions[questionsIndex].type == 2">
<checkbox-group @change="onAnswer">
<label
class="answer-item"
v-for="(item, index) in questions[questionsIndex].options"
:key="index"
:class="{'active': isAnswer(item.option_id, answerArr[questionsIndex], 2)}"
>
<checkbox class="answer-checkbox" :value="item.option_id"></checkbox>
<text class="answer-index">{{item.order.text}}.</text>
<view class="answer-text">{{item.title}}</view>
<view class="answer-icon">
<u-icon v-if="isAnswer(item.option_id, answerArr[questionsIndex], 2)" name="checkbox-mark" size="38rpx" color="#446EFE"></u-icon>
</view>
</label>
</checkbox-group>
</block>
</view>
</block>
<block v-else>
<view class="answer-loding">
<u-loading-icon mode="circle" text="加载中..."></u-loading-icon>
</view>
</block>
</view>
<!-- 答题卡 -->
<!-- answerShow -->
<u-popup :show="answerShow" closeable round @close="answerShow = false">
<view class="answer-lay-content">
<view class="answer-lay-title">答题卡</view>
<view class="answer-lay-flex">
<view class="answer-lay-flex-title">智能组卷客观一</view>
<view class="answer-lay-flex-text">
<text>未答题</text>
<text>已答题</text>
</view>
</view>
<scroll-view scroll-y style="height: 60vh;" v-if="answerArr.length > 0">
<view class="answer-lay-list">
<view class="answer-item" :class="{'active': item.option_ids != ''}" v-for="(item,index) in answerArr" :key="index">
<view class="number">{{index + 1}}</view>
</view>
</view>
</scroll-view>
</view>
</u-popup>
<!-- 下一题 -->
<view class="footer-flex" v-if="questions.length > 0">
<view class="footer-btn" @click="answerShow = true">
<u-icon class="footer-icon" name="order" size="48rpx" color="#111"></u-icon>
<view>答题卡</view>
</view>
<button class="footer-next" :disabled="answerArr[questionsIndex].option_ids == ''" @click="answerNext">{{(this.questionsIndex + 1) == this.questions.length ? '提交': '下一题'}}</button>
</view>
</view>
</template>
<script>
import { questions, answers } from "@/apis/interfaces/college.js"
export default {
data() {
return {
outTime : 0,
percentageVal : 0,
questionsIndex: 0,
questions : [],
answerArr : [],
answerShow : false,
isShowAnswer : true
};
},
computed: {
isAnswer(){
return (id, answer, type) => {
let optionIds = answer.option_ids || []
let isFindIndex = optionIds.findIndex(val => val == id)
return isFindIndex >= 0
}
}
},
created() {
this.outTime = this.$Route.query.time || 60
questions(this.$Route.query.id).then(res => {
this.questions = res;
this.percentageVal += Number((100 / res.length).toFixed())
this.answerArr = new Array(res.length).fill({question_id:'', option_ids:''})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods: {
// 选择答案
onAnswer(e){
let { value } = e.detail
this.$set(this.answerArr, this.questionsIndex, {
question_id: this.questions[this.questionsIndex].question_id,
option_ids : value
})
},
// 下一题
answerNext(type){
if(type != 'time'){
if(this.answerArr[this.questionsIndex] == '') return
if(this.questionsIndex < (this.questions.length - 1)){
this.isShowAnswer = false
setTimeout(() => {
this.questionsIndex++
this.percentageVal += Number((100 / this.questions.length).toFixed())
this.isShowAnswer = true
},200)
return
}
}
uni.showLoading({
title: '加载中...',
mask : true
})
answers(this.$Route.query.id, {
type : 2,
answers: this.answerArr
}).then(res => {
this.$Router.replace({
name: 'CollegeResults',
params: {
id: res.answer_id
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss">
.content{
background-color: $main-color;
padding-bottom: 200rpx;
}
// 加载题
.answer-loding{
height: 50vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
// 答题卡
.answer-lay-content{
.answer-lay-title{
line-height: 70rpx;
padding: 20rpx 30rpx;
border-bottom: solid 1rpx #F6F6F6;
font-size: 36rpx;
font-weight: bold;
}
.answer-lay-flex{
display: flex;
justify-content: space-between;
padding: 30rpx 30rpx 20rpx;
&-title{
font-size: 30rpx;
color: #111;
width: 50%;
@extend .nowrap;
}
&-text{
font-size: 30rpx;
width: 50%;
text-align: right;
text{
margin-left: 30rpx;
padding-left: 35rpx;
color: #333;
position: relative;
&::after{
position: absolute;
left: 0;
top: 50%;
margin-top: -12rpx;
height: 16rpx;
width: 16rpx;
content: " ";
border-radius: 50%;
background: $main-color;
border:solid 7rpx #E4E8F7;
}
&:first-child::after{
background-color: #999999;
border-color: #e7e7e7;
}
}
}
}
.answer-lay-list{
padding: 10rpx;
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: flex-start;
.answer-item{
width: calc(20% - 40rpx);
padding-top: calc(20% - 42rpx);
text-align: center;
border-radius: 50%;
background: white;
border:solid 1rpx #EEEEEE;
box-sizing: border-box;
position: relative;
margin: 20rpx;
color: #999999;
font-weight: bold;
.number{
position: absolute;
top: 50%;
left: 0;
margin-top: -22rpx;
line-height: 40rpx;
height: 40rpx;
font-size: 32rpx;
width: 100%;
height: 100%;
}
&.active{
background: #E4E8F7;
border-color: #E4E8F7;
color: $main-color;
}
}
}
}
// header
.answer-header{
padding: 20rpx 30rpx 50rpx;
.flex{
display: flex;
justify-content: space-between;
line-height: 60rpx;
align-items: center;
padding-bottom: 20rpx;
color: rgba(255, 255, 255, .7);
font-size: 30rpx;
.flex-item{
text{
color: white;
font-weight: bold;
font-size: 34rpx;
margin-left: 10rpx;
}
.flex-item-down{
display: inline-block;
}
}
}
}
// footer
.footer-flex{
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx 30rpx 50rpx;
background: white;
height: 90rpx;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 9;
.footer-next{
height: 90rpx;
line-height: 90rpx;
width: calc(100% - 150rpx);
background: $main-color;
border-radius: 45rpx;
color: white;
text-align: center;
font-size: 32rpx;
font-weight: bold;
padding: 0;
margin: 0;
&[disabled]{
opacity: .7;
background: $main-color;
color: white;
}
}
.footer-btn{
width: 100rpx;
text-align: center;
line-height: 30rpx;
font-size: 26rpx;
color: #111;
text-align: center;
.footer-icon{
display: inline-block;
}
}
}
// 答题卡
.block{
background: white;
border-radius: 20rpx;
margin: 0 30rpx 30rpx;
position: relative;
z-index: 2;
&::after{
content: " ";
width: 90%;
height: 100rpx;
background: rgba(255, 255, 255, .5);
position: absolute;
left: 5%;
bottom: -30rpx;
border-radius: 20rpx;
z-index: -1;
}
// 类型
.answer-type{
padding: 30rpx;
text{
background: $main-color;
color: white;
display: inline-block;
line-height: 50rpx;
height: 50rpx;
padding: 0 20rpx;
border-radius: 10rpx;
font-size: 28rpx;
}
}
// 题目
.answer-q{
padding: 0 30rpx;
font-size: 34rpx;
line-height: 50rpx;
color: #111;
}
// 答题
.answer-list{
padding: 30rpx;
.answer-item{
display: block;
background: #f8f8f8;
margin-bottom: 20rpx;
border-radius: 10rpx;
padding: 20rpx 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
.answer-checkbox{
width: 0;
height: 0;
position: absolute;
overflow: hidden;
}
.answer-index{
width: 50rpx;
height: 60rpx;
line-height: 60rpx;
display: block;
text-align: center;
font-size: 30rpx;
color: #111;
}
.answer-text{
width: calc(100% - 100rpx);
line-height: 40rpx;
font-size: 32rpx;
}
.answer-icon{
width: 50rpx;
text-align: right;
}
&.active{
color: #446EFE;
background: #E4E8F7;
.answer-index{
color: #446EFE;
}
}
}
}
}
</style>

536
pages/college/index.vue Normal file
View File

@@ -0,0 +1,536 @@
<template>
<view>
<!-- 状态栏 -->
<u-sticky bgColor="#FFFFFF">
<view class="status_bar"></view>
<view class="college-bar">
<view class="college-bar-title">商学院</view>
<view class="college-bar-input">
<navigator class="navigator" url="">
<image class="navigator-icon" src="@/static/icons/search_icon.png"></image>
搜索
</navigator>
</view>
<view class="college-bar-icons">
<u-icon class="icon" name="bell" color="#333" bold size="24"></u-icon>
</view>
</view>
</u-sticky>
<!-- 轮播图 -->
<view class="banner">
<view class="banner-swiper">
<u-swiper
class="uswiper"
height="100%"
indicator
radius="6"
bgColor="#fff"
indicatorMode="dot"
:list="bannerArr"
></u-swiper>
</view>
</view>
<!-- 快捷入口 -->
<view class="diamond-flex">
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_00.png" mode="widthFix"></image>
<view class="text">公开课</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_01.png" mode="widthFix"></image>
<view class="text">网授课</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_02.png" mode="widthFix"></image>
<view class="text">面授班</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_03.png" mode="widthFix"></image>
<view class="text">图书</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_04.png" mode="widthFix"></image>
<view class="text">优选课程</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_05.png" mode="widthFix"></image>
<view class="text">课表</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_06.png" mode="widthFix"></image>
<view class="text">全国分校</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_07.png" mode="widthFix"></image>
<view class="text">师资团队</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_08.png" mode="widthFix"></image>
<view class="text">法律法规</view>
</view>
<view class="diamond-item">
<image class="icon" src="@/static/icons/diamond_icon_09.png" mode="widthFix"></image>
<view class="text">增补勘误</view>
</view>
</view>
<!-- 快捷入口 -->
<view class="quick-flex">
<view class="quick-flex-item" :style="'background-image: url(' + require('@/static/imgs/quick_back_00.png') + ');'">
<view class="quick-colum">
<view class="quick-title">考试习题</view>
<view class="quick-sumit">海量学习包</view>
<image class="quick-icon" src="@/static/icons/quick_icon.png" mode="widthFix"></image>
</view>
</view>
<view class="quick-flex-item" :style="'background-image: url(' + require('@/static/imgs/quick_back_01.png') + ');'" @click="onNav('CollegeTest')">
<view class="quick-colum">
<view class="quick-title">考试</view>
<view class="quick-sumit">专业考试题</view>
<image class="quick-icon" src="@/static/icons/quick_icon.png" mode="widthFix"></image>
</view>
</view>
</view>
<!-- 热门网授课 -->
<view class="college-title">
<view class="college-title-text">热门网授课</view>
<navigator class="college-title-more" url="">
更多<u-icon class="college-title-icon" name="arrow-right" size="28rpx" color="#ADADAD"></u-icon>
</navigator>
</view>
<view class="hot">
<view class="hot-scroll">
<view class="hot-item" v-for="(item, index) in 3" :key="index">
<view class="cover">
<image src="@/static/imgs/hot_img.png" mode="aspectFill"></image>
</view>
<view class="title nowrap">2022年至尊先锋VIP班</view>
<view class="flex">
<view class="price nowrap"><text></text>2200</view>
<view class="number nowrap">1698人购买</view>
</view>
</view>
</view>
</view>
<!-- 名师面授班 -->
<view class="college-title">
<view class="college-title-text">名师面授班</view>
<navigator class="college-title-more" url="">
更多<u-icon class="college-title-icon" name="arrow-right" size="28rpx" color="#ADADAD"></u-icon>
</navigator>
</view>
<view class="famous">
<view class="famous-item" v-for="(item, index) in 3" :key="index">
<image class="famous-cover" src="@/static/imgs/famous_img.png" mode="aspectFill"></image>
<view class="famous-content">
<view class="title nowrap">e学主客一体延考上岸班上海</view>
<view class="number nowrap">2028人报名</view>
<view class="price nowrap"><text></text>2200</view>
</view>
</view>
</view>
<!-- 热销图书 -->
<view class="college-title">
<view class="college-title-text">热销图书</view>
<navigator class="college-title-more" url="">
更多<u-icon class="college-title-icon" name="arrow-right" size="28rpx" color="#ADADAD"></u-icon>
</navigator>
</view>
<view class="new-book">
<view class="new-book-item" v-for="(item, index) in 4" :key="index">
<view class="cover">
<image src="@/static/imgs/new_book.png" mode="aspectFill"></image>
</view>
<view class="new-content">
<view class="title nowrap">2022年客观题精讲8...</view>
<view class="flex">
<view class="price"><text></text>2200</view>
<view class="number">1698人购买</view>
</view>
</view>
</view>
</view>
<!-- 法考资讯 -->
<view class="college-title">
<view class="college-title-text">法考资讯</view>
<navigator class="college-title-more" url="">
更多<u-icon class="college-title-icon" name="arrow-right" size="28rpx" color="#ADADAD"></u-icon>
</navigator>
</view>
<view class="news-lists">
<view class="news-lists-item" v-for="(item, index) in 3" :key="index">
<view class="text">
<view class="title">法律服务工作者</view>
<view class="submit">2028人浏览</view>
</view>
<image class="cover" src="@/static/imgs/news_img.png" mode="aspectFill"></image>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bannerArr: [
'https://cdn.uviewui.com/uview/swiper/swiper3.png',
'https://cdn.uviewui.com/uview/swiper/swiper2.png',
'https://cdn.uviewui.com/uview/swiper/swiper1.png',
]
};
},
methods: {
onNav(e) {
this.$Router.push({
name: e
})
}
},
}
</script>
<style lang="scss" scoped>
// 热门课程
.hot{
padding: 20rpx 0 30rpx;
.hot-scroll{
overflow-x: scroll;
white-space:nowrap;
.hot-item{
display: inline-block;
margin-left: 30rpx;
width: 40vw;
&:last-child{
margin-right: 30rpx;
}
.cover{
width: 100%;
padding-top: 67%;
position: relative;
border-radius: $radius-lg;
overflow: hidden;
image{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.title{
padding-top: 20rpx;
line-height: 40rpx;
color: #111111;
}
.flex{
display: flex;
align-items: center;
line-height: 40rpx;
padding-top: 10rpx;
.price{
width: 50%;
color: $text-price;
font-weight: bold;
font-size: 32rpx;
text{
font-size: 80%;
}
}
.number{
width: 50%;
text-align: right;
font-size: 26rpx;
color: #999999;
}
}
}
}
}
// 名师课程班
.famous{
padding: 20rpx 30rpx 0;
.famous-item{
margin-bottom: 30rpx;
display: flex;
flex-wrap: wrap;
.famous-cover{
width: 160rpx;
height: 160rpx;
border-radius: $radius;
overflow: hidden;
}
.famous-content{
width: calc(100% - 160rpx);
padding-left: 30rpx;
box-sizing: border-box;
.title{
line-height: 40rpx;
font-weight: 400;
}
.number{
margin-top: 10rpx;
font-size: 26rpx;
line-height: 40rpx;
color: #999999;
}
.price{
padding-top: 30rpx;
line-height: 40rpx;
font-weight: bold;
color: $text-price;
font-size: 32rpx;
text{
font-size: 80%;
}
}
}
}
}
// 热销图书
.new-book{
padding: 20rpx 15rpx 20rpx;
display: flex;
flex-wrap: wrap;
&-item{
width: calc(50% - 30rpx);
margin: 0 15rpx 30rpx;
background: white;
box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, .02);
border-radius: $radius;
.cover{
position: relative;
width: 100%;
padding-top: 67%;
overflow: hidden;
border-radius: $radius;
image{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.new-content{
padding: 20rpx;
.title{
font-size: 32rpx;
padding-bottom: 10rpx;
line-height: 40rpx;
}
.flex{
display: flex;
justify-content: space-between;
align-items: center;
line-height: 40rpx;
.price{
width: 50%;
text-align: left;
font-size: 32rpx;
font-weight: bold;
color: $text-price;
text{
font-size: 80%;
}
}
.number{
width: 50%;
text-align: right;
font-size: 26rpx;
color: gray;
}
}
}
}
}
// 法考资讯
.news-lists{
padding-bottom: 30rpx;
&-item{
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
.text{
display: flex;
flex-direction: column;
justify-content: space-between;
width: calc(100% - 200rpx);
.title{
font-size: 32rpx;
color: #111111;
line-height: 50rpx;
@extend .ellipsis;
}
.submit{
line-height: 40rpx;
font-size: 28rpx;
color: #999999;
}
}
.cover{
width: 200rpx;
height: 133rpx;
border-radius: $radius;
}
}
}
// 通用标题
.college-title{
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
&-text{
font-weight: bold;
font-size: 36rpx;
color: #111111;
}
&-more{
background: #F5F5F5;
font-size: 28rpx;
color: #999999;
height: 50rpx;
line-height: 50rpx;
padding: 0 15rpx 0 25rpx;
border-radius: 25rpx;
}
.college-title-icon{
display: inline-block;
vertical-align: middle;
margin-top: -8rpx;
}
}
// 快捷入口
.quick-flex{
padding: 20rpx 15rpx 30rpx;
display: flex;
&-item{
position: relative;
width: calc(50% - 30rpx);
padding-top: calc(24% - 10rpx);
background-size: cover;
border-radius: $radius;
margin: 0 15rpx;
.quick-colum{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
color: white;
.quick-title{
font-weight: bold;
font-size: 32rpx;
@extend .nowrap;
}
.quick-sumit{
font-size: 24rpx;
@extend .nowrap;
}
.quick-icon{
margin-top: 10rpx;
width: 26rpx;
}
}
}
}
// 金刚区
.diamond-flex{
padding: 20rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.diamond-item{
width: 20%;
padding: 20rpx 10rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.icon{
width: 70rpx;
height: 70rpx;
}
.text{
padding-top: 15rpx;
color: #111111;
font-size: 28rpx;
@extend .nowrap;
}
}
}
// 轮播图
.banner{
padding: 10rpx 30rpx;
.banner-swiper{
width: 100%;
padding-top: 43%;
position: relative;
overflow: hidden;
.uswiper{
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
}
// 自定义状态栏
.college-bar{
height: 44px;
padding: 5px 30rpx 9px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
&-title{
width: 150rpx;
font-weight: bold;
line-height: 30px;
color: #111111;
font-size: 36rpx;
@extend .nowrap;
}
&-input{
height: 30px;
width: calc(100% - 210rpx);
margin: 0 $margin;
.navigator{
position: relative;
width: 100%;
box-sizing: border-box;
display: inline-block;
background: #F6F6F6;
height: 30px;
line-height: 30px;
border-radius: 15px;
padding: 0 50rpx 0 60rpx;
color: #999999;
font-size: 30rpx;
text-align: center;
.navigator-icon{
position: absolute;
left: 20rpx;
top: 50%;
width: 36rpx;
height: 36rpx;
margin-top: -18rpx;
}
}
}
&-icons{
width: 60rpx;
text-align: right;
.icon{
display: inline-block;
}
}
}
</style>

110
pages/college/test.vue Normal file
View File

@@ -0,0 +1,110 @@
<template>
<view class="content">
<block v-for="(item, index) in testArr" :key="index">
<view class="block">
<image class="icon" v-if="item.answer.is_finish" src="@/static/icons/test_icon.png" mode="widthFix"></image>
<view class="title">{{item.title}}</view>
<view class="text">考试时间{{item.time}}分钟</view>
<view class="text">试卷满分{{item.questions.all.score}}</view>
<view class="text">及格分数{{item.total}}</view>
<view class="submit">
<view class="submit-item" v-if="item.questions.radio.count > 0">·单选{{item.questions.radio.count}}道题每道题{{item.questions.radio.score}}</view>
<view class="submit-item" v-if="item.questions.multi.count > 0">·多选{{item.questions.multi.count}}每道题{{item.questions.multi.score}}</view>
<view class="submit-item" v-if="item.questions.yesno.count > 0">·判断题{{item.questions.yesno.count}}每道题{{item.questions.yesno.score}}</view>
<view class="submit-item">·倒计时结束后系统将提示交卷</view>
</view>
<view class="btns">
<button @click="$Router.push({name: 'CollegeResults', params: {id: item.answer.last_answer_id}})" v-if="item.answer.is_finish">查看成绩</button>
<button @click="$Router.push({name: 'CollegeAnswer', params: {id: item.evaluation_id}})" v-else>开始答题</button>
</view>
</view>
</block>
</view>
</template>
<script>
import { evaluations } from '@/apis/interfaces/college.js'
export default {
data() {
return {
testArr: []
};
},
onShow(){
evaluations().then(res => {
this.testArr = res
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
</script>
<style lang="scss">
.content{
padding-top: 1rpx;
}
.block{
margin: 40rpx 30rpx;
background: white;
border-radius: $radius;
padding: $padding;
position: relative;
.icon{
width: 168rpx;
height: 168rpx;
position: absolute;
right: 50rpx;
top: 50rpx;
opacity: .5;
}
.title{
position: relative;
line-height: 50rpx;
font-size: 36rpx;
margin-bottom: 30rpx;
color: #111111;
&::after{
position: absolute;
content: " ";
height: 50rpx;
left: -30rpx;
top: 0;
background: $main-color;
width: 8rpx;
}
}
.text{
font-size: 32rpx;
line-height: 40rpx;
margin-top: 10rpx;
color: #111111;
}
.submit{
margin-top: 30rpx;
padding-top: 20rpx;
border-top: solid 1rpx #F6F6F6;
.submit-item{
line-height: 40rpx;
margin-top: 10rpx;
font-size: 28rpx;
color: #999999;
}
}
.btns{
padding-top: 50rpx;
button{
background: $main-color;
color: white;
border-radius: $radius-lg;
height: 100rpx;
line-height: 100rpx;
font-size: 34rpx;
&::after{border: none;}
}
}
}
</style>

View File

@@ -0,0 +1,286 @@
<template>
<view>
<block v-if="title != ''">
<view class="header"></view>
<!-- 分数 -->
<view class="results">
<view class="results-title">
<block v-if="isAnswer">
<image src="/static/CollegeResults/CollegeResults_icon_00.png" mode="widthFix"></image>恭喜您考试通过了~
</block>
<block v-else>
<image src="/static/CollegeResults/CollegeResults_icon_01.png" mode="widthFix"></image>未通过请再接再厉~
</block>
</view>
<view class="results-flex">
<view class="results-flex-item">
<view class="results-flex-number">{{total}}<text></text></view>
<view class="results-flex-text">考试分数</view>
</view>
<view class="results-flex-item">
<view class="results-flex-number">{{accuracy}}<text>%</text></view>
<view class="results-flex-text">正确率</view>
</view>
</view>
<view class="results-footer">
<text>{{title}}(满分{{allTotal}})</text>
</view>
</view>
<!-- 答题概况 -->
<view class="situation-flex">
<view class="situation-item">
<view class="situation-val">{{count}}</view>
<view class="situation-text">题目数量</view>
</view>
<view class="situation-item">
<view class="situation-val">{{created}}</view>
<view class="situation-text">考试日期</view>
</view>
</view>
<!-- 答题情况 -->
<view class="instructions">
<view class="instructions-center">
<text>正确</text>
<text>错误</text>
</view>
<!-- instructions -->
<view class="instructions-flex">
<view class="instructions-item" :class="{'active': isWrong(item)}" v-for="(item, index) in count" :key="index">
<view class="number">{{item}}</view>
</view>
</view>
</view>
<!-- 按钮 -->
<view class="btns">
<button size="default" @click="onBack">返回</button>
</view>
</block>
</view>
</template>
<script>
import { report } from "@/apis/interfaces/college.js"
export default {
data() {
return {
isAnswer: false,
title : '',
total : '',
allTotal: '',
accuracy: '',
count : '',
created : '',
wrong : '',
};
},
computed: {
isWrong(){
return (e) => {
return this.wrong.findIndex(val => val == e) >= 0;
}
}
},
created() {
report(this.$Route.query.id).then(res => {
let { title, total, veidoos, created_at, isAnswer } = res;
this.isAnswer = isAnswer;
this.title = title;
this.total = total;
this.created = created_at;
this.count = veidoos.count.all
this.accuracy = (veidoos.count.accuracy).substring(0, (veidoos.count.accuracy).length - 1);
this.allTotal = veidoos.allTotal;
this.wrong = veidoos.wrong;
}).catch(err => {
console.log(err)
uni.showToast({
title: err.message,
icon : "none"
})
})
},
methods: {
onBack(){
this.$Router.back()
}
}
}
</script>
<style lang="scss">
.header{
background-image: url('/static/CollegeResults/CollegeResults_back.png');
background-position: top center;
background-size: cover;
padding: 30rpx 30rpx 0;
height: 300rpx;
}
// 按钮
.btns{
padding: 0 30rpx 50rpx;
box-sizing: border-box;
button[size="default"]{
height: 100rpx;
line-height: 100rpx;
border-radius: $radius-lg;
background: $main-color;
color: white;
font-size: 32rpx;
&::after{
display: none;
}
}
}
// 答题情况
.instructions{
padding: 0 30rpx 30rpx;
.instructions-center{
padding-bottom: 30rpx;
text-align: center;
font-size: 28rpx;
color: #111;
text{
margin: 0 30rpx;
padding-left: 35rpx;
color: #333;
position: relative;
line-height: 70rpx;
&::after{
position: absolute;
left: 0;
top: 50%;
margin-top: -12rpx;
height: 16rpx;
width: 16rpx;
content: " ";
border-radius: 50%;
background: $main-color;
border:solid 7rpx #E4E8F7;
}
&:last-child::after{
background-color: #FF4D4D;
border-color: #F7E4E4;
}
}
}
.instructions-flex{
margin: 0 -20rpx;
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: flex-start;
.instructions-item{
width: calc(20% - 40rpx);
padding-top: calc(20% - 42rpx);
text-align: center;
border-radius: 50%;
background: #E4E8F7;
box-sizing: border-box;
position: relative;
margin: 20rpx;
color: #446EFE;
font-weight: bold;
.number{
position: absolute;
top: 50%;
left: 0;
margin-top: -22rpx;
line-height: 40rpx;
height: 40rpx;
font-size: 32rpx;
width: 100%;
height: 100%;
}
&.active{
background: #F7E4E4;
color: #FF4D4D;
}
}
}
}
// 考试概况
.situation-flex{
background: #F6F6F6;
padding: 30rpx;
border-radius: $radius;
margin: 30rpx;
display: flex;
.situation-item{
text-align: center;
width: 50%;
box-sizing: border-box;
&:last-child{
border-left: solid 1rpx #ddd;
}
.situation-val{
font-weight: bold;
color: #111111;
font-size: 34rpx;
line-height: 50rpx;
}
.situation-text{
color: #999999;
font-size: 28rpx;
line-height: 40rpx;
}
}
}
// 考试结果
.results{
background-color: white;
border-radius: $radius;
margin: -300rpx 30rpx 0;
box-shadow: 0 0 15rpx 15rpx rgba(0, 0, 0, .02);
padding: 50rpx 30rpx;
box-sizing: border-box;
.results-title{
font-weight: bold;
font-size: 36rpx;
text-align: center;
line-height: 90rpx;
image{
width: 68rpx;
height: 68rpx;
vertical-align: middle;
margin-right: 10rpx;
}
}
.results-flex{
display: flex;
justify-content: space-between;
padding-top: 30rpx;
padding-bottom: 20rpx;
.results-flex-item{
width: 50%;
text-align: center;
.results-flex-number{
color: $main-color;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
font-size: 50rpx;
text{
font-size: 30rpx;
padding-left: 10rpx;
}
}
.results-flex-text{
font-size: 28rpx;
color: #111111;
}
}
}
.results-footer{
text-align: center;
padding-top: 30rpx;
text{
display: inline-block;
background: #F6F6F6;
height: 70rpx;
border-radius: 40rpx;
line-height: 70rpx;
padding: 0 50rpx;
font-size: 28rpx;
}
}
}
</style>

328
pages/index/index.vue Normal file
View File

@@ -0,0 +1,328 @@
<template>
<view class="content">
<!-- <video src="https://t12.cdn2020.com:12337/video/m3u8/2021/10/11/d647a87d/index.m3u8"></video> -->
<view class="header">
<view class="banner">
<u-swiper
class="banner-swiper"
:list="bannerArr"
:indicator="true"
previousMargin="20"
nextMargin="20"
circular
radius="10"
bgColor="#ffffff"
height="100%"
></u-swiper>
</view>
<view class="notice">
<view class="notice-title">
<image class="notice-icon" src="@/static/imgs/notice-icon.png" mode="widthFix"></image>公告
</view>
<u-notice-bar
icon=""
:text="notice"
direction="column"
bgColor="#fff"
color="#111111"
></u-notice-bar>
<view class="notice-more">更多<u-icon class="more-icon" size="28rpx" color="#999" name="arrow-right"></u-icon></view>
</view>
</view>
<!-- 自由服务包 -->
<view class="free">
<image class="free-img" src="@/static/imgs/index-img.png" mode="widthFix"></image>
</view>
<!-- 经法产品 -->
<view class="block">
<view class="block-title">
<view class="title">经法产品</view>
<view class="more">更多<u-icon class="more-icon" size="28rpx" color="#999" name="arrow-right"></u-icon></view>
</view>
<view class="the-tabs">
<block v-for="(item, index) in theTabs" :key="index">
<view class="the-tabs-item" :class="{'active': item.id == theTabId}" @click="onTheTab(item)">{{item.title}}</view>
</block>
<view class="the-tabs-acitve-block" :style="theTabStyle"></view>
</view>
<view class="the-flex">
<view class="the-flex-item" v-for="(item, index) in 3" :key="index">
<view class="cover"></view>
<view class="title nowrap">中国工商信用卡服务...</view>
<view class="price nowrap"><text></text>2200</view>
</view>
</view>
</view>
<!-- 综法产品 -->
<view class="block">
<view class="block-title">
<view class="title">综法产品</view>
<view class="more">更多<u-icon class="more-icon" size="28rpx" color="#999" name="arrow-right"></u-icon></view>
</view>
<view class="zong-list">
<view class="zong-list-item" v-for="(item, index) in 4" :key="index">
<image class="cover" src="@/static/imgs/index-pack-01.png" mode="aspectFill"></image>
<view class="colum-flex">
<view class="title nowrap">2022年尊享综法服务包</view>
<view class="price nowrap"><text></text>2200</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { region } from '@/apis/interfaces/address.js'
export default {
data() {
return {
theTabs : [
{ id: 1, title: '全部' },
{ id: 2, title: '信用卡' },
{ id: 3, title: '网贷' },
{ id: 4, title: '信用贷' },
],
theTabId : 1,
theTabStyle : {
left: '0%'
},
bannerArr : [
'https://cdn.uviewui.com/uview/swiper/swiper1.png',
'https://cdn.uviewui.com/uview/swiper/swiper2.png',
'https://cdn.uviewui.com/uview/swiper/swiper3.png',
],
notice : [
'王**信用卡法务咨询办理成功(今日)',
'王**信用卡法务咨询办理成功(今日)',
'王**信用卡法务咨询办理成功(今日)',
]
}
},
onLoad() {
},
methods: {
// 选择城市节点
onCityPicker(e){
console.log(e)
this.getRegion(e.value);
},
// 获取城市数据
getRegion(id){
region({
parent_id: id
}).then(res => {
console.log(res)
})
},
// 经法产品筛选
onTheTab(e){
if(e.id != this.theTabId){
let index = this.theTabs.findIndex(val => val.id === e.id)
this.theTabStyle = {
left: index * (100 / this.theTabs.length) + '%'
}
this.theTabId = e.id
}
}
}
}
</script>
<style lang="scss" scoped>
.header{
background-color: white;
padding-top: 20rpx;
}
// 轮播图
.banner{
position: relative;
width: 100%;
padding-top: 43%;
.banner-swiper{
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
// 轮播
.notice{
background: white;
padding: $padding;
display: flex;
flex-direction: row;
align-items: center;
.notice-title{
background-color: #ECF0FF;
color: #446EFE;
height: 60rpx;
line-height: 60rpx;
width: 130rpx;
text-align: center;
font-size: 28rpx;
font-weight: bold;
border-radius: 20rpx;
.notice-icon{
width: 32rpx;
vertical-align: middle;
margin-bottom: 8rpx;
margin-right: 5rpx;
display: inline-block;
}
}
.notice-more{
font-size: 14px;
height: 50rpx;
border-radius: 25rpx;
box-sizing: border-box;
line-height: 50rpx;
text-align: center;
color: #999999;
.more-icon{
display: inline-block;
}
}
}
// 自由服务包
.free{
padding: $padding;
.free-img{
width: 100%;
}
}
// 综法
.zong-list{
padding: 0 $padding 20rpx;
margin-bottom: 30rpx;
&-item{
position: relative;
margin-bottom: 30rpx;
padding-left: 210rpx;
height: 180rpx;
.cover{
position: absolute;
left: 0;
top: 0;
width: 180rpx;
height: 180rpx;
}
.colum-flex{
display: flex;
flex-direction: column;
justify-content: space-around;
height: 180rpx;
.title{
line-height: 40rpx;
font-size: 32rpx;
color: #111111;
}
.price{
line-height: 40rpx;
font-weight: bold;
color: $text-price;
font-size: 34rpx;
text{
font-size: 80%;
}
}
}
}
}
// 经法
.the-tabs{
background: #ECF0FF;
margin: 0 $margin;
height: 70rpx;
border-radius: 35rpx;
display: flex;
position: relative;
&-item{
position: relative;
z-index: 2;
width: 25%;
line-height: 70rpx;
text-align: center;
font-size: 28rpx;
color: #999999;
transition: all .4s;
&.active{
color: white;
}
}
&-acitve-block{
width: 25%;
height: 70rpx;
background: #446EFE;
border-radius: 35rpx;
position: absolute;
left: 0;
transition: all .4s;
}
}
.the-flex{
padding: $padding 20rpx;
display: flex;
flex-direction: row;
&-item{
width: calc(33.33% - 20rpx);
margin: 0 10rpx;
.cover{
width: 100%;
padding-top: 100%;
background: #f8f8f8;
border-radius: 10rpx;
margin-bottom: 10rpx;
}
.title{
font-size: 32rpx;
color: #111111;
padding: 10rpx 0;
line-height: 40rpx;
}
.price{
line-height: 40rpx;
font-weight: bold;
color: $text-price;
font-size: 34rpx;
text{
font-size: 80%;
}
}
}
}
// 模块
.block{
background-color: white;
border-radius: $radius;
margin: 0 $margin $margin;
.block-title{
padding: 0 $padding;
height: 100rpx;
display: flex;
justify-content: space-between;
align-items: center;
.title{
font-weight: bold;
color: #111111;
font-size: 36rpx;
}
.more{
background-color: #F5F5F5;
font-size: 28rpx;
height: 50rpx;
border-radius: 25rpx;
width: 120rpx;
padding-left: 10rpx;
box-sizing: border-box;
line-height: 50rpx;
text-align: center;
color: #999999;
.more-icon{
display: inline-block;
}
}
}
}
</style>

230
pages/pay/pay.vue Normal file
View File

@@ -0,0 +1,230 @@
<template>
<view class="pay">
<!-- 支付金额 -->
<view class="header">
<view class="header-title">实付金额</view>
<view class="header-price"><text></text>{{total}}</view>
<view class="header-no">订单号:{{orderNo}}</view>
</view>
<!-- 选择支付方式 -->
<view class="choose">
<radio-group @change="payMethod = $event.detail.value">
<label class="choose-item">
<view class="choose-text nowrap">
<image src="@/static/icons/pay_alipay.png" mode="aspectFill"></image>
火力值支付
</view>
<radio class="choose-radio" value="coin" checked></radio>
</label>
<label class="choose-item nowrap">
<view class="choose-text">
<image src="@/static/icons/pay_code.png" mode="aspectFill"></image>
付款码支付
</view>
<radio class="choose-radio" value="code"></radio>
</label>
<label class="choose-item nowrap">
<view class="choose-text">
<image src="@/static/icons/pay_wechat.png" mode="aspectFill"></image>
微信支付
</view>
<radio class="choose-radio" value="wx"></radio>
</label>
</radio-group>
</view>
<!-- 确认支付 -->
<view class="payBtn">
<button size="default" @click="onPay">支付</button>
</view>
</view>
</template>
<script>
import { info } from '@/apis/interfaces/order.js'
import { coinPay, diffCoinPay } from '@/apis/interfaces/pay.js'
export default {
data() {
return {
orderId : '',
diffId : '',
payMethod : 'coin',
payType : 'price',
total : '0.00',
orderNo : ''
};
},
created() {
uni.showLoading({
title: '获取订单信息...',
mask : true
})
info(this.$Route.query.orderId).then(res => {
let { total, order_no, business_order_id, diff_prices, diff } = res
this.orderId = business_order_id
this.diffId = diff.business_order_diff_price_id
this.payType = this.$Route.query.paytype
this.total = this.payType === 'diff' ? diff_prices: total
this.orderNo = order_no
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods: {
// 支付方式
onPay(){
switch(this.payMethod){
case 'coin':
if(this.payType == 'price') this.onCoinPay()
if(this.payType == 'diff') this.onDiffCoinPay()
break;
case 'code':
uni.showToast({
title: '付款码支付暂未开放,请敬期待',
icon : 'none'
})
break;
case 'wx':
uni.showToast({
title: '微信支付暂未开放,请敬期待',
icon : 'none'
})
break;
}
},
// 火力值支付
onCoinPay(){
wx.showLoading({
title: '支付中...',
mask : true
})
console.log(this.orderId)
coinPay(this.orderId).then(res => {
wx.showModal({
title : '提示',
content : '待缴费成功,请提醒用户尽快签约并完善资料',
showCancel : false,
confirmColor: '#446EFE',
success : () => {
this.onRrmoveItem()
}
})
}).catch(err => {
console.log(err)
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 活力值补差价支付
onDiffCoinPay(){
diffCoinPay(this.diffId).then(res => {
wx.showModal({
title : '提示',
content : '补缴差价成功',
showCancel : false,
confirmColor: '#446EFE',
success : () => {
this.onRrmoveItem()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 更新订单列表
onRrmoveItem(){
this.$store.commit('setOrderId', this.orderId)
this.$Router.back()
}
}
}
</script>
<style lang="scss">
.pay{
background: #f8f8f8;
height: 100vh;
width: 100vw;
padding: 30rpx 30rpx 60rpx;
box-sizing: border-box;
.header{
padding: 80rpx 0 100rpx;
text-align: center;
.header-title{
font-size: 32rpx;
padding-bottom: 10rpx;
}
.header-price{
font-size: 68rpx;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
text{
font-size: 60%;
}
}
.header-no{
padding-top: 20rpx;
font-size: 28rpx;
color: gray;
}
}
// 选择支付方式
.choose{
background-color: white;
border-radius: 20rpx;
padding: 10rpx 30rpx;
.choose-item{
display: block;
padding: 20rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
&:last-child{
border-bottom: none;
}
.choose-text{
line-height: 80rpx;
font-size: 32rpx;
padding-left: 80rpx;
position: relative;
image{
position: absolute;
left: 0;
top: 15rpx;
width: 50rpx;
height: 50rpx;
border-radius: 10rpx;
}
}
.choose-radio{
transform:scale(0.8)
}
}
}
// 按钮
.payBtn{
padding: 50rpx 0;
button[size="default"]{
height: 100rpx;
line-height: 100rpx;
padding: 0;
border-radius: 20rpx;
background-color: $main-color;
color: white;
font-size: 32rpx;
font-weight: bold;
&::after{
display: none;
}
}
}
}
</style>

View File

@@ -0,0 +1,25 @@
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
created() {
console.log(this.$Route.query.id)
uni.setNavigationBarTitle({
title: '服务协议'
})
}
}
</script>
<style lang="scss">
</style>

320
pages/transfers/lists.vue Normal file
View File

@@ -0,0 +1,320 @@
<template>
<view class="content">
<!-- tabs -->
<u-sticky bgColor="#FFF" zIndex="9" >
<u-tabs
:current="tabsCurrent"
:list="tabs"
:scrollable="false"
lineColor="#446EFE"
:activeStyle="{
color: '#111',
fontWeight: 'bold',
fontSize: '32rpx'
}"
:inactiveStyle="{
color: '#606266',
fontSize: '30rpx'
}"
@click="onTabs"
></u-tabs>
</u-sticky>
<!-- 订单管理列表 -->
<view class="orders" v-if="orders.length > 0">
<view class="orders-item" v-for="(item, index) in orders" :key="index">
<view class="orders-flex">
<view class="no nowrap">{{item.order.order_no}}</view>
<view class="state">{{item.status.text}}</view>
</view>
<view class="orders-content">
<view class="orders-content-item">
<label>业务类型</label>
<view class="nowrap orders-content-type">
<text v-for="(itemType, indexType) in item.order.item_type" :key="indexType" v-if="itemType.number > 0">{{itemType.title}}x{{itemType.number}}</text>
</view>
</view>
<view class="orders-content-block">
<view class="item-flex" v-for="(citem, cindex) in item.order.items" :key="cindex">
<view class="item-flex-title">{{citem.institution.title}}</view>
<view class="item-flex-value">{{citem.price}}</view>
</view>
</view>
<view class="orders-content-item" v-if="item.order.total > 0">
<label>咨询服务费</label>
<view class="nowrap">{{item.order.total}}</view>
</view>
<view class="orders-content-item">
<label>下单时间</label>
<view class="nowrap">{{item.created_at}}</view>
</view>
</view>
<view class="orders-flex">
<view class="user">
<image class="user-cover" :src="item.to.avatar" mode="aspectFill"></image>
<view class="user-name">{{item.to.nickname}}</view>
</view>
<view class="btns">
<block v-if="type == 'in' && tabsCurrent == 0">
<view class="btns-item btns-red" @click="onRefused(item.business_order_id)">拒绝</view>
<view class="btns-item btns-border" @click="onAgree(item.business_order_id)">接收</view>
</block>
<view class="btns-item" @click="$Router.push({name: 'OrderInfo', params: {orderId: item.business_order_id}})">查看</view>
</view>
</view>
</view>
</view>
<!-- 订单是空的 -->
<view class="order-null" v-else>
<u-empty
mode="order"
icon="http://cdn.uviewui.com/uview/empty/order.png"
text="暂无相关订单"
>
</u-empty>
</view>
</view>
</template>
<script>
import { lists, transferAgree, transferRefuse } from '@/apis/interfaces/transfers.js'
export default {
data() {
return {
tabsCurrent : 0,
type : 'in',
tabs : [
{val: 1, name: '转让中'},
{val: 3, name: '已转让'},
{val: 2, name: '转让失败'},
],
orders : []
};
},
created() {
this.type = this.$Route.query.type;
this.getList()
},
methods: {
// 切换列表
onTabs(e){
this.tabsCurrent = e.index
this.getList()
},
// 变更当前列表状态
removeListVal(id){
let ListArr = this.orders
let ListIndex = ListArr.findIndex(val => val.business_order_id == id)
if(ListIndex >= 0){
this.orders.splice(ListIndex, 1)
}
this.$store.commit('setOrderId', null)
},
// 接收订单
onAgree(id){
uni.showModal({
title : '接收提醒',
content : '确认接收该订单嘛?',
confirmText : '接收',
success : ModalRes => {
uni.showLoading({
title: '加载中...',
mask : true
})
if(ModalRes.confirm){
transferAgree(id).then(res => {
uni.showToast({
title: res
})
// 移出操作后的订单
this.removeItem(id)
})
}
}
})
},
// 拒绝订单
onRefused(id){
uni.showModal({
title : '接收提醒',
content : '确认接收该订单嘛?',
confirmText : '拒绝',
success : ModalRes => {
if(ModalRes.confirm){
transferRefuse(id).then(res => {
uni.showToast({
title: res
})
// 移出操作后的订单
this.removeItem(id)
})
}
}
})
},
// 更新转让单
removeItem(id){
let index = this.orders.findIndex(val => val.business_order_id == id)
if(index >= 0){
this.orders.splice(index, 1)
}
},
// 获取列表
getList(){
lists({
status: this.tabs[this.tabsCurrent].val,
type : this.type
}).then(res => {
let { data } = res;
this.orders = data
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
// 订单为空
.order-null{
height: 80vh;
display: flex;
justify-content: center;
align-items: center;
}
// 订单列表
.orders{
padding: 30rpx 0 10rpx;
.orders-item{
margin: 0 30rpx 20rpx;
background-color: white;
border-radius: $radius;
}
.orders-content{
padding: 20rpx 30rpx;
&-item{
line-height: 70rpx;
display: flex;
justify-content: space-between;
font-size: 30rpx;
color: #111111;
label{
color: #999999;
}
}
&-type{
text{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
}
&-block{
background: rgba(68, 110, 254, .03);
padding: 20rpx;
font-size: 28rpx;
border-radius: 10rpx;
margin: 10rpx 0;
.item-flex{
display: flex;
justify-content: space-between;
line-height: 50rpx;
}
}
}
.orders-flex{
border-bottom: solid 1rpx #F6F6F6;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx $padding;
&:last-child{
border-top: solid 1rpx #F6F6F6;
border-bottom: none;
}
.no{
font-size: 30rpx;
color: #111;
line-height: 60rpx;
width: calc(100% - 230rpx);
}
.state{
color: $main-color;
font-weight: bold;
font-size: 30rpx;
line-height: 60rpx;
width: 200rpx;
text-align: right;
}
.user{
padding-left: 90rpx;
position: relative;
min-height: 70rpx;
box-sizing: border-box;
width: calc(100% - 400rpx);
.user-cover{
position: absolute;
left: 0;
top: 0;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: #ddd;
}
.user-name{
line-height: 70rpx;
font-size: 30rpx;
font-weight: bold;
}
}
.btns{
width: 400rpx;
text-align: right;
.btns-item{
display: inline-block;
height: 70rpx;
line-height: 70rpx;
background: $main-color;
color: white;
border-radius: 35rpx;
padding: 0 30rpx;
font-size: 28rpx;
&.btns-border{
line-height: 66rpx;
box-sizing: border-box;
border:solid 1rpx $main-color;
background: white;
color: $main-color;
margin-right: 20rpx;
}
&.btns-red{
line-height: 66rpx;
box-sizing: border-box;
border:solid 1rpx red;
background: white;
color: red;
margin-right: 20rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,284 @@
<template>
<view>
<block v-if="!eSign">
<!-- 上传身份证 -->
<view class="identity-title">请拍摄并上传你的身份证照片</view>
<view class="identity-flex">
<view class="identity-item" @click="updImg('frontCard')">
<view class="upd" style="background-image: url('/static/imgs/card_front.png');">
<image v-if="frontCard.showpath != ''" :src="frontCard.showpath" class="idcardImg-img" mode="aspectFit"></image>
</view>
<view class="text">拍摄正面</view>
</view>
<view class="identity-item" @click="updImg('backCard')">
<view class="upd" style="background-image: url('/static/imgs/card_verso.png');">
<image v-if="backCard.showpath != ''" :src="backCard.showpath" class="idcardImg-img" mode="aspectFit"></image>
</view>
<view class="text">拍摄反面</view>
</view>
</view>
</block>
<!-- 身份证信息 -->
<view class="identity-from" v-if="realData.name != ''">
<view class="identity-inpus">
<label>真实姓名</label>
<input type="text" placeholder="-" v-model="realData.name" disabled>
</view>
<view class="identity-inpus">
<label>身份证号</label>
<input type="idcard" placeholder="-" v-model="realData.id_card" disabled>
</view>
<view class="identity-inpus">
<label>户籍地</label>
<input type="idcard" placeholder="-" v-model="realData.organ" disabled>
</view>
</view>
<!-- 按钮 -->
<view class="btn" v-if="!eSign">
<button size="default" @click="idCard && !isPathChange ? getSignUrl(): realInfo()">{{idCard && !isPathChange ? '人脸认证': '提交身份信息'}}</button>
</view>
</view>
</template>
<script>
import { certification, identityOcr, certified, eSigns } from '@/apis/interfaces/user'
import { uploads } from '@/apis/interfaces/uploading'
export default {
data() {
return {
idCard : false,
eSign : false,
isPathChange: false,
frontCard : { showpath: '', path : '' }, // 身份证正面
backCard : { showpath: '', path : '' }, // 身份证反面
realData : {
name : '',
id_card : '',
organ : ''
}, // 个人信息
signUrl : '',
isRefresh : false
}
},
onShow(){
if(this.isRefresh){
this.getCertified()
this.isRefresh = false
}
},
created() {
this.getCertified()
},
methods: {
// 检查实名结果
getCertified(){
uni.showLoading({
title: '加载中...',
mask : true
})
certified().then(res => {
let { id_card, e_sign } = res;
this.idCard = id_card;
this.eSign = e_sign;
if(this.idCard){
this.getInfo()
return
}
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none"
})
})
},
// 提交真实信息
getInfo(){
uni.showLoading({
title: '加载中...',
mask : true
})
identityOcr().then(res => {
this.frontCard.showpath = res.front_card
this.backCard.showpath = res.back_card
this.realData = res;
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none"
})
})
},
// 提交照片认证信息
realInfo() {
uni.showLoading({
title: '提交中信息...',
mask : true
})
certification({
front_card: this.frontCard.path,
back_card : this.backCard.path,
redirect_url: 'http://web.douhuofalv.com/app/e-sign?sign_type=personal',
app_scheme: 'doufire://'
}).then(res => {
console.log(res)
let certificationData = res;
wx.showModal({
title : '提示',
content : '您的身份信息已上传,请完成人脸识别以确认您是本人',
showCancel : false,
success : () => {
this.isPathChange = false
this.realData = certificationData.certification
this.signUrl = certificationData.sign.authShortUrl
this.getSignUrl()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none"
})
})
},
// 人脸识别
getSignUrl(){
if(this.signUrl != ''){
this.isRefresh = true
plus.runtime.openURL(this.signUrl)
return
}
uni.showLoading({
title: '加载中...',
mask : true
})
eSigns({
redirect_url: 'http://web.douhuofalv.com/app/e-sign?sign_type=personal',
app_scheme: 'doufire://'
}).then(res => {
this.isRefresh = true
plus.runtime.openURL(res.authShortUrl)
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon: "none"
})
})
},
// 上传图片
updImg(type){
uni.chooseImage({
count : 1,
success : path => {
uploads([{
uri : path.tempFilePaths[0]
}], {
driver: "private-oss"
}).then(res => {
this.isPathChange = true
this[type].showpath = res.url[0]
this[type].path = res.path[0]
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
// 身份信息
.identity-from{
border-bottom: 30rpx solid #f8f8f8;
.identity-inpus{
display: flex;
border-bottom: solid 1rpx #F6F6F6;
padding: 0 30rpx;
height: 100rpx;
line-height: 100rpx;
font-size: 32rpx;
&:last-child{
border-bottom: none;
}
label{
width: 180rpx;
color: gray;
}
input{
height: 100rpx;
font-size: 32rpx;
width: calc(100% - 180rpx);
text-align: right;
}
}
}
// 身份证上传
.identity-title{
padding: 0 30rpx;
line-height: 90rpx;
font-size: 30rpx;
color: #111111;
border-top: 30rpx solid #f8f8f8;
color: gray;
}
.identity-flex{
display: flex;
padding: 0 20rpx 30rpx;
.identity-item{
width: calc(50% - 20rpx);
margin: 0 10rpx;
background-color: rgba(68, 110, 254, .1);
border-radius: 10rpx;
overflow: hidden;
.upd{
padding-top: 63%;
position: relative;
background-size: 56%;
background-position: center;
background-repeat: no-repeat;
.idcardImg-img{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.text{
text-align: center;
line-height: 60rpx;
background: $main-color;
color: white;
font-size: 28rpx;
}
}
border-bottom: 30rpx solid #f8f8f8;
}
// 身份认证按钮
.btn{
padding: 30rpx;
button[size="default"]{
background: $main-color;
color: white;
height: 90rpx;
line-height: 90rpx;
padding: 0;
font-size: 32rpx;
border-radius: 10rpx;
font-weight: bold;
&::after{
display: none;
}
}
}
</style>

136
pages/user/code.vue Normal file
View File

@@ -0,0 +1,136 @@
<template>
<view class="code">
<image class="code-back main-back" src="@/static/code/code_back.png" mode="widthFix"></image>
<image class="code-back header-back" src="@/static/code/code_header.png" mode="widthFix"></image>
<image class="code-back img-lay" src="@/static/code/code_img_lay.png" mode="widthFix"></image>
<view class="code-content">
<view class="header">
<image class="sign" src="@/static/code/code_sign.png" mode="widthFix"></image>
<image class="logo" src="@/static/code/code_logo.png" mode="widthFix"></image>
</view>
<view class="block">
<view class="qrcode">
<l-painter class="qrcode-src">
<l-painter-qrcode
:text="'http://web.douhuofalv.com/login/register?invite_code=' + invite"
css="width: 260rpx; height: 260rpx; background-color:white; padding: 20rpx; border-radius: 10rpx;"
/>
</l-painter>
<view class="qrcode-text">邀请码{{invite}}</view>
</view>
<image class="btn" src="@/static/code/code_btn.png" mode="widthFix"></image>
</view>
<image class="footer" src="@/static/code/code_footer.png" mode="widthFix"></image>
</view>
</view>
</template>
<script>
import { code } from '@/apis/interfaces/user.js'
export default {
data() {
return {
invite: ''
};
},
created() {
code().then( res => {
let { invite } = res;
this.invite = invite
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
</script>
<style lang="scss">
.code {
background: #1F25AE;
height: 100vh;
position: relative;
.code-back {
width: 100%;
position: absolute
}
.main-back {
top: 20vh;
}
.header-back {
z-index: 1;
}
.img-lay {
width: 30vw;
bottom: 0;
left: 0;
z-index: 1;
}
.code-content {
position: absolute;
padding: 50rpx;
z-index: 2;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.header {
text-align: center;
width: 100%;
.sign {
width: 90%;
vertical-align: top;
margin-bottom: 30rpx;
}
.logo {
width: 25vw;
}
}
.block {
text-align: center;
margin-bottom: 30rpx;
.qrcode {
display: inline-block;
border: solid 2rpx #ECC997;
background: #0E2660;
border-radius: 20rpx;
padding: 30rpx;
.qrcode-src {
width: 300rpx;
height: 300rpx;
}
.qrcode-text {
text-align: center;
color: #FFF5C6;
line-height: 50rpx;
padding-top: 30rpx;
}
}
.btn {
width: 400rpx;
margin-top: 30rpx;
}
}
.footer {
width: 70%;
vertical-align: top;
}
}
}
</style>

22
pages/user/eSign.vue Normal file
View File

@@ -0,0 +1,22 @@
<template>
<view>
<web-view :src="webUrl"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
webUrl: ''
};
},
created() {
this.webUrl = this.$Route.query.url
}
}
</script>
<style lang="scss">
</style>

252
pages/user/index.vue Normal file
View File

@@ -0,0 +1,252 @@
<template>
<view>
<view class="user-info">
<block v-if="isAuth">
<view class="user-info-left">
<u-avatar
shape="square"
class="active"
size="120rpx"
:default-url="require('@/static/imgs/default-active.png')"
:src="avatar"
mode="aspectFill"
@click="onNav('UserInfo')"
></u-avatar>
<view class="nickname nowrap" @click="onNav('UserInfo')">{{nickname}}</view>
<view class="tags">
<view class="tags-item" v-if="certification"><image class="tags-icon" src="@/static/icons/Identity_icon.png" mode="widthFix"></image>实名认证</view>
<view class="tags-item">{{identity.name}}</view>
</view>
<view class="state">
<view class="state-tag"><u-icon class="state-icon" size="28rpx" color="#555" name="plus"></u-icon>状态</view>
</view>
</view>
<view class="user-info-right" @click="onUserCode">
<image class="user-qrcode" src="@/static/icons/qrcode.png" mode="widthFix"></image>
</view>
</block>
<block v-else>
<view class="user-info-left">
<u-avatar
shape="square"
class="active"
size="120rpx"
:default-url="require('@/static/imgs/default-active.png')"
mode="aspectFill"
@click="onNav('UserInfo')"
></u-avatar>
<view class="nickname nowrap" @click="onNav('UserInfo')">登录</view>
<view class="tags">暂未登录</view>
</view>
<view class="user-info-right">
<image class="user-qrcode" src="@/static/icons/qrcode.png" mode="widthFix"></image>
</view>
</block>
</view>
<view class="border-solid-empty"></view>
<view class="nav-flex" @click="onNav('AccountIntegral')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_00.png"></image>火力值</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
<view class="nav-flex" @click="onNav('AccountCash')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_01.png"></image>业绩账户</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
<view class="border-solid-empty"></view>
<view class="nav-flex" @click="onNav('UserTeam')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_02.png"></image>我的客户</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
<view class="nav-flex" @click="onNav('AccountBonus')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_04.png"></image>奖金账户</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
<view class="nav-flex" @click="onNav('UserCertification')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_03.png"></image>实名认证</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
<view class="border-solid-empty"></view>
<view class="nav-flex" @click="onNav('UserSet')">
<view class="nav-icon"><image class="nav-icon-src" src="@/static/icons/user_nav_05.png"></image>设置</view>
<u-icon name="arrow-right" color="#cacaca" size="34rpx" bold></u-icon>
</view>
</view>
</template>
<script>
import { info } from '@/apis/interfaces/user.js'
export default {
data() {
return {
isAuth : false,
nickname : '',
identity : '',
avatar : '',
certification : ''
};
},
onShow() {
this.isAuth = this.$store.getters.getToken != ''
if(this.$store.getters.getToken != '') this.getUserInfo()
},
methods: {
// 获取用户信息
getUserInfo(){
uni.showLoading({
title: '加载中...'
})
info().then(res => {
let { nickname, identity, avatar, certification } = res
this.nickname = nickname
this.identity = identity
this.avatar = avatar
this.certification = certification
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 导航
onNav(name){
this.$Router.push({name})
},
// 分享码
onUserCode(){
if(this.identity.order > 1){
this.$Router.push({ name: 'UserCode' })
return
}
uni.showModal({
title : '提示',
content : '您当前非业务员身份无法分享',
cancelColor : '确定',
cancelColor : '#555',
confirmText : '立即开通',
confirmColor: '#446EFE',
success : res => {
if(res.confirm){
this.$Router.pushTab({name: 'Work'})
}
}
})
}
}
}
</script>
<style lang="scss">
.nav-flex{
height: 120rpx;
padding: 0 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 34rpx;
.nav-icon{
display: flex;
align-items: center;
.nav-icon-src{
width: 48rpx;
height: 48rpx;
vertical-align: middle;
margin-right: $margin;
margin-top: 5rpx;
}
}
}
// 用户信息
.user-info{
padding: 50rpx $padding;
display: flex;
&-left{
padding-left: 140rpx;
position: relative;
width: calc(100% - 150rpx);
.active{
position: absolute;
left: 0;
top:0;
border-radius: $radius;
overflow: hidden;
}
.nickname{
font-size: 42rpx;
line-height: 50rpx;
font-weight: bold;
}
.tags{
padding-top: 20rpx;
.tags-item{
@extend .border;
display: inline-block;
border-radius: 20rpx;
padding: 0 15rpx;
font-size: 24rpx;
line-height: 40rpx;
height: 40rpx;
color: #555;
font-weight: 400;
margin-left: $margin - 10;
&::after{
border-radius: 20rpx;
}
&:first-child{
margin-left: 0;
}
.tags-icon{
width: 32rpx;
height: 32rpx;
vertical-align: middle;
margin-right: 5rpx;
margin-bottom: 6rpx;
}
}
}
.state{
padding-top: 20rpx;
.state-tag{
@extend .border;
display: inline-block;
border-radius: 30rpx;
padding: 0 20rpx;
font-size: 30rpx;
line-height: 50rpx;
height: 50rpx;
color: #555;
font-weight: 400;
&::after{
border-radius: 50rpx;
}
.state-icon{
display: inline-block;
margin-right: 5rpx;
}
}
}
}
&-right{
width: 150rpx;
height: 100rpx;
line-height: 100rpx;
position: relative;
text-align: center;
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 1rpx;
height: 100%;
background-image: linear-gradient(90deg, $border-color 50%, transparent 50%);
}
.user-qrcode{
width: 48rpx;
height: 48rpx;
vertical-align: middle;
}
}
}
</style>

163
pages/user/info.vue Normal file
View File

@@ -0,0 +1,163 @@
<template>
<view class="content">
<view class="info-flex">
<label>头像</label>
<u-avatar
class="upd-active"
shape="square"
:src="avatar.url"
:default-url="require('@/static/imgs/default-active.png')"
@click="updAvatar"
></u-avatar>
</view>
<view class="info-flex">
<label>昵称</label>
<input class="info-input" maxlength="8" v-model="nickname" type="text" placeholder="昵称" @blur="onNickname">
</view>
</view>
</template>
<script>
import { info, updInfo } from '@/apis/interfaces/user.js'
import { uploads } from '@/apis/interfaces/uploading.js'
export default {
data() {
return {
nickname: '', // 用户昵称
avatar : {
url : '',
path: ''
}, // 上传头像
};
},
created() {
this.getInfo()
},
methods: {
// 获取用户资料
getInfo(){
uni.showLoading({
title: '加载中...'
})
info().then(res => {
let { nickname, avatar} = res
this.nickname = nickname
this.avatar = {
url : avatar,
path: ''
}
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 更新昵称
onNickname(e){
this.updInfo('nickname', this.nickname)
},
// 更新资料
updInfo(key, val){
uni.showLoading({
title: '加载中...',
mask : true
})
updInfo(key, val).then(res => {
uni.showToast({
title: '修改成功',
icon : 'none',
})
}).catch(err => {
this.getInfo()
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 更新头像
updAvatar(){
uni.chooseImage({
count: 1,
crop : {
width : 300,
height : 300
},
success: res => {
if(res.tempFilePaths.length > 0){
uni.showLoading({
title: '上传中...',
mask : true
})
uploads([{
name: 'avatar',
uri : res.tempFilePaths[0]
}]).then(updRes => {
let { path, url } = updRes
this.avatar = {
url : url[0],
path: path[0]
}
this.updInfo('avatar', path[0])
}).catch(updErr => {
uni.showToast({
title: updErr.message,
icon : 'none'
})
})
}
},
fail: err => {}
})
}
}
}
</script>
<style lang="scss">
.content{
padding-top: 30rpx;
}
// 编辑信息
.info-flex{
background: white;
padding: 20rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
line-height: 60rpx;
position: relative;
overflow: hidden;
&::after {
content: "";
position: absolute;
left: 30rpx;
bottom: 0;
width: 100%;
height: 1rpx;
z-index: 2;
background-image: linear-gradient(0deg, $border-color 50%, transparent 50%);
}
&:last-child::after{
display: none;
}
label{
font-size: 30rpx;
color: #111;
width: 200rpx;
}
.info-input{
width: calc(100% - 200rpx);
text-align: right;
}
.upd-active{
width: 88rpx;
height: 88rpx;
border-radius: $radius;
position: relative;
overflow: hidden;
}
}
</style>

27
pages/user/set.vue Normal file
View File

@@ -0,0 +1,27 @@
<template>
<view>
<button @click="onLogout()">退出登录</button>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
onLogout(){
this.$store.commit('setToken', '');
this.$Router.replaceAll({
name: 'Auth'
})
}
}
}
</script>
<style lang="scss">
</style>

130
pages/user/team.vue Normal file
View File

@@ -0,0 +1,130 @@
<template>
<view class="content">
<view class="header">
客户列表
<text>{{count.all}}客户</text>
</view>
<block v-if="users.length > 0">
<view class="team-item" v-for="(item, index) in users" :key="index">
<u-avatar :src="item.avatar" size="40"></u-avatar>
<view class="name nowrap">
{{item.nickname}}
<text class="identity identity-2" v-if="item.identity.order == 2">业务员</text>
<text class="identity identity-1" v-if="item.identity.order == 1">普通用户</text>
<text class="identity identity-3" v-if="item.identity.order == 3">顾问</text>
</view>
<view class="mobile">{{item.username}}</view>
</view>
</block>
<block v-else>
<view class="list-null">
<u-empty
mode="data"
icon="http://cdn.uviewui.com/uview/empty/data.png"
text="暂无客户数据"
>
</u-empty>
</view>
</block>
</view>
</template>
<script>
import { relations } from '@/apis/interfaces/user.js'
export default {
data() {
return {
users: [],
count: {
all: 0
}
};
},
created() {
relations({
larer: 1
}).then(res => {
let { users, count } = res;
this.users = users.data
this.count = count
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
</script>
<style lang="scss">
.content{
box-sizing: border-box;
}
// 统计数据
.header{
display: flex;
justify-content: space-between;
padding: 0 30rpx;
line-height: 100rpx;
font-weight: bold;
text{
font-size: 28rpx;
color: gray;
font-weight: normal;
}
}
// 团队列表
.team-item{
background: white;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-radius: 20rpx;
margin: 0 30rpx 30rpx 30rpx;
.name{
width: calc(100% - 200rpx - 40px);
padding: 0 20rpx;
box-sizing: border-box;
font-weight: bold;
font-size: 30rpx;
color: #333333;
.identity{
display: inline-block;
background: #F6F6F6;
color: #999999;
font-weight: normal;
margin-left: 20rpx;
border-radius: 20rpx;
height: 40rpx;
line-height: 36rpx;
padding: 0 10rpx;
font-size: 24rpx;
border:solid 1rpx #000;
box-sizing: border-box;
&.identity-2{
background: #ECF0FF;
border-color: #443DE2;
color: #443DE2;
}
&.identity-1{
background: #F6F6F6;
border-color: #999999;
color: #999999;
}
&.identity-3{
background: #FFF7EC;
border-color: #FEAD45;
color: #FEAD45;
}
}
}
.mobile{
width: 200rpx;
color: #666666;
text-align: right;
font-size: 30rpx;
}
}
</style>

211
pages/work/available.vue Normal file
View File

@@ -0,0 +1,211 @@
<template>
<view class="content">
<view class="header-search">
<input type="text" placeholder="输入用户名或手机号码搜索" v-model="searchValue" maxlength="11">
<button size="mini" @click="onSearch">搜索</button>
</view>
<!-- 下级列表 -->
<view class="available-user" v-if="searchValue.length <= 0">
<block v-if="users.length > 0">
<view class="user-item border-solid" v-for="(item, index) in users" :key="index" @click="onItem(item)">
<image class="cover" :src="item.avatar" mode="aspectFill"></image>
<view class="text">
<view class="nickname nowrap">{{item.nickname}}</view>
<view class="no nowrap">{{item.username}}</view>
</view>
<view class="icon">
<u-icon class="icon-u" name="arrow-right" color="#ddd" size="20"></u-icon>
</view>
</view>
</block>
<block v-else>
<view class="search-null">
<u-empty
mode="list"
icon="http://cdn.uviewui.com/uview/empty/list.png"
text="暂无下级用户"
>
</u-empty>
</view>
</block>
</view>
<!-- 搜索结果 -->
<view class="available-user" v-else>
<block v-if="searchResults.length > 0">
<view class="user-item border-solid" v-for="(item, index) in searchResults" :key="index" @click="onItem(item)">
<image class="cover" :src="item.avatar" mode="aspectFill"></image>
<view class="text">
<view class="nickname nowrap">{{item.nickname}}</view>
<view class="no nowrap">{{item.username}}</view>
</view>
<view class="icon">
<u-icon class="icon-u" name="arrow-right" color="#ddd" size="20"></u-icon>
</view>
</view>
</block>
<block v-else>
<view class="search-null">
<u-empty
mode="search"
icon="http://cdn.uviewui.com/uview/empty/search.png"
:text="searchText"
>
</u-empty>
</view>
</block>
</view>
</view>
</template>
<script>
import { availableUser } from '@/apis/interfaces/business.js'
import { relations } from '@/apis/interfaces/user.js'
export default {
data() {
return {
isSearch : false,
users : [],
pages : {},
searchValue : '',
searchResults : [],
searchText : '输入姓名或姓名搜索'
};
},
created() {
this.getUsers()
},
// 监听搜索值变化重置搜索这状态
methods: {
// 我的伙伴
getUsers(){
uni.showLoading({
title: '加载中...',
mask : true
})
relations().then(res => {
let { users } = res;
this.users = users.data
this.pages = users.page
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 搜索用户
onSearch(){
if(this.searchValue == ''){
uni.showToast({
title: '请输入搜索关键字',
icon : 'none'
})
return
}
let isNumber = new RegExp("[0-9]+");
// 搜索信息
uni.showLoading({
title: '搜索中...',
mask : true
})
availableUser(isNumber.test(this.searchValue) ? 'mobile': 'name', this.searchValue).then(res => {
this.searchResults = res
this.isSearch = true
}).catch(err => {
this.searchText = err.message
}).finally(() => {
uni.hideLoading()
})
},
// 选择用户
onItem(userInfo){
this.$store.commit('setUser', userInfo)
this.$Router.back()
}
}
}
</script>
<style lang="scss">
// 搜索结果为空
.search-null{
height: 70vh;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
// 搜索用户
.available-user{
padding-top: 130rpx;
.user-item{
padding: 20rpx 30rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
background: white;
.cover{
width: 88rpx;
height: 88rpx;
border-radius: $radius;
}
.text{
width: calc(100% - 168rpx);
padding-left: 30rpx;
box-sizing: border-box;
.nickname{
line-height: 40rpx;
font-size: 32rpx;
color: #333;
}
.no{
line-height: 40rpx;
color: gray;
font-size: 28rpx;
}
}
.icon{
width: 80rpx;
text-align: right;
.icon-u{
display: inline-block;
}
}
}
}
// header
.header-search{
position: fixed;
top: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx;
background: white;
display: flex;
input{
background: #f8f8f8;
height: 70rpx;
line-height: 70rpx;
border-radius: $radius-lg;
padding: 0 30rpx;
box-sizing: border-box;
width: calc(100% - 170rpx);
font-size: 30rpx;
margin-right: 30rpx;
}
button[size="mini"]{
width: 140rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0;
background: $main-color;
color: white;
font-size: 30rpx;
font-weight: normal;
}
}
</style>

211
pages/work/create.vue Normal file
View File

@@ -0,0 +1,211 @@
<template>
<view class="create-page">
<view class="create-title">创建新的订单</view>
<view class="create-submit">完善创建订单用户与订单类型</view>
<view class="create-from">
<block v-if="createType === 'other'">
<view class="create-user" @click="() => this.$Router.push({name: 'OrderAvailable'})">
<view class="cover">
<image class="cover-src" v-if="user != ''" :src="user.avatar" mode="aspectFill"></image>
<u-icon v-else name="plus" color="#ddd" size="24"></u-icon>
</view>
<view class="nickname nowrap" :class="{'hide': user == ''}">{{user.nickname || '请选择办理用户'}}</view>
<view class="icon">
<u-icon class="icon-u" name="arrow-right" color="#ddd" size="20"></u-icon>
</view>
</view>
</block>
<view class="create-type">
<view class="create-type-title">选择业务类型</view>
<block v-for="(item, index) in businessArr" :key="index">
<view class="create-type-item" :class="{'active': item.business_id == businessId}" @click="onBusiness(item.business_id)">
<image class="create-type-icon" :src="item.cover_url" mode="aspectFill"></image>
<view class="create-type-text">
<view class="title nowrap">{{item.title || '-'}}</view>
<view class="submit nowrap">{{item.subtitle || '-'}}</view>
</view>
</view>
</block>
</view>
<view class="create-btn">
<button size="default" @click="onNext()">下一步</button>
</view>
</view>
</view>
</template>
<script>
import { business } from '@/apis/interfaces/business.js'
export default {
data() {
return {
createType : '',
businessArr: [],
businessId : '',
user : ''
};
},
onShow(){
let user = this.$store.getters.getUser
this.createType = this.$Route.query.type
if(user != ''){
this.user = user
this.$store.commit('setUser', '')
}
},
created() {
business().then(res => {
this.businessArr = res
this.businessId = res[0].business_id
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods: {
// 选择业务类型
onBusiness(id){
this.businessId = id
},
// 创建业务单
onNext(){
if(this.createType == 'other' && !this.user.user_id){
uni.showToast({
title: '请选择办理用户',
icon : 'none'
})
return
}
let busines = this.businessArr.find(val => val.business_id === this.businessId)
this.$Router.replace({
name : 'WorkGenerate',
params : {
businessTitle : busines.title,
businessId : busines.business_id,
serviceUser : this.user.user_id,
createType : this.createType
}
})
}
}
}
</script>
<style lang="scss">
.create-page{
padding: 50rpx;
box-sizing: border-box;
height: 100vh;
.create-title{
text-align: center;
font-weight: bold;
font-size: 44rpx;
}
.create-submit{
text-align: center;
font-size: 30rpx;
color: gray;
padding-top: 10rpx;
}
.create-from{
padding-top: 50rpx;
}
// 目标用户
.create-user{
background: #f8f8f8;
border-radius: $radius;
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
.cover{
width: 88rpx;
height: 88rpx;
background: white;
border-radius: $radius;
margin-right: 20rpx;
border: dashed 1rpx #ddd;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.cover-src{
width: 100%;
height: 100%;
}
}
.nickname{
width: calc(100% - 188rpx);
line-height: 70rpx;
font-size: 32rpx;
&.hide{
color: gray;
}
}
.icon{
width: 80rpx;
text-align: right;
.icon-u{
display: inline-block;
}
}
}
// 选择业务类型
.create-type{
padding-top: 50rpx;
.create-type-title{
text-align: center;
line-height: 50rpx;
color: gray;
font-size: 30rpx;
}
.create-type-item{
background: #f8f8f8;
border-radius: $radius;
padding: 30rpx;
margin-top: 30rpx;
border:solid 1rpx #f8f8f8;
box-sizing: border-box;
display: flex;
align-items: center;
.create-type-icon{
width: 88rpx;
height: 88rpx;
margin-right: $margin;
background-color: white;
border-radius: $radius;
}
.create-type-text{
line-height: 40rpx;
.title{
font-size: 30rpx;
}
.submit{
color: gray;
font-size: 26rpx;
}
}
&.active{
border:solid 1rpx $main-color;
}
}
}
// 按钮
.create-btn{
margin-top: 90rpx;
button[size="default"]{
height: 100rpx;
line-height: 100rpx;
background: $main-color;
font-size: 32rpx;
color: white;
font-weight: bold;
&::after{
border: none;
}
}
}
}
</style>

463
pages/work/generate.vue Normal file
View File

@@ -0,0 +1,463 @@
<template>
<view class="content">
<block v-if="serviceArr.length > 0">
<view class="block" v-for="(item, index) in serviceArr" :key="index">
<view class="block-title">
{{item.title}}
<view class="block-remove" @click="onRemove(index)" v-if="serviceArr.length > 1">
<u-icon class="block-remove-icon" size="15" color="#446EFE" name="minus-circle"></u-icon>移出
</view>
</view>
<!-- 机构 -->
<view class="block-item">
<label class="block-item-label"><text>*</text>机构</label>
<picker :range="item.institution" range-key="title" :value="item.institutionIndex" @change="institutionChange($event, item, index)">
<view class="institution-picker">
<view class="institution-picker-text nowrap">{{item.institution[item.institutionIndex].title}}</view>
<u-icon size="12" color="#999" name="arrow-down-fill"></u-icon>
</view>
</picker>
</view>
<!-- 业务类型 -->
<view class="block-item">
<label class="block-item-label"><text>*</text>业务类型</label>
<picker :range="item.fromType" range-key="title" :value="item.fromIndex" @change="businessChange($event, item, index)">
<view class="institution-picker">
<view class="institution-picker-text nowrap">{{item.fromType[item.fromIndex].title}}</view>
<u-icon size="12" color="#999" name="arrow-down-fill"></u-icon>
</view>
</picker>
</view>
<!-- 表单信 -->
<view
class="block-item"
v-for="(formItem, formIndex) in item.froms"
:key="formIndex"
v-if="item.subVal[formItem.pre_key] == formItem.pre_value"
>
<block v-if="formItem.type == 'price' || formItem.type == 'number'">
<label class="block-item-label"><text v-if="formItem.is_required == 1">*</text>{{formItem.title}}</label>
<view class="inputs-flex">
<input
class="input"
v-model="item.subVal[formItem.key]"
:type="formItem.type == 'price' ? 'digit': 'number'"
:placeholder="'请输入' + formItem.title"
>
<text class="unit" v-if="formItem.type == 'price'"></text>
<text class="unit" v-if="formItem.type == 'number'"></text>
</view>
</block>
<block v-if="formItem.type == 'radio'">
<view class="radio-flex">
<view class="radio-title"><text v-if="formItem.is_required == 1">*</text>{{formItem.title}}</view>
<radio-group @change="item.subVal[formItem.key] = $event.detail.value">
<label class="radio-label" v-for="(radioItem, radioIndex) in formItem.options" :key="radioIndex">
<radio class="radio-input" color="#446EFE" :checked="radioIndex === item.subVal[formItem.key]" :value="radioIndex"/>{{radioItem}}
</label>
</radio-group>
</view>
</block>
<block v-if="formItem.type == 'checkbox'">
<label class="block-item-label"><text v-if="formItem.is_required == 1">*</text>{{formItem.title}}(可多选)</label>
<checkbox-group @change="item.subVal[formItem.key] = $event.detail.value">
<label class="checkbox-item" v-for="(checkboxItem, checkboxIndex) in formItem.options">
<checkbox class="checkbox-input" :value="checkboxIndex" color="#446EFE"></checkbox>{{checkboxItem}}
</label>
</checkbox-group>
</block>
<block v-if="formItem.type == 'textarea'">
<label class="block-item-label"><text v-if="formItem.is_required == 1">*</text>{{formItem.title}}</label>
<textarea
class="textarea"
:placeholder="'请输入' + formItem.title"
v-model="item.subVal[formItem.key]"
></textarea>
</block>
</view>
</view>
</block>
<view class="footer">
<view class="footer-text">温馨提示为了匹配最准确方案请如实填写信息</view>
<view class="footer-flex">
<button @click="onAdd">添加新信息</button>
<button @click="onSubmit">提交</button>
</view>
</view>
</view>
</template>
<script>
import { institution, business, institutionType, submitStore } from '@/apis/interfaces/business.js';
import { octpicker } from '@/components/oct-picker.vue'
export default {
components: { octpicker },
data() {
return {
businessArr: [],
serviceUser: '',
serviceArr : [],
};
},
created() {
let { businessId, serviceUser, businessTitle } = this.$Route.query
this.getInstitution(businessId, businessTitle)
this.getBusiness()
this.serviceUser = serviceUser
},
methods: {
// 移出选项
onRemove(index){
this.serviceArr.splice(index, 1)
},
// 获取主业务
getBusiness(){
business().then(res => {
this.businessArr = res
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 获取主业务机构
getInstitution(businessId, businessTitle){
uni.showLoading({
title: '加载中...'
})
institution(businessId).then(institutionArr => {
let forms = this.getForms(institutionArr[0].institution_id)
forms.then(val => {
this.servicePush( val, institutionArr, businessTitle, businessId )
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 获取业务类型
async getForms(businessId){
return await institutionType(businessId)
},
// 组织业务表单数据
servicePush( vals, institutionArr, businessTitle, businessId ){
let fromType = [],
fromsVal = {},
froms = vals[0].params
fromType = vals.map((val) => {
return {
type_id: val.type_id,
title : val.title
}
})
froms.map(val => {
fromsVal[val.key] = val.type === 'checkbox' ? [] : ''
})
// 新增卡片
this.serviceArr.push({
title : businessTitle,
institution : institutionArr,
allInstitution : vals,
institutionIndex: 0,
fromType : fromType,
fromIndex : 0,
froms : froms,
subVal : {
business_id : Number(businessId),
institution_id : institutionArr[0].institution_id,
type_id : fromType[0].type_id,
...fromsVal
}
})
},
// 机构变更更新业务
institutionChange(e, old, index){
let { value } = e.detail;
let businessId = old.subVal.business_id
// 获取机构的子业务类型
let forms = this.getForms(old.institution[value].institution_id)
forms.then(institutionVal => {
let newObj = old
let fromType = []
let params = institutionVal[0].params
let paramsVal = []
// 业务类型
fromType = institutionVal.map(val => {
return {
type_id: val.type_id,
title : val.title
}
})
// 提交字段
params.map(val => {
paramsVal[val.key] = val.type === 'checkbox' ? [] : ''
})
// 更新数据
newObj.allInstitution = institutionVal;
newObj.institutionIndex = value;
newObj.fromType = fromType;
newObj.fromIndex = 0;
newObj.froms = params;
newObj.subVal = {
business_id : old.subVal.business_id,
institution_id : old.institution[value].institution_id,
type_id : fromType[0].type_id,
...paramsVal
}
this.$set(this.serviceArr, index, newObj)
})
},
// 业务变更
businessChange(e, old, index){
let { value } = e.detail;
let businessId = old.subVal.business_id;
let allInstitution = old.allInstitution
let newObj = old
let params = allInstitution[value].params
let paramsVal = {}
params.map(val => {
paramsVal[val.key] = val.type === 'checkbox' ? [] : ''
})
newObj.fromIndex = value;
newObj.froms = params;
newObj.subVal = {
business_id : old.subVal.business_id,
institution_id : old.subVal.institution_id,
type_id : allInstitution[value].type_id,
...paramsVal
}
this.$set(this.serviceArr, index, newObj)
},
// 添加主业务
onAdd(){
let businessTitle = this.businessArr.map(val => {
return val.title
})
uni.showActionSheet({
itemList: businessTitle,
success : res=> {
let { tapIndex } = res;
this.getInstitution(this.businessArr[tapIndex].business_id, businessTitle[tapIndex])
}
})
},
// 提交订单数据
onSubmit(){
let dataVal = this.serviceArr.map(val => {
return val.subVal
})
if(this.serviceUser == ''){
uni.showToast({
title: '服务用户不能为空',
icon : 'none'
})
return
}
uni.showLoading({
title: '提交中...',
mask : true
})
submitStore({
type : this.$Route.query.createType,
user_id : this.serviceUser,
data : dataVal,
channel : 'app'
}).then(res => {
uni.showModal({
title : '提示',
content : '订单已创建,请尽快提醒用户完善用户资料',
showCancel : false,
success : () => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss">
.content{
padding-top: 20rpx;
padding-bottom: 260rpx;
}
// 表单模块
.block{
background: white;
border-radius: $radius;
margin: 0 30rpx 20rpx;
padding: 30rpx;
.block-title{
font-weight: bold;
line-height: 60rpx;
display: flex;
justify-content: space-between;
align-items: center;
.block-remove{
background: rgba(68, 110, 254, .1);
color: #446EFE;
font-size: 28rpx;
font-weight: normal;
height: 50rpx;
line-height: 50rpx;
border-radius: 25rpx;
padding: 0 25rpx 0 20rpx;
&-icon{
display: inline-block;
margin-right: 10rpx;
margin-bottom: 5rpx;
vertical-align: middle;
}
}
}
.block-item{
padding: 15rpx 0;
&-label{
padding-bottom: 10rpx;
display: block;
font-size: 30rpx;
color: #111111;
text{
color: #FF0000;
font-size: 28rpx;
margin-right: 10rpx;
}
}
// picker
.institution-picker{
background: #F6F6F6;
height: 84rpx;
line-height: 84rpx;
border-radius: 10rpx;
padding: 0 30rpx 0 30rpx;
font-size: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
&-text{
width: calc( 100% - 60rpx );
}
}
// input
.inputs-flex{
display: flex;
justify-content: space-between;
align-items: center;
.input{
background: #F6F6F6;
height: 84rpx;
line-height: 84rpx;
border-radius: 10rpx;
padding: 0 30rpx 0 30rpx;
font-size: 30rpx;
box-sizing: border-box;
width: calc( 100% - 64rpx );
}
.unit{
width: 64rpx;
text-align: right;
}
}
// radio
.radio-flex{
display: flex;
justify-content: space-between;
padding: 10rpx 0;
.radio-title{
font-size: 30rpx;
color: #111111;
text{
color: #FF0000;
font-size: 28rpx;
margin-right: 10rpx;
}
}
.radio-label{
margin-left: 20rpx;
color: #999999;
.radio-input{
transform:scale(0.7);
}
}
}
// checkbox
.checkbox-item{
display: block;
color: #999999;
line-height: 70rpx;
.checkbox-input{
transform:scale(0.7);
vertical-align: middle;
margin-top: -5rpx;
}
}
// textarea
.textarea{
background: #F6F6F6;
width: 100%;
height: 200rpx;
border-radius: 10rpx;
padding: 20rpx 30rpx;
font-size: 30rpx;
line-height: 40rpx;
box-sizing: border-box;
}
}
}
// footer
.footer{
box-shadow: 0 0 10rpx 0 rgba(0, 0, 0, .05);
background-color: white;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 99;
padding: 30rpx 30rpx 70rpx;
.footer-text{
text-align: center;
font-weight: bold;
font-size: 28rpx;
color: #FEA044;
line-height: 40rpx;
padding-bottom: 30rpx;
}
.footer-flex{
display: flex;
margin: 0 -10rpx;
button{
width: calc(50% - 20rpx);
margin: 0 10rpx;
height: 90rpx;
line-height: 90rpx;
border-radius: $radius-lg;
font-size: 32rpx;
border:solid 1rpx $main-color;
background-color: white;
color: $main-color;
&::after{
border: none;
}
&:last-child{
background-color: $main-color;
color: white;
}
}
}
}
</style>

556
pages/work/index.vue Normal file
View File

@@ -0,0 +1,556 @@
<template>
<view class="content">
<view v-if="isAuth">
<!-- 状态栏 -->
<u-sticky bgColor="#FFFFFF">
<view class="status_bar"></view>
<view class="work-bar">
<view class="work-bar-user">
<image class="cover" :src="userInfo.avatar || require('@/static/imgs/default-active.png')" mode="aspectFill"></image>
<view class="nickname">{{userInfo.nickname}}<text class="card" v-if="isManager">{{identity.name}}</text></view>
</view>
<view class="work-bar-add" @click="onCreateOrder" v-if="isManager">
<uni-icons class="icon" type="plusempty" size="30rpx" color="#111"></uni-icons>创建订单
</view>
</view>
</u-sticky>
<!-- 未认证或未考试 -->
<block v-if="!isManager">
<view class="block open-interest">
<view class="title">业务员专属权益</view>
<view class="open-interest-flex">
<view class="open-interest-item" v-for="(item, index) in rightsArr" :key="index" @click="onToast(item)">
<image class="open-interest-icon" :src="item.icon"></image>
<view class="open-interest-text">{{item.title}}</view>
</view>
</view>
</view>
<view class="block open-interest">
<view class="title">仅需两步即可成为业务员</view>
<view class="open-interest-block">
<image class="open-interest-icon" :src="isCertification ? require('@/static/icons/work_icon_25.png'): require('@/static/icons/work_icon_24.png')"></image>
<view class="open-interest-text">
<view class="open-interest-title">实名认证</view>
<view class="open-interest-submit">通过身份证实名认证</view>
</view>
<button class="open-interest-btn" size="mini" :disabled="isCertification" @click="$Router.push({name: 'UserCertification'})">{{isCertification ? '已认证': '去认证'}}</button>
</view>
<view class="open-interest-block">
<image class="open-interest-icon" :src="isAnswer ? require('@/static/icons/work_icon_25.png'): require('@/static/icons/work_icon_23.png')"></image>
<view class="open-interest-text">
<view class="open-interest-title">通过业务员考试</view>
<view class="open-interest-submit">通过线上考试即可完成</view>
</view>
<button class="open-interest-btn" size="mini" :disabled="isAnswer" @click="$Router.push({name: 'CollegeTest'})">{{isAnswer ? '已通过': '去考试'}}</button>
</view>
</view>
<!-- 提示信息 -->
<u-popup :show="privilegeShow" mode="center" bgColor="transparent">
<view class="privilege-lay">
<image class="privilege-lay-img" src="@/static/imgs/privilege-lay-header.png" mode="widthFix"></image>
<view class="privilege-lay-content"><text>{{privilegeText}}</text></view>
<view class="privilege-lay-remove">
<u-icon class="privilege-lay-icon" name="close-circle" color="white" size="30" @click="privilegeShow = false"></u-icon>
</view>
</view>
</u-popup>
</block>
<!-- 管理中台 -->
<block v-else>
<view class="block">
<view class="block-title">统计数据</view>
<view class="total-flex">
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_00.png"></image>
<view class="title">预约咨询单</view>
<view class="number">-<text></text></view>
</view>
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_01.png"></image>
<view class="title">已缴费</view>
<view class="number">-<text></text></view>
</view>
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_02.png"></image>
<view class="title">办理完成</view>
<view class="number">-<text></text></view>
</view>
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_03.png"></image>
<view class="title">退款中</view>
<view class="number">-<text></text></view>
</view>
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_04.png"></image>
<view class="title">完成结案</view>
<view class="number">-<text></text></view>
</view>
<view class="total-item">
<image class="icon" src="@/static/icons/work_icon_05.png"></image>
<view class="title">结案金额</view>
<view class="number">-<text></text></view>
</view>
</view>
</view>
<view class="block">
<view class="block-title">订单管理</view>
<view class="tool-flex">
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 0 })">
<image class="icon" src="@/static/icons/work_icon_06.png"></image>
<view class="number" v-if="orderCount.a_init > 0">{{orderCount.a_init}}</view>
<view class="text">待预约</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 2 })">
<image class="icon" src="@/static/icons/work_icon_21.png"></image>
<view class="number" v-if="orderCount.a_service > 0">{{orderCount.a_service}}</view>
<view class="text">匹配服务包</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 3 })">
<image class="icon" src="@/static/icons/work_icon_07.png"></image>
<view class="number" v-if="orderCount.a_serviced > 0">{{orderCount.a_serviced}}</view>
<view class="text">待缴服务费</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 4 })">
<image class="icon" src="@/static/icons/work_icon_10.png"></image>
<view class="number" v-if="orderCount.b_sign > 0">{{orderCount.b_sign}}</view>
<view class="text">待签约</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 5 })">
<image class="icon" src="@/static/icons/work_icon_08.png"></image>
<view class="number" v-if="orderCount.a_bank > 0">{{orderCount.a_bank}}</view>
<view class="text">待完善资料</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 6 })">
<image class="icon" src="@/static/icons/work_icon_09.png"></image>
<view class="number" v-if="orderCount.b_check > 0">{{orderCount.b_check}}</view>
<view class="text">初审中</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 7 })">
<image class="icon" src="@/static/icons/work_icon_12.png"></image>
<view class="number" v-if="orderCount.b_recheck > 0">{{orderCount.b_recheck}}</view>
<view class="text">复审中</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 8 })">
<image class="icon" src="@/static/icons/work_icon_13.png"></image>
<view class="number" v-if="orderCount.b_process > 0">{{orderCount.b_process}}</view>
<view class="text">办理中</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 9 })">
<image class="icon" src="@/static/icons/work_icon_14.png"></image>
<view class="number" v-if="orderCount.b_confirm > 0">{{orderCount.b_confirm}}</view>
<view class="text">待结案</view>
</view>
<view class="tool-flex-item" @click="onNav('Orders', { 'type': 10 })">
<image class="icon" src="@/static/icons/work_icon_15.png"></image>
<view class="number" v-if="orderCount.b_complete > 0">{{orderCount.b_complete}}</view>
<view class="text">办理完成</view>
</view>
</view>
</view>
<view class="block">
<view class="block-title">转让订单管理</view>
<view class="tool-flex">
<view class="tool-flex-item" @click="onNav('TransfersOrders', { type: 'out' })">
<image class="icon" src="@/static/icons/work_icon_26.png"></image>
<view class="number" v-if="orderCount.transfer_out > 0">{{orderCount.transfer_out}}</view>
<view class="text">转出订单</view>
</view>
<view class="tool-flex-item" @click="onNav('TransfersOrders', { type: 'in' })">
<image class="icon" src="@/static/icons/work_icon_19.png"></image>
<view class="number" v-if="orderCount.transfer_in > 0">{{orderCount.transfer_in}}</view>
<view class="text">转入订单</view>
</view>
</view>
</view>
<view class="block">
<view class="block-title">特殊订单管理</view>
<view class="tool-flex">
<view class="tool-flex-item" @click="onNav('ModifyOrder', {})">
<image class="icon" src="@/static/icons/work_icon_16.png"></image>
<view class="number" v-if="orderCount.audit_bank > 0">{{orderCount.audit_bank}}</view>
<view class="text">修改资料</view>
</view>
<view class="tool-flex-item" @click="onNav('PoorOrder', {})">
<image class="icon" src="@/static/icons/work_icon_17.png"></image>
<view class="number" v-if="orderCount.diff_prices > 0">{{orderCount.diff_prices}}</view>
<view class="text">补差价</view>
</view>
<view class="tool-flex-item" @click="onNav('RefundOrder')">
<image class="icon" src="@/static/icons/work_icon_18.png"></image>
<view class="number" v-if="orderCount.refund > 0">{{orderCount.refund}}</view>
<view class="text">退款订单</view>
</view>
</view>
</view>
</block>
</view>
<!-- 未登录 -->
<view v-else class="auth-null">
<u-empty
mode="permission"
icon="http://cdn.uviewui.com/uview/empty/permission.png"
text="暂未登录"
>
</u-empty>
<button class="auth-null-btn" size="mini" @click="onNav('Auth')">登录</button>
</view>
</view>
</template>
<script>
import { index, rights } from '@/apis/interfaces/work.js'
export default {
data() {
return {
isAuth : false,
rightsArr : [],
userInfo : {
nickname: '',
avatar : ''
},
identity : {},
isAnswer : false,
isCertification : false,
certification : null,
isManager : false,
orderCount : {},
// 权益说明
privilegeShow : false,
privilegeText : ''
};
},
onShow() {
let i = 0;
this.isAuth = this.$store.getters.getToken != ''
if(this.isAuth){
this.getIndex()
}
},
methods: {
// 显示业务员权益
onToast(val){
this.privilegeText = val.content
this.privilegeShow = true
},
// 工作台信息
getIndex(){
uni.showLoading({
title: '加载中...',
mask : true
})
Promise.all([rights(), index()]).then(res => {
let rightsData = res[0],
indexData = res[1]
let { nickname, avatar, business_orders_count, isCertification, certification, isManager, isAnswer, identity } = indexData
this.rightsArr = rightsData
this.userInfo = {
nickname,
avatar
}
this.isCertification = isCertification
this.certification = certification
this.isManager = isManager
this.isAnswer = isAnswer
this.orderCount = business_orders_count
this.identity = identity
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 导航
onNav(name, obj){
let params = obj || {}
this.$Router.push({name, params})
},
// 创建订单
onCreateOrder(){
uni.showActionSheet({
itemList: ['个人订单', '客户订单'],
success : res => {
this.onNav('OrderCreate', {
type: res.tapIndex === 0 ? 'self' : 'other'
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.content{
padding-bottom: 30rpx;
}
// 登录提示
.auth-null{
height: 100vh;
width: 100vw;
background: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.auth-null-btn{
height: 90rpx;
line-height: 90rpx;
padding: 0;
width: 70vw;
background: $main-color;
color: white;
font-size: 32rpx;
margin-top: 100rpx;
font-weight: bold;
}
}
// 弹出特权
.privilege-lay{
width: 70vw;
.privilege-lay-img{
width: 70vw;
vertical-align: top;
}
.privilege-lay-content{
background: white;
border-radius: 0 0 20rpx 20rpx;
width: 70vw;
padding: 80rpx 30rpx 50rpx;
box-sizing: border-box;
margin-top: -50rpx;
line-height: 50rpx;
color: #111111;
font-size: 30rpx;
}
.privilege-lay-remove{
padding-top: 30rpx;
text-align: center;
.privilege-lay-icon{
display: inline-block;
}
}
}
// header
.work-bar{
padding: 30rpx;
margin-bottom: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
&-user{
position: relative;
line-height: 70rpx;
height: 70rpx;
width: calc(100% - 200rpx);
padding-left: 90rpx;
box-sizing: border-box;
.cover{
width: 70rpx;
height: 70rpx;
border-radius: 50%;
position: absolute;
left: 0;
top: 0;
}
.nickname{
font-weight: bold;
font-size: 34rpx;
.card{
color: $main-color;
font-size: 24rpx;
display: inline-block;
height: 40rpx;
line-height: 38rpx;
border-radius: 24rpx;
padding: 0 15rpx;
margin-left: 20rpx;
margin-bottom: 2rpx;
vertical-align: middle;
border:solid 1rpx $main-color;
font-weight: normal;
}
}
}
&-add{
width: 200rpx;
font-size: 30rpx;
text-align: right;
line-height: 70rpx;
.icon{
margin-right: 5rpx;
font-weight: bold;
}
}
}
// 订单管理
.tool-flex{
padding: 0 10rpx;
display: flex;
flex-wrap: wrap;
.tool-flex-item{
width: 25%;
text-align: center;
margin-bottom: 30rpx;
position: relative;
.icon{
width: 78rpx;
height: 78rpx;
background: #ddd;
border-radius: 20rpx;
}
.number{
position: absolute;
right: 20%;
background: #fe4444;
top: -10rpx;
height: 40rpx;
line-height: 40rpx;
min-width: 40rpx;
font-size: 24rpx;
color: white;
border-radius: 50%;
}
.text{
line-height: 40rpx;
font-size: 26rpx;
color: #111;
text-align: center;
}
}
}
// 数据统计单
.total-flex{
padding: 0 20rpx 20rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
.total-item{
margin: 0 10rpx 20rpx;
background: #f8f8f8;
width: calc(50% - 20rpx);
padding: 20rpx 20rpx 20rpx 120rpx;
box-sizing: border-box;
border-radius: $radius;
position: relative;
min-height: 140rpx;
.icon{
position: absolute;
left: 20rpx;
top: 50%;
width: 70rpx;
height: 70rpx;
margin-top: -35rpx;
}
.title{
font-size: 28rpx;
color: #111;
@extend .nowrap;
}
.number{
padding-top: 5rpx;
font-weight: bold;
font-size: 40rpx;
color: #111;
font-family: Arial, Helvetica, sans-serif;
@extend .nowrap;
text{
font-size: 80%;
font-weight: normal;
padding-left: 10rpx;
}
}
}
}
// 通用板块
.block{
background: white;
margin: 0 30rpx 20rpx;
border-radius: $radius;
.block-title{
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
color: '#111';
font-size: 32rpx;
}
}
// 开通业务员
.open-interest{
padding: 30rpx;
margin-bottom: 30rpx;
.title{
text-align: center;
font-size: 34rpx;
font-weight: bold;
line-height: 80rpx;
}
.open-interest-flex{
display: flex;
flex-wrap: wrap;
padding-top: 30rpx;
justify-content: space-between;
.open-interest-item{
text-align: center;
.open-interest-icon{
width: 88rpx;
height: 88rpx;
vertical-align: top;
margin-bottom: 15rpx;
}
.open-interest-text{
font-size: 28rpx;
color: #111111;
line-height: 40rpx;
}
}
}
// 开通步骤
.open-interest-block{
padding: 30rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
.open-interest-icon{
width: 88rpx;
height: 88rpx;
}
.open-interest-text{
width: calc( 100% - 258rpx);
padding:0 30rpx;
box-sizing: border-box;
.open-interest-title{
font-weight: bold;
color: #111111;
line-height: 40rpx;
font-size: 30rpx;
}
.open-interest-submit{
color: #666666;
font-size: 26rpx;
line-height: 40rpx;
}
}
.open-interest-btn[size="mini"]{
width: 170rpx;
height: 70rpx;
line-height: 70rpx;
padding: 0;
border-radius: 35rpx;
background: $main-color;
color: white;
font-size: 30rpx;
&::after{
display: none;
}
&[disabled]{
background: #EEEEEE;
color: #999999;
}
}
}
}
</style>

304
pages/work/mailed.vue Normal file
View File

@@ -0,0 +1,304 @@
<template>
<view class="content">
<view class="mailed-back"></view>
<view class="receive" v-if="address != ''" @click="onCopy(address.name + ' ' + address.mobile + ' ' + address.full_address)">
<text class="receive-icon"></text>
<view class="receive-text">
<view class="receive-name">{{address.name}}<text>{{address.mobile}}</text></view>
<view class="receive-add">{{address.full_address}}</view>
</view>
<uni-icons class="receive-right" type="right" color="gray"></uni-icons>
</view>
<view class="material">
<view class="material-title">
<text class="material-title-text">邮寄物品</text>
<u-checkbox-group @change="onAll" v-model="checkboxAll">
<u-checkbox name="all" activeColor="#446EFE" shape="circle" label="全选" labelSize="14" labelColor="#111"></u-checkbox></text>
</u-checkbox-group>
</view>
<u-checkbox-group
v-model="checkboxValue"
iconPlacement="right"
placement="column"
@change="onCheckboxChange"
>
<view class="material-item" v-for="(item, index) in deliverCount" :key="index">
<u-checkbox :name="item.value" activeColor="#446EFE" shape="circle" :label="item.title" labelSize="14" labelColor="#111"></u-checkbox>
</view>
</u-checkbox-group>
</view>
<view class="from">
<view class="from-flex">
<label>物流单号</label>
<view class="from-inputs">
<input class="from-inputs-input" v-model="no" type="text" placeholder="请填写">
<uni-icons type="scan" color="#111" size="36rpx" @click="onScan"></uni-icons>
</view>
</view>
<view class="from-flex">
<label>物流公司</label>
<view class="from-inputs">
<picker :range="expressArr" range-key="name" @change="onPicker">
<view class="from-inputs-input" :class="{ 'hide': expressIndex == null }">{{expressIndex == null ? '请选择': expressArr[expressIndex].name}}</view>
</picker>
<uni-icons type="right" color="#999999" size="36rpx"></uni-icons>
</view>
</view>
</view>
<view class="from-btn">
<button @click="onSubmit">提交</button>
</view>
</view>
</template>
<script>
import { express, orderAddress, submitExpresses } from '@/apis/interfaces/mailed.js'
export default {
data() {
return {
address : '',
no : '',
expressIndex : null,
expressArr : [],
checkboxAll : [],
checkboxValue: [],
deliverCount : []
};
},
created() {
uni.showLoading({
title: '加载中...',
mask : true
})
Promise.all([orderAddress(this.$Route.query.orderId),express()]).then(res => {
let addressData = res[0],
expressData = res[1],
deliverOption = []
for(let key in addressData.deliver_count){
if(key == 'mobile' && !addressData.deliver_count[key]){
deliverOption.push({
value: 1,
title: '电话卡'
})
}
if(key == 'metarial' && !addressData.deliver_count[key]){
deliverOption.push({
value: 2,
title: '征信资料'
})
}
}
this.expressArr = expressData
this.deliverCount = deliverOption
this.address = addressData.address
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods: {
// 选择框
onCheckboxChange(e){
this.checkboxAll = e.length == this.deliverCount.length ? ['all'] : []
this.checkboxValue = e;
},
// 全选
onAll(e){
if(e.length > 0){
this.checkboxValue = this.deliverCount.map(val => {
return val.value
})
}else{
this.checkboxValue = []
}
},
// 提交订单物流
onSubmit(){
if(this.checkboxValue.length <= 0){
uni.showToast({
title: '请选择邮寄的物品',
icon : 'none'
})
return
}
if(this.expressIndex != ''){
uni.showToast({
title: '请选择物流公司',
icon : 'none'
})
return
}
uni.showLoading({
title: '加载中...',
mask : true
})
submitExpresses(this.$Route.query.orderId, {
express_id : this.expressArr[this.expressIndex].express_id,
number : this.no,
type : this.checkboxValue,
staff_address_id: this.address.address_id
}).then(res => {
uni.showModal({
content : '材料已邮寄',
showCancel : false,
success : () => {
if(this.deliverCount.length <= 1){
this.$store.commit('setOrderId', this.$Route.query.orderId)
}
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 选择物流公司
onPicker(e){
this.expressIndex = e.detail.value
},
// 扫码
onScan(){
uni.scanCode({
scanType: ['barCode', 'qrCode'],
success: res => {
let { result } = res;
this.no = result;
}
})
},
// 复制地址
onCopy(e){
uni.setClipboardData({
data: e,
success: res => {
uni.showToast({
title: '地址已复制',
icon : 'none'
})
}
})
}
}
}
</script>
<style lang="scss">
.mailed-back{
background: $main-color;
height: 150rpx;
}
// 按钮
.from-btn{
padding: 30rpx;
button{
background: $main-color;
color: white;
font-size: 32rpx;
height: 100rpx;
line-height: 100rpx;
padding: 0;
border-radius: 20rpx;
}
}
// 表单
.from{
background: white;
border-radius: 20rpx;
padding: 10rpx 30rpx;
margin: 30rpx;
.from-flex{
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
label{
width: 150rpx;
line-height: 90rpx;
}
.from-inputs{
width: calc(100% - 150rpx);
display: flex;
justify-content: flex-end;
align-items: center;
.from-inputs-input{
font-size: 30rpx;
text-align: right;
margin-right: 30rpx;
flex: 1;
height: 90rpx;
line-height: 90rpx;
&.hide{
color: gray;
}
}
}
}
}
// 邮寄物品
.material{
background: white;
border-radius: 20rpx;
padding: 30rpx;
margin: 30rpx;
.material-title{
padding-bottom: 20rpx;
font-size: 30rpx;
display: flex;
justify-content: space-between;
&-text{
font-weight: bold;
}
}
.material-item{
padding: 20rpx 0;
}
}
// 邮寄信息
.receive{
background-color: white;
margin: -130rpx 30rpx 0;
border-radius: 20rpx;
padding: $padding;
display: flex;
justify-content: space-between;
align-items: center;
.receive-icon{
background: $main-color;
color: white;
width: 48rpx;
height: 48rpx;
line-height: 48rpx;
border-radius: 10rpx;
display: inline-block;
font-size: 28rpx;
text-align: center;
}
.receive-text{
width: calc(100% - 130rpx);
.receive-name{
padding-bottom: 5rpx;
font-weight: bold;
font-size: 32rpx;
text{
font-size: 90%;
margin-left: 20rpx;
font-weight: normal;
color: #111;
}
}
.receive-add{
font-size: 28rpx;
color: #111;
}
}
.receive-right{
color: gray;
}
}
</style>

19
pages/work/mailedInfo.vue Normal file
View File

@@ -0,0 +1,19 @@
<template>
<view class="content">
邮寄信息详情
</view>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

209
pages/work/modifyOrder.vue Normal file
View File

@@ -0,0 +1,209 @@
<template>
<view class="content">
<block v-if="orders.length > 0">
<view v-for="(item, index) in orders" :key="index" class="order-block">
<view class="order-header">
<view class="order-header-no nowrap">{{item.order_no}}</view>
<view class="order-header-price nowrap">{{item.total}}</view>
</view>
<view class="order-content">
<view class="order-content-item">
<label>订单类型</label>
<view class="order-content-val order-content-type nowrap">
<text class="order-type" v-for="(citem, cindex) in item.item_type" :key="cindex" v-if="citem.number > 0">{{citem.title}}×{{citem.number}}</text>
</view>
</view>
<view class="order-content-item">
<label>客户姓名</label>
<view class="order-content-val nowrap">{{ item.user.nickname }}</view>
</view>
<view class="order-content-item">
<label>客户电话</label>
<view class="order-content-val nowrap">{{ item.user.username }}</view>
</view>
<view class="order-content-item">
<label>服务包数量</label>
<view class="order-content-val nowrap">×{{ item.services.length }}</view>
</view>
<view class="order-content-item">
<label>创建时间</label>
<view class="order-content-val nowrap">{{item.created_at}}</view>
</view>
</view>
<view class="order-btns">
<button class="order-left-btn" size="mini" @click="onCallPhone(item.user.username)">联系客户</button>
<view class="order-right">
<button size="mini" @click="$Router.push({name: 'WorkPerfectChoose', params: {orderId: item.business_order_id, type: 'perfect'}})">修改</button>
<button size="mini" @click="$Router.push({name: 'OrderInfo', params: {orderId: item.business_order_id}})">查看</button>
</view>
</view>
</view>
</block>
<block v-else>
<view class="null">
<u-empty
mode="order"
icon="http://cdn.uviewui.com/uview/empty/order.png"
>
</u-empty>
</view>
</block>
</view>
</template>
<script>
import { ordersEditorders } from '@/apis/interfaces/order.js'
export default {
data() {
return {
orders: [],
page : ''
}
},
created() {
this.getList()
},
onShow() {
// 是否处理当前列表状态
let isOrderId = this.$store.getters.getOrderId
if(isOrderId != null){
this.removeListVal(isOrderId)
}
},
methods:{
// 联系客户
onCallPhone(phone){
uni.makePhoneCall({
phoneNumber: phone
})
},
// 获取订单列表
getList(){
ordersEditorders().then(res => {
let { data, page } = res;
this.orders = data
this.page = page
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 变更当前列表状态
removeListVal(id){
let ListArr = this.orders
let ListIndex = ListArr.findIndex(val => val.business_order_id == id)
if(ListIndex >= 0){
this.orders.splice(ListIndex, 1)
}
this.$store.commit('setOrderId', null)
},
}
}
</script>
<style lang="scss">
.content{
padding: 1rpx 0;
box-sizing: border-box;
}
.null{
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
// 订单模块
.order-block{
background-color: white;
margin: 30rpx;
border-radius: 20rpx;
.order-header{
display: flex;
justify-content: space-between;
border-bottom: solid 1rpx #f6f6f6;
padding: 15rpx 30rpx;
line-height: 80rpx;
font-size: 30rpx;
&-no{
color: gray;
width: calc(100% - 200rpx);
}
&-price{
font-weight: bold;
color: red;
width: 200rpx;
text-align: right;
}
}
.order-content{
padding: 20rpx 30rpx;
&-item{
display: flex;
justify-content: space-between;
line-height: 70rpx;
font-size: 30rpx;
label{
width: 200rpx;
color: gray;
}
.order-content-val{
width: calc(100% - 200rpx);
text-align: right;
}
.order-content-type{
text{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
}
}
}
.order-btns{
display: flex;
justify-content: space-between;
border-top: solid 1rpx #f6f6f6;
padding: 20rpx 30rpx;
button[size="mini"]{
margin: 0;
padding: 0;
height: 70rpx;
line-height: 68rpx;
border-radius: 40rpx;
padding: 0 30rpx;
font-size: 30rpx;
background: white;
color: $main-color;
border:solid 1rpx $main-color;
&::after{
display: none;
}
}
.order-right{
button[size="mini"]{
margin-left: 30rpx;
background: $main-color;
color: white;
}
}
}
}
</style>

304
pages/work/orderInfo.vue Normal file
View File

@@ -0,0 +1,304 @@
<template>
<view class="content" v-if="order_no != ''">
<view class="order-header"></view>
<!-- 订单主要信息 -->
<view class="order-back order-flex order-info">
<view class="order-state">{{statusText}}</view>
<view class="order-item">
<label>服务类型</label>
<view class="order-value nowrap">
<text class="order-type" v-for="(item, index) in item_type" :key="index" v-if="item.number > 0">{{item.title}}×{{item.number}}</text>
</view>
</view>
<view class="order-items">
<view class="order-items-flex" v-for="(item, index) in items" :key="index" @click="$Router.push({ name: 'OrderSchemes', params: { id: item.business_order_item_id }})">
<label>{{item.institution.title}}({{item.business_type.title}})</label>
<view class="order-items-type nowrap">{{item.price}}<uni-icons type="right" color="gray" size="14px"></uni-icons></view>
</view>
</view>
<view class="order-item">
<label>欠款总金额</label>
<view class="order-value order-value-price nowrap">{{serviceTotal}}</view>
</view>
</view>
<!-- 订单服务包信息 -->
<view class="order-back order-flex" v-if="services.length > 0">
<view class="order-title">服务包</view>
<view class="order-serve">
<block v-for="(item, index) in services" :key="index">
<view class="serve-header">
{{item.title}}<text>{{item.price}}</text>
</view>
<view class="serve-item" v-for="(citem, cindex) in item.items" :key="cindex">
<view class="services-flex">
<label class="services-flex-label nowrap">服务类型</label>
<view class="services-flex-val nowrap">{{citem.business}}({{citem.type}})</view>
</view>
<view class="services-flex">
<label class="services-flex-title nowrap">{{citem.title}}</label>
<view class="services-flex-price nowrap"><text></text>{{citem.price}}</view>
</view>
</view>
</block>
</view>
</view>
<!-- 客户信息 -->
<view class="order-back order-flex">
<view class="order-title">客户信息</view>
<view class="order-item">
<label>客户姓名</label>
<view class="order-value nowrap">{{user.nickname || '-'}}</view>
</view>
<view class="order-item">
<label>客户性别</label>
<view class="order-value nowrap">{{user.sex || '-'}}</view>
</view>
<view class="order-item">
<label>客户电话</label>
<view class="order-value nowrap">{{user.username || '-'}}</view>
</view>
<view class="order-btn" @click="onCallPhone(user.username)">联系客户</view>
</view>
<!-- 订单其他信息 -->
<view class="order-back order-flex">
<view class="order-title">订单信息</view>
<view class="order-item">
<label>订单编号</label>
<view class="order-value nowrap">{{order_no || '-'}}</view>
</view>
<view class="order-item">
<label>创建时间</label>
<view class="order-value nowrap">{{created_at || '-'}}</view>
</view>
<view class="order-item">
<label>订单金额</label>
<view class="order-value nowrap">{{total || '-'}}</view>
</view>
</view>
</view>
</template>
<script>
import { info } from '@/apis/interfaces/order.js'
export default {
data() {
return {
orderId : '',
total : '0.00',
order_no : '',
statusText : '',
created_at : '',
user : {
nickname : '',
sex : '',
username : ''
},
item_type : [],
items : [],
services : [],
serviceTotal: ''
};
},
onShow() {
this.orderId = this.$Route.query.orderId
this.getInfo()
},
methods: {
// 订单详情
getInfo(){
info(this.orderId).then(res => {
let { status, created_at, total, order_no, user, item_type, items, services, service_prices } = res
this.statusText = status.text
this.created_at = created_at
this.total = total
this.order_no = order_no
this.user = user
this.item_type = item_type
this.items = items
this.services = services
this.serviceTotal = service_prices
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 刷新列表订单
onRefreshOrder(){
this.$store.commit('setOrderId', this.$Route.query.orderId)
},
// 拨打电话
onCallPhone(phone){
uni.makePhoneCall({
phoneNumber: phone,
fail(err) {
uni.showToast({
title: err.message,
icon : 'none'
})
}
})
}
}
}
</script>
<style lang="scss">
// header
.order-header{
background: #446EFE;
height: 150rpx;
}
// 订单块
.order-back{
background: white;
border-radius: 20rpx;
margin: 0 30rpx 30rpx;
}
// 订单信息
.order-info{
margin: -100rpx 30rpx 30rpx;
.order-state{
font-weight: bold;
font-size: 30rpx;
margin: 0 -30rpx;
padding: 0 30rpx;
border-bottom: solid 1rpx #f6f6f6;
padding-bottom: 20rpx;
line-height: 80rpx;
font-size: 48rpx;
}
}
// 订单列表
.order-flex{
padding: 20rpx 30rpx;
.order-title{
font-weight: bold;
font-size: 36rpx;
line-height: 60rpx;
}
// 订单信息
.order-item{
display: flex;
justify-content: space-between;
line-height: 80rpx;
font-size: 30rpx;
label{
width: 200rpx;
}
.order-value{
color: gray;
width: calc(100% - 200rpx);
text-align: right;
.order-type{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
&.order-value-price{
color: red;
font-weight: bold;
}
}
}
// 服务包信息
.order-serve{
background-color: rgba(68, 110, 254, .03);
border-radius: 10rpx;
margin: 15rpx 0;
padding: 0 25rpx;
.serve-header{
display: flex;
padding-top: 20rpx;
padding-bottom: 20rpx;
justify-content: space-between;
font-weight: bold;
border-bottom: solid 1rpx #f6f6f6;
text{
color: red;
}
}
.serve-item{
border-bottom: solid 1rpx #f6f6f6;
padding: 20rpx 0;
&:last-child{
border: none;
}
}
.services-flex{
display: flex;
font-size: 30rpx;
line-height: 55rpx;
.services-flex-label{
width: 150rpx;
color: #111111;
}
.services-flex-val{
width: calc(100% - 150rpx);
text-align: right;
color: gray;
}
.services-flex-title{
width: 50%;
color: #111111;
font-size: 30rpx;
}
.services-flex-price{
font-size: 30rpx;
width: 50%;
text-align: right;
font-weight: bold;
color: #111111;
}
}
}
// 订单服务项目
.order-items{
background-color: rgba(68, 110, 254, .03);
border-radius: 10rpx;
margin-bottom: 10rpx;
padding: 20rpx 30rpx;
.order-items-flex{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
line-height: 60rpx;
font-size: 28rpx;
label{
width: 340rpx;
}
.order-items-type{
width: calc(100% - 340rpx);
text-align: right;
color: gray;
}
}
}
// 订单按钮
.order-btn{
margin: 0 -30rpx;
padding: 20rpx 30rpx 0;
border-top: solid 1rpx #f6f6f6;
text-align: center;
line-height: 60rpx;
color: $main-color;
font-size: 32rpx;
}
}
</style>

424
pages/work/orders.vue Normal file
View File

@@ -0,0 +1,424 @@
<template>
<view class="content">
<!-- tabs -->
<u-sticky bgColor="#FFF" zIndex="9" >
<u-tabs
:current="tabsCurrent"
:list="tabs"
lineColor="#446EFE"
:activeStyle="{
color: '#111',
fontWeight: 'bold',
fontSize: '32rpx'
}"
:inactiveStyle="{
color: '#606266',
fontSize: '30rpx'
}"
@click="onTabs"
></u-tabs>
</u-sticky>
<!-- 订单管理列表 -->
<view class="orders" v-if="orders.length > 0">
<view class="orders-item" v-for="(item, index) in orders" :key="index">
<view class="orders-flex">
<view class="no nowrap">
<text class="orders-tag" v-if="!item.is_my">客户</text>
<text class="orders-tag order-tag-my" v-else>个人</text>
{{item.order_no}}
</view>
<view class="state">{{item.status.text}}</view>
</view>
<view class="orders-content">
<view class="orders-content-item">
<label>业务类型</label>
<view class="nowrap orders-content-type">
<text v-for="(itemType, indexType) in item.item_type" :key="indexType" v-if="itemType.number > 0">{{itemType.title}}x{{itemType.number}}</text>
</view>
</view>
<view class="orders-content-block">
<view class="item-flex" v-for="(citem, cindex) in item.items" :key="cindex">
<view class="item-flex-title">{{citem.institution.title}}({{citem.business_type.title}})</view>
<view class="item-flex-value">{{citem.price}}</view>
</view>
</view>
<view class="orders-content-item" v-if="item.total > 0">
<label>咨询服务费</label>
<view class="nowrap">{{item.total}}</view>
</view>
<view class="orders-content-item">
<label>下单时间</label>
<view class="nowrap">{{item.created_at}}</view>
</view>
</view>
<view class="orders-flex">
<view class="user">
<image class="user-cover" :src="item.user.avatar" mode="aspectFill"></image>
<view class="user-name">{{item.user.nickname}}</view>
</view>
<view class="btns">
<view class="btns-item btns-border" v-if="item.deliver_count.can && item.deliver_count.num < item.deliver_count.all" @click="$Router.push({name: 'MailedOrder', params: {orderId: item.business_order_id}})">{{item.deliver_count.num}}/{{item.deliver_count.all}})邮寄材料</view>
<view class="btns-item btns-border" v-if="item.can.transfer" @click="onTransfers(index, item)">转让</view>
<view class="btns-item btns-border" v-if="item.status.value == 2" @click="onOrdersService(item.business_order_id)">匹配</view>
<view class="btns-item btns-border" v-if="item.status.value == 4 && item.is_my" @click="onSign(item.business_order_id)">签约</view>
<view class="btns-item btns-border" v-if="item.status.value == 3" @click="$Router.push({name: 'Pay', params: {orderId: item.business_order_id, type: 'acting', paytype: 'price'}})">缴费</view>
<view class="btns-item btns-border" v-if="item.status.value == 5" @click="$Router.push({name: 'WorkPerfectChoose', params: {orderId: item.business_order_id, type: 'perfect'}})">完善</view>
<view class="btns-item" @click="$Router.push({name: 'OrderInfo', params: {orderId: item.business_order_id}})">查看</view>
</view>
</view>
</view>
</view>
<!-- 订单是空的 -->
<view class="order-null" v-else>
<u-empty
mode="order"
icon="http://cdn.uviewui.com/uview/empty/order.png"
text="暂无相关订单"
>
</u-empty>
</view>
<!-- 转让订单 -->
<u-action-sheet
:actions="actionLevels"
description="请选择订单转让对象"
cancelText="取消"
round="10"
:show="actionShow"
@close="actionShow = false"
@select="onActionSheet"
></u-action-sheet>
</view>
</template>
<script>
import { lists, orderSign, getOrderSignStatus } from '@/apis/interfaces/order.js'
import { levels, transfer } from '@/apis/interfaces/transfers.js'
export default {
data() {
return {
tabsCurrent : 0,
tabType : 0,
tabs : [
{val: 0, name: '待预约'},
{val: 2, name: '匹配服务包'},
{val: 3, name: '待缴服务费'},
{val: 4, name: '待签约'},
{val: 5, name: '待完善资料'},
{val: 6, name: '初审中'},
{val: 7, name: '复审中'},
{val: 8, name: '办理中'},
{val: 9, name: '待结案'},
{val: 10, name: '办理完成'}
],
orders : [],
actionShow : false,
actionLevels: [],
getSignState: false,
getNextTab : false,
};
},
created() {
let { type } = this.$Route.query
this.tabType = type;
this.tabsCurrent = this.tabs.findIndex(val => val.val == type);
this.getList()
},
onShow() {
// 是否处理当前列表状态
let isOrderId = this.$store.getters.getOrderId
if(isOrderId != null){
if(this.getSignState){
this.onGetSign(isOrderId)
return
}
// 匹配服务包变更了状态切换tab栏目获取新的列表数据
if(this.getNextTab){
this.tabsCurrent = this.tabsCurrent + 1
this.tabType = this.tabs[this.tabsCurrent].val
this.getList()
this.getNextTab = false;
this.$store.commit('setOrderId', null)
return
}
this.getList()
// this.removeListVal(isOrderId)
}
},
methods: {
// 切换列表
onTabs(e){
this.tabsCurrent = e.index
this.tabType = e.val
this.getList()
},
// 变更当前列表状态
removeListVal(id){
let ListArr = this.orders
let ListIndex = ListArr.findIndex(val => val.business_order_id == id)
if(ListIndex >= 0){
this.orders.splice(ListIndex, 1)
}
this.$store.commit('setOrderId', null)
},
// 获取列表
getList(){
this.$store.commit('setOrderId', null)
lists({
status: this.tabType
}).then(res => {
let { data } = res;
this.orders = data
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 获取转让对象
onTransfers(index, item){
levels(item.business_order_id).then(res => {
let ActionSheet = []
for(let key in res){
ActionSheet.push({
key,
name : res[key],
val : item,
index
})
}
this.actionLevels = ActionSheet
this.actionShow = true
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 转让订单
onActionSheet(e){
uni.showLoading({
title: '提交中',
mask : true
})
transfer(e.val.business_order_id, e.key).then(res => {
uni.hideLoading()
uni.showModal({
title : '提示',
content : res,
showCancel : false,
success: () => {
e.val.can.transfer = false
this.$set(this.orders, e.index, e.val)
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 匹配服务包
onOrdersService(id){
this.$Router.push({
name: 'OrdersService',
params: {
orderId: id,
},
});
this.getNextTab = true;
},
// 签约
onSign(id){
uni.showLoading({
title: '获取签约信息...',
mask : true
})
orderSign(id, {
app_scheme: "doufire://"
}).then(res => {
this.$store.commit('setOrderId', id)
this.getSignState = true
plus.runtime.openURL(res.sign_url)
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 查询订单签约状态
onGetSign(id){
uni.showLoading({
title: '加载中...',
mask : true
})
this.getSignState = false
this.$store.commit('setOrderId', null)
getOrderSignStatus(id).then(res => {
if(res.status){
this.removeListVal(id)
}
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
// 订单为空
.order-null{
height: 80vh;
display: flex;
justify-content: center;
align-items: center;
}
// 订单列表
.orders{
padding: 30rpx 0 10rpx;
.orders-item{
margin: 0 30rpx 20rpx;
background-color: white;
border-radius: $radius;
}
.orders-content{
padding: 20rpx 30rpx;
&-item{
line-height: 70rpx;
display: flex;
justify-content: space-between;
font-size: 30rpx;
color: #111111;
label{
color: #999999;
}
}
&-type{
text{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
}
&-block{
background: rgba(68, 110, 254, .03);
padding: 20rpx;
font-size: 28rpx;
border-radius: 10rpx;
margin: 10rpx 0;
.item-flex{
display: flex;
justify-content: space-between;
line-height: 50rpx;
}
}
}
.orders-flex{
border-bottom: solid 1rpx #F6F6F6;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx $padding;
&:last-child{
border-top: solid 1rpx #F6F6F6;
border-bottom: none;
}
.orders-tag{
display: inline-block;
background: $main-color;
font-size: 26rpx;
color: white;
border-radius: 10rpx;
padding: 0 10rpx;
height: 40rpx;
line-height: 40rpx;
margin-right: 10rpx;
&.order-tag-my{
background: $text-price;
}
}
.no{
font-size: 30rpx;
color: #111;
line-height: 60rpx;
width: calc(100% - 150rpx);
}
.state{
color: $main-color;
font-weight: bold;
font-size: 30rpx;
line-height: 60rpx;
width: 150rpx;
text-align: right;
}
.user{
padding-left: 90rpx;
position: relative;
min-height: 70rpx;
box-sizing: border-box;
width: calc(100% - 400rpx);
.user-cover{
position: absolute;
left: 0;
top: 0;
width: 70rpx;
height: 70rpx;
border-radius: 50%;
background: #ddd;
}
.user-name{
line-height: 70rpx;
font-size: 30rpx;
font-weight: bold;
}
}
.btns{
width: 400rpx;
text-align: right;
.btns-item{
display: inline-block;
height: 70rpx;
line-height: 70rpx;
background: $main-color;
color: white;
border-radius: 35rpx;
padding: 0 30rpx;
font-size: 30rpx;
&.btns-border{
line-height: 68rpx;
box-sizing: border-box;
border:solid 1rpx $main-color;
background: white;
color: $main-color;
margin-right: 20rpx;
}
}
}
}
}
</style>

312
pages/work/perfectBasis.vue Normal file
View File

@@ -0,0 +1,312 @@
<template>
<view class="content">
<block v-if="!loding">
<view class="from">
<view class="from-item from-item-50">
<label><text>*</text>姓名</label>
<input class="from-input" disabled v-model="baseInfo.name" type="text" placeholder="真实姓名">
</view>
<view class="from-item from-item-50">
<label><text>*</text>性别</label>
<input class="from-input" disabled v-model="baseInfo.sex" type="text" placeholder="性别">
</view>
<view class="from-item from-item-50">
<label><text>*</text>年龄</label>
<input class="from-input" disabled v-model="baseInfo.age" type="text" placeholder="年龄">
</view>
<view class="from-item from-item-50">
<label><text>*</text>属相</label>
<input class="from-input" disabled v-model="baseInfo.zodiak" type="text" placeholder="属相">
</view>
<view class="from-item from-item-100">
<label>
<text>*</text>婚姻
<uni-icons v-if="baseInfo.check_params.marriage" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.marriage.description)"></uni-icons>
</label>
<picker
:disabled="isCheck && !baseInfo.check_params.hasOwnProperty('marriage')"
class="from-picker"
:range="baseInfo.marriages"
:value="baseInfo.marriage"
@change="baseInfo.marriage = $event.detail.value"
>
<view class="from-picker-text">
<view class="nowrap">{{baseInfo.marriages[baseInfo.marriage]}}</view>
<u-icon class="icon" name="arrow-down-fill" color="#999" size="10"></u-icon>
</view>
</picker>
</view>
<view class="from-item from-item-100" v-if="baseInfo.marriage == 1">
<label>
<text>*</text>配偶姓名
<uni-icons v-if="baseInfo.check_params.mate" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.mate.description)"></uni-icons>
</label>
<input
class="from-input"
v-model="baseInfo.mate"
type="text"
placeholder="输入配偶姓名"
>
</view>
<view class="from-item from-item-50">
<label>
<text>*</text>学历
<uni-icons v-if="baseInfo.check_params.marriage" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.education.description)"></uni-icons>
</label>
<picker class="from-picker" :range="baseInfo.educations" :value="baseInfo.education" @change="baseInfo.education = $event.detail.value">
<view class="from-picker-text">
<view class="nowrap">{{baseInfo.educations[baseInfo.education]}}</view>
<u-icon class="icon" name="arrow-down-fill" color="#999" size="10"></u-icon>
</view>
</picker>
</view>
<view class="from-item from-item-50">
<label>
<text>*</text>毕业院校
<uni-icons v-if="baseInfo.check_params.school" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.school.description)"></uni-icons>
</label>
<input class="from-input" type="text" v-model="baseInfo.school" placeholder="输入毕业院校">
</view>
<view class="from-item from-item-100">
<label><text>*</text>身份证号</label>
<input class="from-input" disabled type="text" v-model="baseInfo.id_card" placeholder="身份证号">
</view>
<view class="from-item from-item-100">
<label><text>*</text>身份证地址</label>
<input class="from-input" type="text" disabled v-model="baseInfo.address" placeholder="身份证地址">
</view>
<view class="from-item from-item-100">
<label>
<text>*</text>联系电话
<uni-icons v-if="baseInfo.check_params.mobile" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.mobile.description)"></uni-icons>
</label>
<input class="from-input" type="number" v-model="baseInfo.mobile" placeholder="输入的联系电话">
</view>
<view class="from-item from-item-100">
<label>
<text>*</text>联系地址
<uni-icons v-if="baseInfo.check_params.contact_address" class="from-icon" type="info" size="18" color="red" @click="modifyToast(baseInfo.check_params.contact_address.description)"></uni-icons>
</label>
<view class="from-city-picker">
<uni-data-picker
:localdata="cityPicker"
:border="false"
split="-"
placeholder="选择城市"
v-model="baseInfo.district_id"
@change="onCityPicker"
></uni-data-picker>
</view>
</view>
<view class="from-item from-item-100">
<textarea class="from-textarea" auto-height type="text" v-model="baseInfo.tmp_address" placeholder="输入详细地址"></textarea>
</view>
</view>
<view class="btn">
<button size="default" @click="onSubmit">提交基础资料</button>
</view>
</block>
</view>
</template>
<script>
import { perfectBase, updPerfectBase } from '@/apis/interfaces/order.js'
import { region } from '@/apis/interfaces/address.js'
export default {
data() {
return {
loding : true,
orderId : '',
baseInfo : {},
cityPicker : [],
isCheck : false
};
},
created() {
this.orderId = this.$Route.query.orderId
uni.showLoading({
title: '加载中...',
mask : true
})
region().then(res => {
this.cityPicker = res;
this.getPerfectBase()
}).then(err => {
uni.showToast({
title: '获取城市信息失败:' + err.message,
icon : 'none'
})
})
},
methods: {
// 获取用户基础信息
getPerfectBase(){
perfectBase(this.orderId).then(res => {
let { base, province } = res;
console.log(res)
console.log(base.check_params.toString() != '')
this.baseInfo = base;
this.isCheck = base.check_params.toString() != ''
console.log(base.check_params)
this.loding = false;
uni.hideLoading()
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 选择城市
onCityPicker(e){
let { value } = e.detail
this.baseInfo.district_id = value[0].value
this.baseInfo.city_id = value[1].value
this.baseInfo.province_id = value[2].value
},
// 提交基础资料
onSubmit(){
let data = {
mobile : this.baseInfo.mobile,
marriage : this.baseInfo.marriage,
mate : this.baseInfo.mate,
education : this.baseInfo.education,
school : this.baseInfo.school,
tmp_address : this.baseInfo.tmp_address,
province_id : this.baseInfo.district_id,
city_id : this.baseInfo.city_id,
district_id : this.baseInfo.province_id
}
updPerfectBase(this.orderId, data).then(res => {
uni.showModal({
title : '提示',
content : '资料已保存',
showCancel : false,
success : ModalRes => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 修改提示信息
modifyToast(text){
uni.showModal({
title : '驳回原因',
content : text || '-',
showCancel : false,
})
}
}
}
</script>
<style lang="scss">
.content{
padding-top: 30rpx;
box-sizing: border-box;
}
// btn
.btn{
padding: 0 30rpx 60rpx 30rpx;
button[size="default"]{
color: white;
height: 100rpx;
line-height: 100rpx;
border-radius: 45rpx;
background-color: $main-color;
padding: 0;
border-radius: 20rpx;
font-size: 34rpx;
&::after{
display: none;
}
}
}
// form
.from{
margin:0 30rpx 30rpx 30rpx;
background: white;
display: flex;
flex-wrap: wrap;
border-radius: 20rpx;
padding: 15rpx;
.from-item{
margin: 15rpx;
&.from-item-50{
width: calc(50% - 30rpx);
}
&.from-item-100{
width: calc(100% - 30rpx);
}
label{
color: #111111;
font-size: 30rpx;
padding-bottom: 20rpx;
display: block;
& > text{
color: #FF0101;
margin-right: 5rpx;
display: inline-block;
}
.from-icon{
vertical-align: top;
margin-left: 10rpx;
}
}
.from-input{
background: #F6F6F6;
width: 100%;
height: 90rpx;
border-radius: 10rpx;
padding: 0 30rpx;
box-sizing: border-box;
font-size: 30rpx;
}
.from-textarea{
padding: 20rpx 30rpx;
background: #F6F6F6;
width: 100%;
box-sizing: border-box;
font-size: 30rpx;
line-height: 50rpx;
border-radius: 10rpx;
}
.from-picker{
.from-picker-text{
position: relative;
background: #F6F6F6;
width: 100%;
height: 90rpx;
line-height: 90rpx;
border-radius: 10rpx;
font-size: 30rpx;
padding: 0 90rpx 0 30rpx;
box-sizing: border-box;
& > .icon{
position: absolute;
right: 30rpx;
top: 50%;
margin-top: -10rpx;
}
}
}
.from-city-picker{
@extend .from-picker;
.from-picker-text{
text{
margin-left: 10rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,192 @@
<template>
<view class="perfect">
<view class="perfect-header">
<text v-if="isFinish == 0">完善订单资料</text>
<text v-if="isFinish == 1">订单资料审核中</text>
<text v-if="isFinish == 2">修改订单资料</text>
<image class="cover" src="@/static/background/info_back.png" mode="widthFix"></image>
</view>
<view class="perfect-list">
<view class="perfect-item" @click="onPerfect('WorkPerfectBasis', baseInfo.is_finish, baseInfo.business_order_user_id)">
<view class="cover">
<image class="cover-src" src="@/static/icons/tabs_show_01.png" mode="aspectFit"></image>
</view>
<view class="main">
<view class="title nowrap">基础信息</view>
<view class="submit nowrap">客户身份等基础信息</view>
</view>
<view class="state normal" v-if="baseInfo.is_finish == 0">待完善<u-icon class="arrow" color="#446EFE" name="arrow-right"></u-icon></view>
<view class="state" v-else-if="baseInfo.is_finish == 2">待修改<u-icon class="arrow" color="#FFAB3F" name="arrow-right"></u-icon></view>
<view class="state gray" v-else>已完善<u-icon class="arrow" color="gray" name="arrow-right"></u-icon></view>
</view>
<!-- 机构列表 -->
<block v-for="(item, index) in businessArr" :key="index">
<view class="perfect-item" @click="onPerfect('WorkPerfectInstitutions', item.is_finish, item.business_order_item_id)">
<view class="cover">
<image class="cover-src" :src="item.institution.cover" mode="aspectFit"></image>
</view>
<view class="main">
<view class="title nowrap">{{item.institution.title || '-'}}</view>
<view class="submit nowrap">{{item.business_type.title || '-'}}</view>
</view>
<view class="state normal" v-if="item.is_finish == 0">待完善<u-icon class="arrow" color="#446EFE" name="arrow-right"></u-icon></view>
<view class="state" v-else-if="item.is_finish == 2">待修改<u-icon class="arrow" color="#FFAB3F" name="arrow-right"></u-icon></view>
<view class="state gray" v-else>已完善<u-icon class="arrow" color="gray" name="arrow-right"></u-icon></view>
</view>
</block>
</view>
</view>
</template>
<script>
import { perfect } from '@/apis/interfaces/order.js'
export default {
data() {
return {
orderId : '',
baseInfo : {
name : '',
is_finish: 0
},
isFinish : 0,
businessArr : []
};
},
created() {
this.orderId = this.$Route.query.orderId
},
onShow(){
this.getPerfect()
},
methods: {
// 获取基础资料
getPerfect(){
uni.showLoading({
title : '加载中...',
mask : true
})
perfect(this.$Route.query.orderId).then(res => {
let { base, items, is_finish } = res;
this.isFinish = is_finish;
this.baseInfo = base;
this.businessArr = items;
if(is_finish == 1 && this.$Route.query.type == 'perfect'){
this.$store.commit('setOrderId', this.$Route.query.orderId)
}
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 资料导航
onPerfect(name, finish, id){
if(finish == 1) return
this.$Router.push({
name,
params: {
orderId: id
}
})
}
}
}
</script>
<style lang="scss">
.perfect{
background: #f8f8f8;
min-height: 100vh;
// header
.perfect-header{
background: linear-gradient(180deg, $main-color, #6588ff);
padding: 30rpx 50rpx 130rpx;
position: relative;
font-weight: bold;
color: white;
font-size: 46rpx;
.cover{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
// 资料列表
.perfect-list{
position: relative;
margin-top: -80rpx;
padding: 0 50rpx;
z-index: 1;
.perfect-item{
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
background: white;
border-radius: 20rpx;
padding: 40rpx;
box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, .02);
margin-bottom: 30rpx;
overflow: hidden;
.cover{
width: 180rpx;
height: 180rpx;
position: absolute;
right: 0;
bottom: -30rpx;
opacity: .15;
transform: rotate(-45deg);
&-src{
width: 180rpx;
height: 180rpx;
}
&::after{
content: " ";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to top, #ffffff, rgba(255,255,255,0));
}
}
.main{
width: calc(100% - 200rpx);
.title{
font-weight: bold;
font-size: 34rpx;
line-height: 50rpx;
}
.submit{
font-size: 28rpx;
color: gray;
line-height: 50rpx;
}
}
.state{
position: relative;
z-index: 1;
width: 200rpx;
text-align: right;
font-size: 30rpx;
color: $text-price;
.arrow{
display: inline-block;
vertical-align: middle;
margin-bottom: 5rpx;
}
&.normal{
color: $main-color;
}
&.gray{
color: gray;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,427 @@
<template>
<view class="content">
<!-- 银行基础信息 -->
<view class="block header-flex">
<image class="header-logo" :src="baseInfo.cover" mode="aspectFit"></image>
<view class="header-text">
<view class="title">{{baseInfo.title}}</view>
<view class="type">{{baseInfo.type}}</view>
</view>
</view>
<!-- 表单 -->
<view class="block form">
<block
v-for="(item, index) in params"
:key="index"
v-if="item.pre_key != null ? isShowBlock(params, item): true"
>
<view class="from-item" :class="item.flex == 50 ? 'from-item-50': 'from-item-100'">
<block v-if="item.type == 'price' || item.type == 'number' || item.type == 'text' || item.type == 'region'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<input class="from-input" v-model="item.value" :type="item.type" :placeholder="item.placeholder || '请输入'">
</block>
<!-- mobile -->
<block v-if="item.type == 'mobile'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<input class="from-input" v-model="item.value" type="number" :placeholder="item.placeholder || '请输入'">
</block>
<!-- password -->
<block v-if="item.type == 'password'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<input class="from-input" v-model="item.value" type="safe-password" password :placeholder="item.placeholder || '请输入'">
</block>
<!-- date -->
<block v-if="item.type == 'date'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<picker class="from-picker" mode="date" :value="item.value" @change="item.value = $event.detail.value">
<view class="from-picker-text">
<view class="text nowrap">{{item.value || '选择日期'}}</view>
<u-icon class="icon" name="calendar" color="#999" size="20"></u-icon>
</view>
</picker>
</block>
<!-- radio -->
<block v-if="item.type == 'radio'">
<view class="from-radio">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<radio-group @change="item.value = $event.detail.value">
<label class="from-radio-labe" v-for="(radioItem, radioIndex) in item.options" :key="radioIndex">
<radio :value="radioIndex" :checked="item.value === radioIndex" color="#446EFE" /><text>{{radioItem}}</text>
</label>
</radio-group>
</view>
</block>
<!-- checkbox -->
<block v-if="item.type == 'checkbox'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<checkbox-group @change="item.value = $event.detail.value">
<label class="checkbox-item" v-for="(checkboxItem, checkboxIndex) in item.options">
<checkbox class="checkbox-input" :checked="isChecked(checkboxIndex, item.value)" :value="checkboxIndex" color="#446EFE"></checkbox>{{checkboxItem}}
</label>
</checkbox-group>
</block>
<!-- select -->
<block v-if="item.type == 'select'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<picker class="from-picker" :range="item.options" :value="item.value" @change="item.value = $event.detail.value">
<view class="from-picker-text">
<view class="nowrap">{{item.options[item.value]}}</view>
<u-icon class="icon" name="arrow-down-fill" color="#999" size="10"></u-icon>
</view>
</picker>
</block>
<!-- textarea -->
<block v-if="item.type == 'textarea'">
<label>
<text v-if="item.is_required === 1">*</text>{{item.title}}
<uni-icons v-if="item.reason.description" class="from-icon" type="info" size="18" color="red" @click="modifyToast(item.reason.description)"></uni-icons>
</label>
<textarea class="from-textarea" v-model="item.value" :placeholder="item.placeholder"></textarea>
</block>
</view>
</block>
</view>
<!-- 提交数据 -->
<view class="form-btns">
<button size="default" @click="onSubmit('local')">暂时保存</button>
<button size="default" @click="onSubmit('serve')">提交审核</button>
</view>
</view>
</template>
<script>
import { baseBase, updBaseBase } from '@/apis/interfaces/order.js'
export default {
data() {
return {
baseInfo: {
cover: '',
title: '',
type : ''
},
params : []
};
},
computed: {
isChecked(){
return (val, vals) => {
let valsArr = vals || []
return valsArr.findIndex(v => v == val) >= 0
}
},
isShowBlock(){
return (params, item) => {
if(item.pre_key != null){
let paramsValue = params.find(v => v.key == item.pre_key)
return paramsValue.value == item.pre_value
}
return true
}
}
},
created() {
// 获取银行机构信息
this.getBaseBase()
},
methods: {
// 银行机构信息
getBaseBase(){
uni.showLoading({
title: '加载中...',
mask : true
})
baseBase(this.$Route.query.orderId).then(res => {
let { item, params } = res;
uni.getStorage({
key : 'institutions' + this.$Route.query.orderId,
success : StorageRes => {
let { data } = StorageRes
let storageParams = []
storageParams = params.map(val => {
if(val.type == 'checkbox' && data[val.key].length > 0){
val.value = data[val.key]
return val
}
val.value = data[val.key]
return val
})
this.params = storageParams
},
fail : StorageErr => {
this.params = params
},
complete: () => {
this.baseInfo = {
cover: item.institution.cover,
title: item.institution.title,
type : item.business_type.title
}
uni.hideLoading()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 提交银行资料
onSubmit(type){
uni.showLoading({
title: '加载中...',
mask : true
})
let subData = {};
let dataArr = [];
for(let val of this.params){
if(val.type == 'checkbox'){
subData[val.key] = val.value || []
} else subData[val.key] = val.value
}
if(type === 'local'){
uni.setStorage({
key : 'institutions' + this.$Route.query.orderId,
data : subData,
success : res => {
uni.showToast({
title: '表单信息已存储',
icon : 'none'
})
}
})
return
}
// 组织提交数据
for(let key in subData){
dataArr.push({
key,
value: subData[key]
})
}
updBaseBase(this.$Route.query.orderId, {
data: dataArr
}).then(res => {
uni.showModal({
title : '提示',
content : '机构资料已保存',
showCancel : false,
success : ModalRes => {
uni.removeStorageSync('institutions' + this.$Route.query.orderId)
this.$Router.back()
}
})
uni.hideLoading()
}).catch(err => {
console.log(err)
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 修改提示信息
modifyToast(text){
uni.showModal({
title : '驳回原因',
content : text || '-',
showCancel : false,
})
}
}
}
</script>
<style lang="scss">
.content{
padding-top: 1rpx;
box-sizing: border-box;
}
.block{
background: white;
margin: 30rpx 30rpx;
border-radius: 20rpx;
}
// 表单按钮
.form-btns{
padding: 0 15rpx 50rpx;
display: flex;
button[size="default"]{
width: calc(50% - 30rpx);
margin: 0 15rpx;
color: white;
height: 100rpx;
line-height: 100rpx;
background-color: $main-color;
padding: 0;
border-radius: 20rpx;
font-size: 34rpx;
&:first-child{
line-height: 98rpx;
box-sizing: border-box;
background-color: white;
color: $main-color;
border:solid 1rpx $main-color;
}
&::after{
display: none;
}
}
}
// 表单
.form{
padding: 10rpx 15rpx 40rpx;
display: flex;
flex-wrap: wrap;
flex-direction: flex-start;
align-content: flex-start;
.from-item{
margin: 30rpx 15rpx 0;
label{
color: #111111;
font-size: 30rpx;
padding-bottom: 20rpx;
display: block;
& > text{
color: #FF0101;
margin-right: 5rpx;
display: inline-block;
}
.from-icon{
vertical-align: top;
margin-left: 10rpx;
}
}
&.from-item-50{
width: calc(50% - 30rpx);
}
&.from-item-100{
width: calc(100% - 30rpx);
}
// input
.from-input{
background: #F6F6F6;
width: 100%;
height: 90rpx;
border-radius: 10rpx;
padding: 0 30rpx;
box-sizing: border-box;
font-size: 30rpx;
}
// textarea
.from-textarea{
padding: 20rpx 30rpx;
background: #F6F6F6;
width: 100%;
box-sizing: border-box;
font-size: 30rpx;
line-height: 50rpx;
border-radius: 10rpx;
}
// radio
.from-radio{
width: 100%;
box-sizing: border-box;
font-size: 30rpx;
height: 60rpx;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
.from-radio-labe{
display: inline-block;
margin-left: 20rpx;
radio{
transform:scale(0.7)
}
text{
color: #999999;
}
}
}
// picker
.from-picker{
.from-picker-text{
position: relative;
background: #F6F6F6;
width: 100%;
height: 90rpx;
line-height: 90rpx;
border-radius: 10rpx;
font-size: 30rpx;
padding: 0 30rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
& > .text{
width: calc(100% - 80rpx);
}
}
}
// checkbox
.checkbox-item{
display: block;
color: #999999;
line-height: 70rpx;
.checkbox-input{
transform:scale(0.7);
vertical-align: middle;
margin-top: -5rpx;
}
}
}
}
// header
.header-flex{
padding: 30rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.header-logo{
width: 88rpx;
height: 88rpx;
}
.header-text{
width: calc(100% - 128rpx);
.title{
font-weight: bold;
line-height: 40rpx;
font-size: 32rpx;
margin-bottom: 10rpx;
}
.type{
font-size: 26rpx;
height: 40rpx;
line-height: 40rpx;
color: $main-color;
background: #ECF0FF;
display: inline-block;
padding: 0 15rpx;
border-radius: 20rpx;
}
}
}
</style>

211
pages/work/poorOrder.vue Normal file
View File

@@ -0,0 +1,211 @@
<template>
<view class="content">
<block v-if="orders.length > 0">
<view v-for="(item, index) in orders" :key="index" class="order-block">
<view class="order-header">
<view class="order-header-no nowrap">{{item.order_no}}</view>
<view class="order-header-price nowrap">{{item.total}}</view>
</view>
<view class="order-content">
<view class="order-content-item">
<label>客户姓名</label>
<view class="order-content-val nowrap">{{ item.user.nickname }}</view>
</view>
<view class="order-content-item">
<label>客户电话</label>
<view class="order-content-val nowrap">{{ item.user.username }}</view>
</view>
<view class="order-content-item">
<label>服务包数量</label>
<view class="order-content-val nowrap">×{{ item.services.length }}</view>
</view>
<view class="order-content-item">
<label>已缴纳费</label>
<view class="order-content-val nowrap">{{ item.paid }}</view>
</view>
<view class="order-content-item">
<label>需补缴费</label>
<view class="order-content-val nowrap">{{ item.price }}</view>
</view>
<view class="order-content-item">
<label>创建时间</label>
<view class="order-content-val nowrap">{{item.created_at}}</view>
</view>
</view>
<view class="order-btns">
<button class="order-left-btn" size="mini" @click="onCallPhone(item.user.username)">联系客户</button>
<view class="order-right">
<button size="mini" @click="$Router.push({name: 'Pay', params: {orderId: item.order_id, type: 'acting', paytype: 'diff'}})">补缴</button>
<button size="mini" @click="$Router.push({name: 'OrderInfo', params: {orderId: item.order_id}})">查看</button>
</view>
</view>
</view>
</block>
<block v-else>
<view class="null">
<u-empty
mode="order"
icon="http://cdn.uviewui.com/uview/empty/order.png"
>
</u-empty>
</view>
</block>
</view>
</template>
<script>
import { ordersDiffs } from '@/apis/interfaces/order.js'
export default {
data() {
return {
orders: [],
page : ''
}
},
created() {
this.getList()
},
onShow() {
// 是否处理当前列表状态
let isOrderId = this.$store.getters.getOrderId
if(isOrderId != null){
this.removeListVal(isOrderId)
}
},
methods:{
// 联系客户
onCallPhone(phone){
uni.makePhoneCall({
phoneNumber: phone
})
},
// 获取订单列表
getList(){
ordersDiffs().then(res => {
let { data, page } = res;
this.orders = data
this.page = page
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 变更当前列表状态
removeListVal(id){
let ListArr = this.orders
let ListIndex = ListArr.findIndex(val => val.business_order_id == id)
if(ListIndex >= 0){
this.orders.splice(ListIndex, 1)
}
this.$store.commit('setOrderId', null)
},
}
}
</script>
<style lang="scss">
.content{
padding: 1rpx 0;
box-sizing: border-box;
}
.null{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
// 订单模块
.order-block{
background-color: white;
margin: 30rpx;
border-radius: 20rpx;
.order-header{
display: flex;
justify-content: space-between;
border-bottom: solid 1rpx #f6f6f6;
padding: 15rpx 30rpx;
line-height: 80rpx;
font-size: 30rpx;
&-no{
color: gray;
width: calc(100% - 200rpx);
}
&-price{
font-weight: bold;
color: red;
width: 200rpx;
text-align: right;
}
}
.order-content{
padding: 20rpx 30rpx;
&-item{
display: flex;
justify-content: space-between;
line-height: 70rpx;
font-size: 30rpx;
label{
width: 200rpx;
color: gray;
}
.order-content-val{
width: calc(100% - 200rpx);
text-align: right;
}
.order-content-type{
text{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
}
}
}
.order-btns{
display: flex;
justify-content: space-between;
border-top: solid 1rpx #f6f6f6;
padding: 20rpx 30rpx;
button[size="mini"]{
margin: 0;
padding: 0;
height: 70rpx;
line-height: 68rpx;
border-radius: 40rpx;
padding: 0 30rpx;
font-size: 30rpx;
background: white;
color: $main-color;
border:solid 1rpx $main-color;
&::after{
display: none;
}
}
.order-right{
button[size="mini"]{
margin-left: 30rpx;
background: $main-color;
color: white;
}
}
}
}
</style>

187
pages/work/refundOrder.vue Normal file
View File

@@ -0,0 +1,187 @@
<template>
<view class="content">
<!-- 订单管理列表 -->
<view class="orders" v-if="orders.length > 0">
<view class="orders-item" v-for="(item, index) in orders" :key="index">
<view class="orders-flex">
<view class="no nowrap">
<text class="orders-tag" v-if="!item.is_my">客户</text>
<text class="orders-tag order-tag-my" v-else>个人</text>
{{item.order_no}}
</view>
<view class="state">{{item.status.text}}</view>
</view>
<view class="orders-content">
<view class="orders-content-item">
<label>业务类型</label>
<view class="nowrap orders-content-type">
<text v-for="(itemType, indexType) in item.item_type" :key="indexType" v-if="itemType.number > 0">{{itemType.title}}x{{itemType.number}}</text>
</view>
</view>
<view class="orders-content-block">
<view class="item-flex" v-for="(citem, cindex) in item.items" :key="cindex">
<view class="item-flex-title">{{citem.institution.title}}</view>
<view class="item-flex-value">{{citem.price}}</view>
</view>
</view>
<view class="orders-content-item" v-if="item.total > 0">
<label>咨询服务费</label>
<view class="nowrap">{{item.total}}</view>
</view>
<view class="orders-content-item">
<label>下单时间</label>
<view class="nowrap">{{item.created_at}}</view>
</view>
<view class="orders-content-item">
<label>退款时间</label>
<view class="nowrap">-</view>
</view>
</view>
</view>
</view>
<!-- 订单是空的 -->
<view class="order-null" v-else>
<u-empty
mode="order"
icon="http://cdn.uviewui.com/uview/empty/order.png"
text="暂无已退款订单"
>
</u-empty>
</view>
</view>
</template>
<script>
import { lists } from '@/apis/interfaces/order.js'
export default {
data() {
return {
orders: []
};
},
created() {
this.getList()
},
methods:{
// 获取列表
getList(){
lists({
status: 11
}).then(res => {
let { data } = res;
this.orders = data
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss">
// 订单为空
.order-null{
height: 80vh;
display: flex;
justify-content: center;
align-items: center;
}
// 订单列表
.orders{
padding: 30rpx 0 10rpx;
.orders-item{
margin: 0 30rpx 20rpx;
background-color: white;
border-radius: $radius;
}
.orders-content{
padding: 20rpx 30rpx;
&-item{
line-height: 70rpx;
display: flex;
justify-content: space-between;
font-size: 30rpx;
color: #111111;
label{
color: #999999;
}
}
&-type{
text{
margin-right: 30rpx;
position: relative;
display: inline-block;
&::after{
position: absolute;
content: "/";
width: 30rpx;
text-align: center;
font-size: 30rpx;
top: 0;
right: -30rpx;
}
&:last-child{
margin-right: 0;
&::after{
display: none;
}
}
}
}
&-block{
background: rgba(68, 110, 254, .03);
padding: 20rpx;
font-size: 28rpx;
border-radius: 10rpx;
margin: 10rpx 0;
.item-flex{
display: flex;
justify-content: space-between;
line-height: 50rpx;
}
}
}
.orders-flex{
border-bottom: solid 1rpx #F6F6F6;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx $padding;
&:last-child{
border-top: solid 1rpx #F6F6F6;
border-bottom: none;
}
.orders-tag{
display: inline-block;
background: $main-color;
font-size: 26rpx;
color: white;
border-radius: 10rpx;
padding: 0 10rpx;
height: 40rpx;
line-height: 40rpx;
margin-right: 10rpx;
&.order-tag-my{
background: $text-price;
}
}
.no{
font-size: 30rpx;
color: #111;
line-height: 60rpx;
width: calc(100% - 150rpx);
}
.state{
color: $main-color;
font-weight: bold;
font-size: 30rpx;
line-height: 60rpx;
width: 150rpx;
text-align: right;
}
}
}
</style>

206
pages/work/schemes.vue Normal file
View File

@@ -0,0 +1,206 @@
<template>
<view class="content" v-if="scheme != ''">
<view class="schemes-header">
<view class="schemes-user">您好{{user.nickname}} {{user.sex == '男'? '先生': '女士'}}</view>
<view class="schemes-text">以下是根据您的情况为您匹配的机构最佳方案由于银行政策实时变动该方案为预估方案仅供参考具体以协商为准感谢您的支持</view>
</view>
<!-- 卡片信息 -->
<view class="schemes-block">
<view class="schemes-info">
<view class="schemes-flex schemes-flex-header">
<view class="schemes-title">{{scheme.institution.title}}</view>
<text class="schemes-type">{{scheme.business_type.title}}</text>
</view>
<view class="schemes-flex" v-for="(item, index) in scheme.base" :key="index">
<view class="schemes-label">{{item.title}}</view>
<text class="schemes-value">{{item.value || '-'}}</text>
</view>
</view>
<view class="schemes-info schemes-footer">
<view class="schemes-info-title">
预估方案
<text>YGFA</text>
</view>
<block v-if="scheme.params.length > 0">
<view class="schemes-flex" v-for="(item, index) in scheme.params" :key="index">
<view class="schemes-label">{{item.title}}</view>
<text class="schemes-value">{{item.value || '-'}}</text>
</view>
</block>
<block v-else>
<view class="params-null">
<u-empty
mode="coupon"
icon="http://cdn.uviewui.com/uview/empty/coupon.png"
text="暂无预估方案"
>
</u-empty>
</view>
</block>
<view class="schemes-tips">
<view class="schemes-tips-title">须知</view>
<text>{{scheme.business_type.notic}}</text>
</view>
</view>
</view>
<!-- 温馨提示 -->
<view class="notic">
<text>{{scheme.business_type.sweet_notic}}</text>
</view>
</view>
</template>
<script>
import { getSchemes } from '@/apis/interfaces/order.js'
export default {
data() {
return {
user : { name : '', sex: '' },
scheme: '',
};
},
created() {
this.getSchemesInfo()
},
methods: {
getSchemesInfo(){
getSchemes(this.$Route.query.id).then(res => {
let { scheme, user } = res;
this.scheme = scheme
this.user = user
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss">
.content{
padding-bottom: 50rpx;
box-sizing: border-box;
}
// 温馨提示
.notic{
padding: 30rpx;
color: #FBAF3B;
font-size: 28rpx;
line-height: 40rpx;
}
// 方案
.schemes-block{
border-radius: 20rpx;
background: white;
margin: -80rpx 30rpx 0;
position: relative;
.schemes-info{
padding: 30rpx;
box-sizing: border-box;
position: relative;
border-bottom: dashed 1rpx #EEEEEE;
&.schemes-footer{
border-bottom: none;
position: relative;
&::after{
position: absolute;
top: -20rpx;
left: -20rpx;
content: " ";
width: 40rpx;
height: 40rpx;
background: #f8f8f8;
border-radius: 50%;
}
&::before{
position: absolute;
top: -20rpx;
right: -20rpx;
content: " ";
width: 40rpx;
height: 40rpx;
background: #f8f8f8;
border-radius: 50%;
}
}
.schemes-info-title{
display: flex;
justify-content: space-between;
font-weight: bold;
font-size: 40rpx;
padding-bottom: 30rpx;
color: $main-color;
text{
opacity: .3;
}
}
.params-null{
padding: 30rpx 0 50rpx;
}
.schemes-flex{
display: flex;
justify-content: space-between;
align-items: center;
.schemes-title{
font-weight: bold;
font-size: 40rpx;
line-height: 70rpx;
}
.schemes-type{
background: white;
color: $main-color;
border:solid 1rpx $main-color;
font-size: 28rpx;
padding: 0 20rpx;
line-height: 40rpx;
border-radius: 20rpx;
}
&.schemes-flex-header{
padding-bottom: 20rpx;
}
.schemes-label{
line-height: 70rpx;
font-size: 30rpx;
width: 200rpx;
color: #999999;
}
.schemes-value{
width: calc( 100% - 200rpx );
font-size: 30rpx;
text-align: right;
}
}
// 提示信息
.schemes-tips{
background: #F6F6F6;
border-radius: 20rpx;
margin-top: 30rpx;
padding: 30rpx;
font-size: 28rpx;
color: #666;
.schemes-tips-title{
font-weight: bold;
color: #111;
padding-bottom: 20rpx;
}
}
}
}
// header
.schemes-header{
background: $main-color;
padding: 30rpx 30rpx 150rpx;
color: white;
.schemes-user{
font-size: 30rpx;
padding-bottom: 20rpx;
}
.schemes-text{
font-size: 30rpx;
line-height: 45rpx;
}
}
</style>

457
pages/work/service.vue Normal file
View File

@@ -0,0 +1,457 @@
<template>
<view class="content">
<!-- 服务包列表 -->
<view class="services">
<view class="services-null" v-if="services.length <= 0">
<u-empty
mode="data"
icon="http://cdn.uviewui.com/uview/empty/data.png"
text="暂无添加服务包"
>
</u-empty>
</view>
<view class="services-list" v-else>
<view class="services-item" v-for="(item, index) in services" :key="index">
<view class="services-header">
<view class="title">{{item.title}}<text>{{item.tag}}</text></view>
<view class="remove" @click="onRemove(item, index)">移出</view>
</view>
<view class="services-content">
<block v-for="(citem, cindex) in item.items" :key="cindex">
<view class="services-content-item">
<view class="services-flex">
<label class="services-flex-label nowrap">服务类型</label>
<view class="services-flex-val nowrap">{{citem.business}}({{citem.type}})</view>
</view>
<view class="services-flex">
<label class="services-flex-title nowrap">{{citem.title}}</label>
<view class="services-flex-price nowrap"><text></text>{{citem.price}}</view>
</view>
</view>
</block>
</view>
<view class="services-price">服务包价格<text>{{item.price}}</text></view>
</view>
</view>
</view>
<!-- 选择业务 -->
<u-popup :show="institutionsShow" round="20rpx" closeable @close="institutionsShow = false, itemsVal = []">
<view class="institutions">
<view class="institutions-title">选择业务</view>
<scroll-view scroll-y class="institutions-scroll">
<view class="institutions-lists" v-if="institutions.length > 0">
<view class="institutions-block" :class="{ 'active': item.isChoose }" v-for="(item, index) in institutions" :key="index" @click="onInstitution(item, index)">
<view class="institutions-block-item">
<label>业务类型</label>
<view class="val nowrap">{{item.business}}({{item.type}})</view>
</view>
<view class="institutions-block-item">
<label>业务机构</label>
<view class="val nowrap">{{item.title}}</view>
</view>
<view class="institutions-block-item">
<label>金额</label>
<view class="val price nowrap">{{item.price}}</view>
</view>
</view>
</view>
<view v-else class="institutions-null">
<u-empty
mode="list"
icon="http://cdn.uviewui.com/uview/empty/list.png"
text="暂无可分配的业务"
>
</u-empty>
</view>
</scroll-view>
<view class="institutions-footer">
<button class="btn" @click="onAddService" :disabled="itemsVal.length <= 0">选好了({{itemsVal.length}})</button>
</view>
</view>
</u-popup>
<!-- footer -->
<view class="footer">
<view class="footer-total">{{services.length}}个服务包总价格<text>{{total}}</text></view>
<button class="footer-btn" :disabled="services.length <= 0" @click="onServiceOver">保存配置服务包</button>
</view>
</view>
</template>
<script>
import { service, serviceAdd, serviceRemove, serviceOver } from '@/apis/interfaces/order.js'
export default {
data() {
return {
total : '0.00',
orderId : '',
institutions : [],
services : [],
itemsVal : [],
institutionsShow: false
};
},
created() {
this.orderId = this.$Route.query.orderId
// 开始配置服务包
this.getService()
},
methods: {
// 获取业务
getService(){
service(this.orderId).then(res => {
let { institutions, services, total } = res;
this.institutions = institutions.map(val => {
val.isChoose = false
return val;
})
this.total = total;
this.services = services;
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 选择业务
onInstitution(val, index){
let idIndex = this.itemsVal.findIndex(e => e === val.item_id)
if(idIndex >= 0){
val.isChoose = !val.isChoose;
this.itemsVal.splice(idIndex, 1)
this.$set(this.institutions, index, val)
return
}
if(idIndex < 0 && this.itemsVal.length <= 2){
val.isChoose = !val.isChoose;
this.itemsVal.push(val.item_id)
this.$set(this.institutions, index, val)
return
}
uni.showToast({
title: '单一服务包业务数量不可以超过3项',
icon : 'none'
})
},
// 新增服务包
onAddService(){
serviceAdd(this.orderId, this.itemsVal).then(res => {
let { institutions, services, total } = res;
this.institutions = institutions.map(val => {
val.isChoose = false
return val;
});
this.total = total;
this.services = services
this.itemsVal = []
this.institutionsShow = false
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 删除服务包
onRemove(val, index){
serviceRemove(this.orderId, {
group_no: val.group_no
} ).then(res => {
let { institutions, services, total } = res;
this.institutions = institutions.map(val => {
val.isChoose = false
return val;
});
this.total = total;
this.services = services;
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 保存配置服务包
onServiceOver(){
if(this.institutions.length > 0){
uni.showModal({
title : '提示',
content : '当前还有' + this.institutions.length + '项业务未匹配服务包,是否放弃未匹配的业务继续保存服务包?',
cancelText : '继续配置',
cancelColor : '#FFAB3F',
confirmText : '立即保存',
confirmColor: '#446EFE',
success : res => {
if(res.confirm){
this.onSubmitService()
}
}
})
return
}
this.onSubmitService()
},
// 提交保存服务
onSubmitService(){
wx.showLoading({
title: '保存中...',
mask : true
})
serviceOver(this.orderId).then(res => {
uni.showModal({
content : res.message,
showCancel : false,
confirmColor: '#446EFE',
success : res => {
if(res.confirm){
this.$store.commit('setOrderId', this.orderId)
uni.navigateBack()
}
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
},
onNavigationBarButtonTap() {
this.institutionsShow = true
}
}
</script>
<style lang="scss">
// 服务包列表
.services{
padding-bottom: 250rpx;
box-sizing: border-box;
.services-null{
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
}
// 服务包列表
.services-list{
padding: 10rpx 30rpx;
.services-item{
background: white;
border-radius: 20rpx;
padding: 30rpx;
margin: 30rpx 0;
.services-header{
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
.title{
font-size: 32rpx;
font-weight: bold;
color: #111;
width: calc(100% - 150rpx);
text{
background: $main-color;
color: white;
font-weight: normal;
font-size: 26rpx;
border-radius: 10rpx;
padding: 0 10rpx;
margin-left: 10rpx;
line-height: 40rpx;
}
}
.remove{
background: rgba(68, 110, 254, .1);
color: #446EFE;
height: 50rpx;
line-height: 50rpx;
width: 100rpx;
border-radius: 25rpx;
text-align: center;
font-size: 28rpx;
}
}
.services-content{
background-color: rgba(68, 110, 254, .03);
border-radius: 10rpx;
margin: 15rpx 0;
padding: 0 25rpx;
.services-content-item{
border-bottom: solid 1rpx #f6f6f6;
padding: 20rpx 0;
&:last-child{
border: none;
}
}
.services-flex{
display: flex;
font-size: 30rpx;
line-height: 55rpx;
.services-flex-label{
width: 150rpx;
color: #111111;
}
.services-flex-val{
width: calc(100% - 150rpx);
text-align: right;
color: gray;
}
.services-flex-title{
width: 50%;
color: #111111;
font-size: 30rpx;
}
.services-flex-price{
font-size: 30rpx;
width: 50%;
text-align: right;
font-weight: bold;
color: #111111;
}
}
}
.services-price{
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
color: gray;
line-height: 60rpx;
text{
color: $text-price;
font-weight: bold;
font-size: 34rpx;
}
}
}
}
}
// 添加服务包
.institutions{
padding: 0 0 180rpx;
position: relative;
// 标题
.institutions-title{
padding: 30rpx;
text-align: center;
font-size: 36rpx;
font-weight: bold;
line-height: 60rpx;
}
// 列表
.institutions-scroll{
height: 65vh;
.institutions-null{
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
}
.institutions-lists{
padding: 15rpx 0;
.institutions-block{
margin: 15rpx 30rpx;
background: #f8f8f8;
padding: 30rpx;
border-radius: 20rpx;
border:solid 1rpx #f8f8f8;
box-sizing: border-box;
.institutions-block-item{
display: flex;
justify-content: space-between;
line-height: 50rpx;
font-size: 30rpx;
label{
color: gray;
width: 200rpx;
}
.val{
width: calc(100% - 200rpx);
text-align: right;
&.price{
color: $text-price;
font-weight: bold;
}
}
}
&.active{
background-color: #E4E8F7;
border-color: $main-color;
}
}
}
}
// footer
.institutions-footer{
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx 30rpx 50rpx;
.btn{
background: $main-color;
height: 100rpx;
line-height: 100rpx;
color: white;
font-size: 32rpx;
border-radius: $radius-lg;
&::after{
display: none;
}
&[disabled]{
background-color: $main-color;
color: white;
opacity: .7;
}
}
}
}
// footer
.footer{
padding: 30rpx 30rpx 50rpx;
background: white;
position: fixed;
width: 100%;
box-sizing: border-box;
bottom: 0;
left: 0;
z-index: 9;
box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, .02);
.footer-total{
padding-bottom: 30rpx;
text-align: center;
font-size: 30rpx;
color: gray;
line-height: 40rpx;
text{
font-weight: bold;
color: red;
}
}
.footer-btn{
background: $main-color;
height: 100rpx;
line-height: 100rpx;
color: white;
font-size: 32rpx;
border-radius: $radius-lg;
&::after{
display: none;
}
.icon{
display: inline-block;
vertical-align: middle;
margin-right: 10rpx;
margin-bottom: 5rpx;
}
&[disabled]{
background-color: $main-color;
color: white;
opacity: .7;
}
}
}
</style>

35
router/index.js Normal file
View File

@@ -0,0 +1,35 @@
import {
RouterMount,
createRouter
} from 'uni-simple-router';
import store from '@/store/index'
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routes: [...ROUTES]
});
//全局路由前置守卫
router.beforeEach((to, from, next) => {
let isToken = store.getters.getToken === '' || uni.getStorageSync('token') === ''
if(to.auth != undefined){
if(to.auth && isToken){
next({
name: 'Auth',
NAVTYPE: 'push'
})
return
}
}
next();
});
// 全局路由后置守卫
router.afterEach((to, from) => {
})
export {
router,
RouterMount
}

122
scss/globa.scss Normal file
View File

@@ -0,0 +1,122 @@
/**
* Web唐明明
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
*/
// 文字颜色
$text-color: #333;
$text-gray: #666;
$text-gray-m: #999;
$text-price: #FFAB3F;
$main-color: #446EFE;
// 边框颜色
$border-color: #ddd;
// 全局窗口色
$window-color: #F3F6FB;
// 文字尺寸
$title-size: 32rpx;
$title-size-lg: 30rpx;
$title-size-m: 28rpx;
$title-size-sm: 26rpx;
// 模块圆角
$radius: 20rpx;
$radius-lg: 12rpx;
$radius-m: 10rpx;
// 模块边距
$margin: 30rpx;
$padding: 30rpx;
// 0.5像素边线
.border-solid{
position: relative;
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1rpx;
background-image: linear-gradient(0deg, $border-color 50%, transparent 50%);
}
}
.border-solid-empty{
@extend .border-solid;
&::after{
width: calc(100% - #{$margin * 2});
left: $margin;
}
}
.border{
position: relative;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
border: 1rpx solid $border-color;
transform: scale(0.5);
transform-origin: 0 0;
pointer-events: none;
}
}
// 状态栏高度
.status_bar {
height: var(--status-bar-height);
}
/* #ifndef APP-PLUS-NVUE */
// ios安全距离
.ios-bottom{
padding-bottom: env(safe-area-inset-bottom);
padding-bottom: constant(safe-area-inset-bottom);
}
.ios-left{
padding-left: env(safe-area-inset-left);
padding-left: constant(safe-area-inset-left);
}
.ios-right{
padding-right: env(safe-area-inset-right);
padding-right: constant(safe-area-inset-right);
}
.ios-top{
padding-top: var(--status-bar-height);
}
// 公共样式
.vertical {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
}
.nowrap {
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis{
max-width: 100%;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
/* #endif */

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
static/code/code_back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

BIN
static/code/code_btn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
static/code/code_footer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

BIN
static/code/code_header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
static/code/code_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

BIN
static/code/code_sign.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

BIN
static/gliconfont.ttf Normal file

Binary file not shown.

51
static/iconfont.css Normal file
View File

@@ -0,0 +1,51 @@
@font-face {
font-family: "iconfont"; /* Project id 2869797 */
src: url('@/static/iconfont.ttf');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-jia:before {
content: "\e60a";
}
.icon-dui:before {
content: "\e609";
}
.icon-gengduo2:before {
content: "\e608";
}
.icon-gengduo:before {
content: "\e607";
}
.icon-saoma:before {
content: "\e605";
}
.icon-tuandui:before {
content: "\e606";
}
.icon-sousuo:before {
content: "\e603";
}
.icon-pinglun:before {
content: "\e601";
}
.icon-shezhi:before {
content: "\e602";
}

BIN
static/iconfont.ttf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
static/icons/pay_alipay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
static/icons/pay_code.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
static/icons/pay_wechat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
static/icons/qrcode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
static/icons/quick_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

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