first commit

This commit is contained in:
那些花儿
2025-07-14 08:45:13 +08:00
commit 3e86198a82
2710 changed files with 610330 additions and 0 deletions
@@ -0,0 +1,185 @@
const home = {
template: /*language=HTML*/ `
<div>
<van-nav-bar title="首页" class="nav-bar" placeholder fixed></van-nav-bar>
<van-swipe :autoplay="100000" :height="200" class="home__swipe">
<van-swipe-item>
<img src="/assets/mobile/img/home/home1.png" alt="">
</van-swipe-item>
<van-swipe-item>
<img src="/assets/mobile/img/home/home2.png" alt="">
</van-swipe-item>
<van-swipe-item>
<img src="/assets/mobile/img/home/home3.png" alt="">
</van-swipe-item>
</van-swipe>
<!--快捷入口-->
<div class="quick-grid">
<div class="section-title">快速入口</div>
<van-grid :column-num="4" icon-size="46" square clickable :border="false">
<van-grid-item v-for="item in quickEntries"
@click="menuClick(item)"
:key="item.id"
:text="item.name">
<img :src="item.icon"
slot="icon"
style="width: 40px; height: 40px"/>
</van-grid-item>
</van-grid>
</div>
<!--活动列表-->
<div class="act-list">
<div class="section-title">最新活动</div>
<template v-if="activityOptions && activityOptions.length > 0">
<div v-for="item in activityOptions" :key="item.id" class="act-item" @click="enterAct(item)">
<van-tag class="act-item-wrapper-tag" v-if="$moment().unix() > $moment(item.endDate).unix()">
已结束
</van-tag>
<van-tag class="act-item-wrapper-tag" type="success" v-else-if="$moment().unix() < $moment(item.endDate).unix()">
进行中
</van-tag>
<div class="act-item-cover">
<van-image v-if="item.cover" width="120" height="84" :src="item.cover"></van-image>
</div>
<div class="act-item-wrapper">
<div class="content-title">
{{item.name}}
</div>
<div class="content-text">
<div>开始时间:{{$moment(item.startDate).format('MM-DD HH:mm')}}</div>
<div class="mt5">结束时间:{{$moment(item.endDate).format('MM-DD HH:mm')}}</div>
</div>
</div>
</div>
</template>
<van-empty v-if="!activityOptions || activityOptions.length === 0" description="暂无最新活动"></van-empty>
</div>
</div>
`,
data() {
return {
activityOptions: [],
quickEntries: []
}
},
methods: {
listQuickEntry() {
this.$axios.post("/platform/home/listQuickEntry", { platform: "H5" }).then((res) => {
if (res.code === 0) {
this.quickEntries = res.data
}
})
},
listActivity() {
this.$axios.post("/platform/home/listHomeActivity").then((resp) => {
if (resp.code === 0) {
this.activityOptions = resp.data
}
})
},
menuClick(item) {
this.$pjaxReplace(item.href)
},
//点击进入活动
enterAct(item) {
this.$pjaxReplace(item.h5Url)
}
},
created() {
this.listQuickEntry()
this.listActivity()
},
style: /*language=CSS*/ `
.home__swipe .van-swipe-item img {
width: 100%;
height: 100%;
}
.quick-grid {
background-color: #fff;
margin: 10px;
border-radius: 10px;
padding: 10px;
}
.quick-grid .van-grid-item .van-grid-item__text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 85%;
text-align: center;
flex-shrink: 0;
}
.act-list {
background-color: #fff;
margin: 10px;
border-radius: 10px;
padding: 10px;
position: relative;
}
.act-item {
width: 100%;
padding: 6px;
background-color: #fff;
display: flex;
position: relative;
}
.act-item-cover {
margin: 0 14px 0 0;
width: 120px;
height: 84px;
flex-shrink: 0;
}
.act-item-cover .van-image{
/*width: 120px;*/
/*height: 84px;*/
width: 100%;
height: 100%;
}
.act-item-wrapper{
display: flex;
flex-wrap: wrap;
align-content: space-between;
width: 100%;
}
.act-item-wrapper-tag{
position: absolute;
left: 10px;
top: 10px;
z-index: 1;
}
.act-item-wrapper .content-title{
font-size: 14px;
width: 100%;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
.act-item-wrapper .content-text{
font-size: 12px;
color: grey;
padding-bottom: 6px;
}
.section-title{
padding: 10px 0 5px 10px;
}
`
}
@@ -0,0 +1,62 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style></style>
<div id="app" v-cloak>
<div>
<div>
<home v-if="homeTabbarActive === 'home'" @module-click="moduleClick"></home>
<work v-if="homeTabbarActive === 'work'"></work>
<mine v-if="homeTabbarActive === 'mine'"></mine>
</div>
<div id="page-tarbar" class="page-tarbar">
<van-tabbar v-model="homeTabbarActive" @change="homeTabbarChange">
<van-tabbar-item name="home" icon="wap-home-o">首页</van-tabbar-item>
<van-tabbar-item name="work" icon="gem">工作台</van-tabbar-item>
<van-tabbar-item name="mine" icon="user-o">我的</van-tabbar-item>
</van-tabbar>
</div>
</div>
</div>
<script>
<!--#include("home.js"){}#-->
<!--#include("work.js"){}#-->
<!--#include("mine.js"){}#-->
new Vue({
el: "#app",
store,
components: {
home,
mine,
work
},
data() {
return {
homeTabbarActive: "home"
}
},
methods: {
homeTabbarChange(val) {
this.$store.commit("setActiveTarBar", val)
},
moduleClick(val) {
console.log(val)
this.homeTabbarActive = "work"
}
},
created() {
if (!this.$store.state.activeTarBar) {
this.$store.commit("setActiveTarBar", "home")
} else {
this.homeTabbarActive = this.$store.state.activeTarBar
}
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,370 @@
const mine = {
template: /*language=HTML*/ `
<div class="home-mine">
<van-nav-bar title="个人中心" class="nav-bar"></van-nav-bar>
<div class="profile-card">
<div class="profile-header">
<div class="avatar-section">
<div class="avatar-wrapper">
<van-image :src="avatar" round width="80" height="80" class="avatar">
<van-loading slot="loading" type="spinner" size="20"></van-loading>
</van-image>
<div class="status-badge">
<div class="status-dot"></div>
<span>{{ $store.state.user.userState }}</span>
</div>
</div>
</div>
<div class="basic-info">
<div class="name-row">
<h2 class="username">{{ $store.state.user.username }}</h2>
<div class="gender-tag">
<van-icon name="friends-o" class="gender-icon"></van-icon>
<span>{{ $store.state.user.sex }}</span>
</div>
</div>
<div class="employee-id">
工号:
<span class="id-value">{{ $store.state.user.loginname }}</span>
</div>
</div>
</div>
<div class="info-list">
<div class="info-item">
<van-icon name="user-o"></van-icon>
<span class="item-label">人员类型</span>
<span class="info-value">{{ $store.state.user.personType }}</span>
</div>
<div class="info-item">
<van-icon name="user-o"></van-icon>
<span class="item-label">人事编制</span>
<span class="info-value">{{ $store.state.user.userState }}</span>
</div>
<div class="info-item">
<van-icon name="wap-home-o"></van-icon>
<span class="item-label">所属单位</span>
<span class="info-value">{{ $store.state.user.unit.name }}</span>
</div>
<div class="info-item">
<van-icon name="wap-home-o"></van-icon>
<span class="item-label">所属工会</span>
<span class="info-value">{{ $store.state.user.union.name }}</span>
</div>
</div>
</div>
<div class="action-cards">
<van-cell-group>
<van-cell is-link @click="$pjaxReplace('/platform/h5/indexMine/userInfo')" class="action-cell">
<span class="cell-title" slot="title">
<van-icon name="user-o" class="cell-icon"></van-icon>
个人信息
</span>
</van-cell>
<van-cell is-link @click="$pjaxReplace('/platform/signature/h5')" class="action-cell">
<span class="cell-title" slot="title">
<van-icon name="edit" class="cell-icon"></van-icon>
我的签名
</span>
</van-cell>
<!-- <van-cell :value="$store.state.user.totalIntegral" is-link @click="$pjaxReplace('/platform/integral/records/h5')" class="action-cell">-->
<!-- <span class="cell-title" slot="title">-->
<!-- <van-icon name="points" class="cell-icon"></van-icon>-->
<!-- 我的积分-->
<!-- </span>-->
<!-- </van-cell>-->
</van-cell-group>
</div>
<div class="logout-wrapper">
<van-button round block color="#ee0a24" @click="logout" class="logout-btn">退出登录</van-button>
</div>
</div>
`,
computed: {
avatar() {
const sex = this.$store.state.user.sex
if (sex === "男" || !sex) {
return "/assets/platform/img/home/avatar_boy.png"
} else {
return "/assets/platform/img/home/avatar_girl.png"
}
}
},
methods: {
logout() {
this.$dialog
.confirm({
title: "温馨提示",
message: "您确认要退出登录吗?"
})
.then(() => {
this.$store.dispatch("logout")
})
}
},
style() {
return /*language=CSS*/ `
.home-mine {
background: #f7f8fa;
}
.profile-card {
margin: 16px;
padding: 20px;
background: white;
border-radius: 12px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
animation: slideIn 0.3s ease-out;
}
.profile-header {
display: flex;
gap: 16px;
align-items: flex-start;
margin-bottom: 20px;
animation: slideIn 0.3s ease-out;
}
.avatar-section {
flex-shrink: 0;
width: 80px;
}
.avatar-wrapper {
position: relative;
width: 80px;
height: 80px;
}
.avatar {
border: 2px solid #f5f5f5;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
transition: transform 0.3s;
}
.status-badge {
position: absolute;
bottom: -2px;
right: -2px;
background: rgba(255, 255, 255, 0.9);
color: #34c759;
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
display: flex;
align-items: center;
gap: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 1;
animation: fadeInScale 0.3s ease-out 0.2s backwards;
}
.status-dot {
width: 6px;
height: 6px;
background: #34c759;
border-radius: 50%;
}
.basic-info {
flex: 1;
padding-top: 4px;
display: flex;
flex-direction: column;
gap: 8px;
}
.name-row {
display: flex;
align-items: center;
gap: 12px;
animation: slideLeft 0.3s ease-out;
}
.username {
margin: 0;
font-size: 20px;
font-weight: 500;
color: #333;
}
.gender-tag {
display: inline-flex;
align-items: center;
gap: 4px;
background: #f5f5f5;
padding: 2px 10px;
border-radius: 20px;
font-size: 13px;
color: #666;
}
.employee-id {
color: #666;
font-size: 15px;
animation: slideLeft 0.3s ease-out 0.1s backwards;
}
.id-value {
color: #333;
font-weight: 500;
font-size: 16px;
}
.info-list {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #f5f5f5;
display: flex;
flex-direction: column;
gap: 16px;
}
.info-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
animation: slideLeft 0.3s ease-out;
transition: background-color 0.3s;
padding: 8px;
border-radius: 8px;
}
.info-item:active {
background-color: #f5f5f5;
}
.item-label {
color: #999;
width: 70px;
}
.info-value {
color: #333;
flex: 1;
}
.info-item .van-icon {
font-size: 16px;
color: #666;
width: 20px;
}
.action-cards {
margin: 16px;
animation: slideUp 0.3s ease-out;
}
.action-cell {
padding: 16px !important;
}
.cell-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 15px;
color: #333;
}
.cell-icon {
font-size: 18px;
color: #666;
}
.logout-wrapper {
padding: 16px;
margin-top: 20px;
animation: fadeIn 0.3s ease-out;
}
.logout-btn {
height: 44px;
font-size: 16px;
transition: opacity 0.3s;
}
.logout-btn:active {
opacity: 0.8;
}
/* 动画定义 */
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideLeft {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInScale {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* 为每个列表项添加延迟动画 */
.info-item:nth-child(1) {
animation-delay: 0.1s;
}
.info-item:nth-child(2) {
animation-delay: 0.2s;
}
.info-item:nth-child(3) {
animation-delay: 0.3s;
}
.info-item:nth-child(4) {
animation-delay: 0.4s;
}
`
}
}
@@ -0,0 +1,81 @@
const work = {
template: /*language=HTML*/ `
<div class="workbenche">
<van-nav-bar title="工作台" placeholder fixed></van-nav-bar>
<div class="module-item" v-for="item in $store.state.user.h5ModuleMenus" :key="item.id">
<div class="module-header">
<div class="module-header__content">{{item.name}}</div>
</div>
<div class="module-content">
<van-grid :column-num="3">
<van-grid-item icon="photo-o" :text="menu.name" v-for="menu in item.menus" :key="menu.id"
@click="menuClick(menu)">
<template #icon>
<img :src="menu.icon" alt="" style="width: 40px;height: 40px">
</template>
<template #text>
<span>{{menu.name}}</span>
</template>
</van-grid-item>
</van-grid>
</div>
</div>
</div>
`,
store,
methods: {
menuClick(item) {
this.$pjaxReplace(item.href)
}
},
style: /*language=CSS*/ `
.left-span-label {
border-left: 4px solid var(--color-primary);
font-size: 15px;
color: #000;
font-weight: 600;
padding-left: 8px;
margin-top: 6px;
}
.van-grid-item__content {
padding: 14px 8px;
}
.grid_text {
white-space: nowrap;
overflow: hidden;
width: 100%;
text-align: center;
font-size: 12px;
font-family: "微软雅黑", Helvetica, STHeiTi, sans-serif;
color: grey;
margin-top: 6px;
}
.module-item {
background-color: #fff;
box-shadow: 1px 1px #ccc;
margin-bottom: 10px;
padding: 6px;
}
.module-header {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
padding: 12px 10px;
font-weight: 400;
}
.workbenche .module-item .module-header .module-header__content {
display: flex;
flex-direction: column;
flex: 1;
font-size: 18px;
font-weight: 700;
color: var(--color-primary);
}
`
}
@@ -0,0 +1,149 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
.bgcolor-white {
background: #ffffff;
}
.table-list .table-card {
margin: 10px;
background: #fff;
padding: 8px;
border-bottom: 1px #ebedf0 solid;
position: relative;
border-radius: 0 !important;
}
.table-list .table-card:nth-of-type(1) {
margin: 0 10px 10px 10px;
padding-top: 10px;
}
.flex-card {
display: flex;
align-items: center;
justify-content: space-between;
}
.left {
font-size: 14px;
width: 50%;
}
.right {
text-align: right;
}
.increase {
font-weight: bold;
color: red;
}
.decrease {
font-weight: bold;
}
.time {
color: grey;
font-size: 13px;
margin-top: 2px;
}
</style>
<div id="app" v-cloak>
<van-sticky>
<van-nav-bar title="我的积分" @click-left="historyBack" left-arrow left-text="返回" placeholder fixed></van-nav-bar>
<van-dropdown-menu>
<van-dropdown-item v-model="pageForm.changeType" :options="changeTypeOptions" @change="doSearch"></van-dropdown-item>
<van-dropdown-item v-model="pageForm.state" :options="stateOptions" @change="doSearch"></van-dropdown-item>
<van-dropdown-item v-model="pageForm.integralOrigin" :options="integralOriginOptions" @change="doSearch"></van-dropdown-item>
</van-dropdown-menu>
</van-sticky>
<div class="bgcolor-white">
<van-list v-if="tableData.length>0" v-model="tableLoading" :finished="tableFinished" finished-text="没有更多了" @load="onLoad">
<div class="table-list">
<div class="table-card flex-card" v-for="row in tableData" :key="row.id">
<div class="left">
<van-icon name="points" size="16" style="top: 1px"></van-icon>
{{ row.remark ? row.remark : row.integralOrigin }}
</div>
<div class="right">
<div :class="row.changeValue > 0 ? 'increase' : 'decrease'">{{ (row.changeValue > 0 ? '+' : '') + row.changeValue }}</div>
<div class="time">{{ row.changeTime }}</div>
</div>
</div>
</div>
</van-list>
<van-empty v-else image="/assets/platform/plugins/vant-green/images/nodata/nodata.png" description="暂无数据"></van-empty>
</div>
</div>
<script>
const vue = new Vue({
el: "#app",
store,
components: {},
data() {
return {
totalIntegral: 0,
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
searchKeyword: ""
},
tableData: [],
tableLoading: false,
tableFinished: false,
changeTypeOptions: [],
stateOptions: [],
integralOriginOptions: []
}
},
methods: {
historyBack,
doSearch() {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.tableData = []
this.onLoad()
},
onLoad() {
this.tableLoading = true
this.$axios.post("/platform/integral/records/pageData", this.pageForm).then((resp) => {
this.tableData = this.tableData.concat(resp.data.list)
this.pageForm.totalCount = resp.data.totalCount
if (this.tableData.length >= this.pageForm.totalCount) {
this.tableFinished = true
} else {
this.pageForm.pageNumber++
}
this.tableLoading = false
})
}
},
created() {
this.totalIntegral = this.$store.state.user.totalIntegral
this.$businessTool.getDictOptions("INTEGRAL_CHANGE_TYPE").then((data) => {
data.forEach((item) => {
this.changeTypeOptions.push({ text: item.name, value: item.code })
})
this.changeTypeOptions.unshift({ text: "全部变动类型" })
})
this.$businessTool.getDictOptions("INTEGRAL_STATE").then((data) => {
data.forEach((item) => {
this.stateOptions.push({ text: item.name, value: item.code })
})
this.stateOptions.unshift({ text: "全部积分状态" })
})
this.$businessTool.getDictOptions("INTEGRAL_ORIGIN").then((data) => {
data.forEach((item) => {
this.integralOriginOptions.push({ text: item.name, value: item.code })
})
this.integralOriginOptions.unshift({ text: "全部积分来源" })
})
this.onLoad()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,99 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
.bgcolor-white {
background: #ffffff;
}
.van-status__figure {
text-align: center;
line-height: 1.5;
}
.van-status__figure img {
width: 130px;
height: 130px;
}
</style>
<div id="app" v-cloak>
<van-nav-bar title="我的签名" @click-left="historyBack" left-arrow left-text="返回" placeholder fixed></van-nav-bar>
<div class="bgcolor-white">
<div v-if="!showSignature" class="p10">
<van-image width="100%" height="200" :src="userSignatureUrl" v-if="userSignatureUrl" style="border: 1px dashed #000">
<template slot="error">获取签名失败</template>
</van-image>
<div v-else class="van-status__figure">
<img src="/assets/platform/plugins/vant-green/images/figure/fail.png" class="" />
<div class="text-center pt10 pb10">暂无签名</div>
</div>
<!-- <van-status orient="vertical" :figure="14" title="暂无签名" v-else></van-status>-->
<div class="margin-top10">
<van-button v-if="!userSignatureUrl" block type="primary" @click="openSignature">去签名</van-button>
<van-button v-else block type="primary" @click="openSignature">修改签名</van-button>
</div>
</div>
<signature v-if="showSignature" @save="saveSignature"></signature>
</div>
</div>
<script>
const vue = new Vue({
el: "#app",
store,
components: {
signature: httpVueLoader("/components/plugins/sysSignature/index.vue?v=" + new Date().getTime())
},
data() {
return {
showSignature: false,
userSignatureUrl: null
}
},
methods: {
getUserSignature() {
this.$axios.post("/platform/signature/get").then((res) => {
if (res.code === 0) {
this.userSignatureUrl = res.data.signature
}
})
},
openSignature() {
this.showSignature = true
},
saveSignature(signature) {
console.log(signature)
const file = base64ToFile(signature, "signature.png")
const formData = new FormData()
formData.append("file", file)
axios
.post("/platform/signature/update", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then((res) => {
return res.data
})
.then((res) => {
if (res.code === 0) {
this.showSignature = false
this.$toast.success(res.msg)
this.getUserSignature()
} else {
this.$toast.fail(res.msg)
}
})
}
},
created() {
this.getUserSignature()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,35 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<div id="app" v-cloak>
<van-nav-bar title="个人信息" @click-left="historyBack" left-arrow left-text="返回" placeholder fixed></van-nav-bar>
<member-info :user-id="userId" ref="memberInfoRef"></member-info>
</div>
<script>
<!--#include("/platform/zhghh5/staffmanage/member/common/mobileMemberInfo.js"){}#-->
new Vue({
el: "#app",
store,
data() {
return {
userId: ""
}
},
components: {
"member-info": MOBILE_MEMBER_INFO
},
methods: {
viewInfo() {
this.userId = this.$store.state.user.id
}
},
created() {
this.viewInfo()
}
})
</script>
<!--#
}
#-->