Commit e77ce462 authored by Junling Bu's avatar Junling Bu
Browse files

chore[litemall-vue]: 增加用户反馈页面

parent 59ecc562
...@@ -43,10 +43,38 @@ export function authLogout() { ...@@ -43,10 +43,38 @@ export function authLogout() {
method: 'post' method: 'post'
}) })
} }
const AuthInfo='wx/auth/info'; //用户信息
export function authInfo() {
return request({
url: AuthInfo,
method: 'get'
})
}
const AuthProfile='wx/auth/profile'; //验证码
export function authProfile(data) {
return request({
url: AuthProfile,
method: 'post',
data
})
}
const AuthRegister='wx/auth/register'; //账号注册 const AuthRegister='wx/auth/register'; //账号注册
const AuthReset='wx/auth/reset'; //账号密码重置 const AuthReset='wx/auth/reset'; //账号密码重置
export function authReset(data) {
return request({
url: AuthReset,
method: 'post',
data
})
}
const AuthRegisterCaptcha='wx/auth/regCaptcha'; //验证码 const AuthRegisterCaptcha='wx/auth/regCaptcha'; //验证码
export function authRegisterCaptcha(data) {
return request({
url: AuthRegisterCaptcha,
method: 'post',
data
})
}
const AuthBindPhone='wx/auth/bindPhone'; //绑定微信手机号 const AuthBindPhone='wx/auth/bindPhone'; //绑定微信手机号
const GoodsCount='wx/goods/count'; //统计商品总数 const GoodsCount='wx/goods/count'; //统计商品总数
...@@ -282,6 +310,14 @@ const OrderGoods='wx/order/goods'; // 代评价商品信息 ...@@ -282,6 +310,14 @@ const OrderGoods='wx/order/goods'; // 代评价商品信息
const OrderComment='wx/order/comment'; // 评价订单商品信息 const OrderComment='wx/order/comment'; // 评价订单商品信息
const FeedbackAdd='wx/feedback/submit'; //添加反馈 const FeedbackAdd='wx/feedback/submit'; //添加反馈
export function feedbackAdd(data) {
return request({
url: FeedbackAdd,
method: 'post',
data
})
}
const FootprintList='wx/footprint/list'; //足迹列表 const FootprintList='wx/footprint/list'; //足迹列表
const FootprintDelete='wx/footprint/delete'; //删除足迹 const FootprintDelete='wx/footprint/delete'; //删除足迹
...@@ -350,4 +386,6 @@ export function getList(api, query) { ...@@ -350,4 +386,6 @@ export function getList(api, query) {
method: 'get', method: 'get',
params: query params: query
}) })
} }
\ No newline at end of file
export const REFUND_LIST = '';
\ No newline at end of file
import request from '@/utils/request'
// export const GOODS_CATEGORY = '/category';
export const GOODS_CATEGORY = '/wx/catalog/index';
export const GOODS_CHANNGE_CATEGORY = '/wx/catalog/current?id=';
export const GOODS_SEARCH = '/moreGoods';
export const GOODS_DETAIL = '/details';
export function goodsCategory(query) {
return request({
url: '/wx/catalog/index',
method: 'get',
params: query
})
}
export function goodsChannelCategory(query) {
return request({
url: '/wx/catalog/index',
method: 'get',
params: query
})
}
export function goodsSearch(query) {
return request({
url: '/wx/catalog/current?id=',
method: 'get',
params: query
})
}
export function goodsDetail(query) {
return request({
url: '/wx/catalog/index',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
export const ORDER_LIST = '/order-list';
export const ELE_COUPON_LIST = '/electronic-list';
export const REFUND_LIST = '/refund-list';
import request from '@/utils/request'
import request from '@/utils/request'
export const HOME_module = '/home';
export const ALL_GOODS = '/moreGoods';
export const SHOPINFO = '/shop-info';
// 运费模板
export const POST_FEE = '';
export function getHome(query) {
return request({
url: '/wx/home/index',
method: 'get',
params: query
})
}
import request from '@/utils/request'
// 登录
export const USER_LOGIN = '/wx/auth/login';
export const USER_LOGOUT = '';
// 用户信息
export const USER_PROFILE = '/user-profile';
export const USER_MODIFY_PASSWORD = '';
export const USER_CHANGE_MOBILE = '';
// 验证码
export const USER_SENDCODE = '';
// 地址
export const ADDRESS = '/address';
export const ADDRESS_DEFAULT = '/address-default';
// 收藏
export const GOODS_COLLECT_LIST = '/moreGoods';
export function loginByUsername(data) {
return request({
url: '/wx/auth/login',
method: 'post',
data
})
}
export function logout() {
return request({
url: '/auth/logout',
method: 'post'
})
}
export function getUserInfo(token) {
return request({
url: '/auth/info',
method: 'get',
params: { token }
})
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ const UserAddress = () => import('@/views/user/module-address'); ...@@ -4,6 +4,7 @@ const UserAddress = () => import('@/views/user/module-address');
const UserAddressEdit = () => import('@/views/user/module-address-edit'); const UserAddressEdit = () => import('@/views/user/module-address-edit');
const UserServer = () => import('@/views/user/module-server'); const UserServer = () => import('@/views/user/module-server');
const UserHelp = () => import('@/views/user/module-help'); const UserHelp = () => import('@/views/user/module-help');
const UserFeedback = () => import('@/views/user/module-feedback');
const UserInformation = () => import('@/views/user/user-information-set'); const UserInformation = () => import('@/views/user/user-information-set');
const UserInfo_SetBg = () => import('@/views/user/user-information-set/set-bg'); const UserInfo_SetBg = () => import('@/views/user/user-information-set/set-bg');
...@@ -61,6 +62,11 @@ export default [ ...@@ -61,6 +62,11 @@ export default [
name: 'user-help', name: 'user-help',
component: UserHelp component: UserHelp
}, },
{
path: '/user/feedback',
name: 'user-feedback',
component: UserFeedback
},
{ {
path: '/user/information', path: '/user/information',
name: 'user-information', name: 'user-information',
......
import { loginByUsername, logout, getUserInfo } from '@/api/user' import { authLoginByAccount, authLogout, authInfo } from '@/api/api'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
const user = { const user = {
...@@ -52,7 +52,7 @@ const user = { ...@@ -52,7 +52,7 @@ const user = {
LoginByUsername({ commit }, userInfo) { LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim() const username = userInfo.username.trim()
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => { authLoginByAccount(username, userInfo.password).then(response => {
const token = response.data.data const token = response.data.data
commit('SET_TOKEN', token) commit('SET_TOKEN', token)
setToken(token) setToken(token)
...@@ -69,12 +69,6 @@ const user = { ...@@ -69,12 +69,6 @@ const user = {
getUserInfo(state.token).then(response => { getUserInfo(state.token).then(response => {
const data = response.data.data const data = response.data.data
if (data.perms && data.perms.length > 0) { // 验证返回的perms是否是一个非空数组
commit('SET_PERMS', data.perms)
} else {
reject('getInfo: perms must be a non-null array !')
}
commit('SET_ROLES', data.roles) commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name) commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar) commit('SET_AVATAR', data.avatar)
...@@ -86,60 +80,22 @@ const user = { ...@@ -86,60 +80,22 @@ const user = {
}) })
}, },
// 第三方验证登录
// LoginByThirdparty({ commit, state }, code) {
// return new Promise((resolve, reject) => {
// commit('SET_CODE', code)
// loginByThirdparty(state.status, state.email, state.code).then(response => {
// commit('SET_TOKEN', response.data.token)
// setToken(response.data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
// },
// 登出 // 登出
LogOut({ commit, state }) { LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { authLogout(state.token).then(() => {
commit('SET_TOKEN', '') commit('Authorization', '')
commit('SET_ROLES', []) commit('avatar', '')
commit('SET_PERMS', []) commit('background_image', [])
commit('nickName', [])
removeToken() removeToken()
resolve() resolve()
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })
}) })
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
},
// 动态修改权限
ChangeRoles({ commit, dispatch }, role) {
return new Promise(resolve => {
commit('SET_TOKEN', role)
setToken(role)
getUserInfo(role).then(response => {
const data = response.data
commit('SET_ROLES', data.roles)
commit('SET_PERMS', data.perms)
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve()
})
})
} }
} }
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
</template> </template>
<script> <script>
import { goodsCategory, goodsChannelCategory } from '@/api/goods'; import { catalogList } from '@/api/api';
import getLocationParam from '@/utils/location-param'; import getLocationParam from '@/utils/location-param';
import { Search } from 'vant'; import { Search } from 'vant';
...@@ -52,7 +52,7 @@ export default { ...@@ -52,7 +52,7 @@ export default {
methods: { methods: {
initData() { initData() {
goodsCategory().then(res => { catalogList().then(res => {
this.list = res.data.data.categoryList; this.list = res.data.data.categoryList;
this.$refs.classTree.changeList(res.data.data); this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory; this.subCategory = res.data.data.currentSubCategory;
...@@ -63,7 +63,7 @@ export default { ...@@ -63,7 +63,7 @@ export default {
return data.filter(item => item.children && item.children.length); return data.filter(item => item.children && item.children.length);
}, },
changeCatalog(id) { changeCatalog(id) {
goodsChannelCategory({ id: id}).then(res => { catalogList({ id: id}).then(res => {
let index = getIndex(this.list, res.data.data.currentCategory.id); let index = getIndex(this.list, res.data.data.currentCategory.id);
this.$refs.classTree.changeList(res.data.data); this.$refs.classTree.changeList(res.data.data);
this.subCategory = res.data.data.currentSubCategory; this.subCategory = res.data.data.currentSubCategory;
......
...@@ -37,7 +37,16 @@ export default { ...@@ -37,7 +37,16 @@ export default {
}, },
loadAddress() { loadAddress() {
addressList().then(res => { addressList().then(res => {
this.addressList = res.data.data; var list = res.data.data;
for(var i = 0; i < list.length; i++ ){
var item = list[i]
this.addressList.push({
id: item.id,
name: item.name,
tel: item.tel,
address: item.province + item.city + item.county + " " + item.addressDetail
})
}
}) })
} }
}, },
......
<template>
<div>
<van-cell-group title="反馈类型">
<van-cell class="order-coupon" :title="type" is-link arrow-direction="down" @click="showList = true" />
</van-cell-group>
<van-cell-group title="反馈内容">
<van-field v-model="content"
clearable autosize center
placeholder="对我们网站、商品、服务,你还有什么建议吗?你还希望在商城上买到什么?请告诉我们..."
type="textarea"
rows="10"
size="large"
/>
</van-cell-group>
<van-cell-group title="联系方式">
<van-field size="large" v-model="mobile" placeholder="请输入联系电话,方便我们与您联系" />
</van-cell-group>
<van-button size="large" type="primary" @click="submit">提交</van-button>
<van-popup v-model="showList" position="bottom">
<van-picker :columns="types" @change="onType" />
</van-popup>
</div>
</template>
<script>
import { Field , Picker, Popup, Button } from 'vant';
import { feedbackAdd } from '@/api/api';
export default {
data() {
return {
mobile: '',
content: '',
showList: false,
types:['商品相关', '功能异常', '优化建议', '其他'],
type: ''
};
},
created() {
},
methods: {
onType(picker, value, index) {
this.type = value
this.showList = false
},
submit() {
if(this.mobile === ''){
this.$toast("请输入联系电话");
return;
}
if(this.type === ''){
this.$toast("请选择反馈类型");
return;
}
if(this.content === ''){
this.$toast("请输入反馈内容");
return;
}
feedbackAdd({ mobile: this.mobile, feedType: this.type, content: this.content}).then(res => {
this.$toast("感谢您的宝贵意见!");
this.$router.go(-1);
})
}
},
components: {
[Field.name]: Field,
[Popup.name]: Popup,
[Button.name]: Button,
[Picker.name]: Picker
}
};
</script>
<style lang="scss" scoped>
.addressGroup {
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
.bottom_btn {
position: fixed;
bottom: 0;
}
</style>
<template> <template>
<div> <div>
<van-collapse accordion="true" v-model="activeNames"> <van-collapse :accordion="true" v-model="activeNames">
<van-collapse-item :title="issue.question" :name="index" v-for="(issue, index) in issueList" :key="index"> <van-collapse-item :title="issue.question" :name="index" v-for="(issue, index) in issueList" :key="index">
{{issue.answer}} {{issue.answer}}
</van-collapse-item> </van-collapse-item>
...@@ -35,7 +35,4 @@ export default { ...@@ -35,7 +35,4 @@ export default {
[CollapseItem.name]: CollapseItem [CollapseItem.name]: CollapseItem
} }
}; };
</script> </script>
<style scoped lang="scss"> \ No newline at end of file
</style>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div> <div>
<van-cell-group> <van-cell-group>
<van-cell title="联系客服" @click="showKefu = true" isLink></van-cell> <van-cell title="联系客服" @click="showKefu = true" isLink></van-cell>
<van-cell title="意见反馈" isLink></van-cell> <van-cell title="意见反馈" to="/user/feedback" isLink></van-cell>
<van-cell title="常见问题" to="/user/help" isLink/> <van-cell title="常见问题" to="/user/help" isLink/>
</van-cell-group> </van-cell-group>
<van-popup v-model="showKefu"> <van-popup v-model="showKefu">
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
</template> </template>
<script> <script>
import { REFUND_LIST } from '@/api/order'; import { REFUND_LIST } from '@/api/api';
import { Tab, Tabs, Panel, Card, List } from 'vant'; import { Tab, Tabs, Panel, Card, List } from 'vant';
import InfinityScroll from '@/components/infinity-scroll'; import InfinityScroll from '@/components/infinity-scroll';
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
<script> <script>
import { Uploader, Picker, Popup, Button } from 'vant'; import { Uploader, Picker, Popup, Button } from 'vant';
import { USER_PROFILE } from '@/api/user';
import { removeLocalStorage } from '@/utils/local-storage'; import { removeLocalStorage } from '@/utils/local-storage';
import { getLocalStorage } from '@/utils/local-storage'; import { getLocalStorage } from '@/utils/local-storage';
import { authLogout } from '@/api/api'; import { authLogout } from '@/api/api';
...@@ -78,12 +77,7 @@ export default { ...@@ -78,12 +77,7 @@ export default {
console.log(file); console.log(file);
}, },
onSexConfirm(value, index) { onSexConfirm(value, index) {
this.$reqPut(USER_PROFILE, {
gender: index[0]
}).then(res => {
this.gender = res.data.data.gender;
this.showSex = false;
});
}, },
getUserInfo() { getUserInfo() {
const infoData = getLocalStorage( const infoData = getLocalStorage(
......
<template> <template>
<div> <div>
<van-cell-group> <van-cell-group>
<van-field <van-field
label="登录密码" label="登录密码"
v-model="password" v-model="password"
type="password" type="password"
placeholder="请输入登录密码" placeholder="请输入登录密码"
:error="!!$vuelidation.error('password')" /> :error="!!$vuelidation.error('password')" />
<van-field <van-field
label="新手机号" label="新手机号"
v-model="new_mobile" v-model="new_mobile"
placeholder="请输入新手机号" placeholder="请输入新手机号"
:error="!!$vuelidation.error('new_mobile')" /> :error="!!$vuelidation.error('new_mobile')" />
<van-field <van-field
label="验证码" label="验证码"
v-model="code" v-model="code"
@click-icon="getCode" @click-icon="getCode"
placeholder="请输入验证码"> placeholder="请输入验证码">
<span slot="icon" <span slot="icon"
class="verifi_code red" class="verifi_code red"
:class="{verifi_code_counting: counting}" :class="{verifi_code_counting: counting}"
@click="getCode"> @click="getCode">
<countdown v-if="counting" :time="60000" @countdownend="countdownend"> <countdown v-if="counting" :time="60000" @countdownend="countdownend">
<template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template> <template slot-scope="props">{{ +props.seconds || 60 }}秒后获取</template>
</countdown> </countdown>
<span v-else>获取验证码</span> <span v-else>获取验证码</span>
</span> </span>
</van-field> </van-field>
</van-cell-group> </van-cell-group>
<div class="bottom_btn"> <div class="bottom_btn">
<van-button size="large" type="danger" @click="saveMobile">保存</van-button> <van-button size="large" type="danger" @click="saveMobile">保存</van-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { USER_SENDCODE } from '@/api/user'; import { authRegisterCaptcha } from '@/api/api';
import { Field } from 'vant'; import { Field } from 'vant';
export default { export default {
data: () => ({ data: () => ({
password: '', password: '',
new_mobile: '', new_mobile: '',
code: '', code: '',
counting: false counting: false
}), }),
vuelidation: { vuelidation: {
data: { data: {
password: { password: {
required: true required: true
}, },
new_mobile: { new_mobile: {
required: true, required: true,
mobile: true mobile: true
} }
} }
}, },
methods: { methods: {
getCode() { getCode() {
if (!this.counting && this.vuelidat()) { if (!this.counting && this.vuelidat()) {
this.$reqPost(USER_SENDCODE, { authRegisterCaptcha({
mobile: this.new_mobile, mobile: this.new_mobile,
operation: 'changeMobile' operation: 'changeMobile'
}).then(() => { }).then(() => {
this.$toast.success('发送成功'); this.$toast.success('发送成功');
this.counting = true; this.counting = true;
}); });
} }
}, },
countdownend() { countdownend() {
this.counting = false; this.counting = false;
}, },
vuelidat() { vuelidat() {
this.$vuelidation.valid(); this.$vuelidation.valid();
if (this.$vuelidation.error('new_mobile')) { if (this.$vuelidation.error('new_mobile')) {
const msg = this.$vuelidation.error('new_mobile'); const msg = this.$vuelidation.error('new_mobile');
this.$toast(msg == 'Required' ? '请输入手机号' : msg); this.$toast(msg == 'Required' ? '请输入手机号' : msg);
return false; return false;
} }
return true; return true;
}, },
saveMobile() { saveMobile() {
console.log('保存手机号'); console.log('保存手机号');
} }
}, },
components: { components: {
[Field.name]: Field [Field.name]: Field
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '../../../../assets/scss/var'; @import '../../../../assets/scss/var';
@import '../../../../assets/scss/mixin'; @import '../../../../assets/scss/mixin';
.bottom_btn { .bottom_btn {
padding: 30px 15px 0 15px; padding: 30px 15px 0 15px;
} }
.verifi_code { .verifi_code {
@include one-border; @include one-border;
padding-left: 10px; padding-left: 10px;
&::after { &::after {
border-bottom: 0; border-bottom: 0;
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
} }
&_counting { &_counting {
color: $font-color-gray; color: $font-color-gray;
} }
} }
</style> </style>
<template> <template>
<div class="set_nickname"> <div class="set_nickname">
<van-cell-group> <van-cell-group>
<van-field v-model="nickName" label="昵称" :error="!!$vuelidation.error('nickName')"/> <van-field v-model="nickName" label="昵称" :error="!!$vuelidation.error('nickName')"/>
</van-cell-group> </van-cell-group>
<div class="bottom_btn"> <div class="bottom_btn">
<van-button size="large" type="danger" @click="saveNick">保存</van-button> <van-button size="large" type="danger" @click="saveNick">保存</van-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { USER_PROFILE } from '@/api/user'; import { authProfile } from '@/api/api';
import { Field } from 'vant'; import { Field } from 'vant';
export default { export default {
data() { data() {
return { return {
nickName: '' nickName: ''
}; };
}, },
created() { created() {
this.getNick(); this.getNick();
}, },
methods: { methods: {
getNick() { getNick() {
this.nickName = localStorage.getItem('nickName') || ''; this.nickName = localStorage.getItem('nickName') || '';
}, },
saveNick() { saveNick() {
if (true) { if (true) {
this.$reqPut(USER_PROFILE, { nickName: this.nickName }) authProfile({ nickName: this.nickName })
.then(res => { .then(res => {
localStorage.setItem('nickName', res.data.data.nickName); localStorage.setItem('nickName', res.data.data.nickName);
return this.$dialog.alert({ message: '保存成功' }); return this.$dialog.alert({ message: '保存成功' });
}) })
.then(() => { .then(() => {
this.$router.go(-1); this.$router.go(-1);
}); });
} }
} }
}, },
components: { components: {
[Field.name]: Field [Field.name]: Field
} }
}; };
</script> </script>
<style scoped> <style scoped>
.bottom_btn { .bottom_btn {
padding: 30px 15px 0 15px; padding: 30px 15px 0 15px;
} }
</style> </style>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<script> <script>
import { USER_MODIFY_PASSWORD, USER_LOGOUT } from '@/api/user'; import { authReset, authLogout } from '@/api/api';
import { removeLocalStorage } from '@/utils/local-storage'; import { removeLocalStorage } from '@/utils/local-storage';
import { Field } from 'vant'; import { Field } from 'vant';
...@@ -49,21 +49,14 @@ export default { ...@@ -49,21 +49,14 @@ export default {
methods: { methods: {
modifypassword() { modifypassword() {
if (this.passwordValid()) { if (this.passwordValid()) {
this.$reqPut(USER_MODIFY_PASSWORD, { authReset({
old_password: this.password, old_password: this.password,
new_password: this.new_password new_password: this.new_password
}) })
.then(() => this.$dialog.alert({ message: '保存成功, 请重新登录.' })) .then(() => {
.then(() => this.$reqGet(USER_LOGOUT)) this.$dialog.alert({ message: '保存成功, 请重新登录.' })
.then(() => { authLogout();
removeLocalStorage( });
'Authorization',
'avatar',
'background_image',
'nickName'
);
this.$router.replace({ name: 'login' });
});
} }
}, },
passwordValid() { passwordValid() {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment