对接选课接口
This commit is contained in:
parent
f4e8120d91
commit
8e709572b3
@ -1,26 +1,21 @@
|
||||
// 参数接口
|
||||
|
||||
// 响应接口
|
||||
import {get, post} from "@/utils/request";
|
||||
import { get, post } from "@/utils/request";
|
||||
|
||||
|
||||
/**
|
||||
* 获取服务器时间
|
||||
*/
|
||||
export const serverTimeApi = async () => {
|
||||
return await get('/api/server/serverTime')
|
||||
}
|
||||
export const standardWordsRandomApi = async () => {
|
||||
return await get('/api/standardWords/findRandom')
|
||||
}
|
||||
export const cmsArticleFindPageApi = async (params: any) => {
|
||||
return await get("/api/cmsArticle/findPage", params);
|
||||
export const loginRegisterJzApi = async (params: any) => {
|
||||
return await post("/open/login/registerJz", params);
|
||||
};
|
||||
export const xkAddXkqdApi = async (params: any) => {
|
||||
return await post("/mobile/xk/addXkqd", params);
|
||||
};
|
||||
|
||||
export const agencyAgencyListApi = async () => {
|
||||
return await get("/api/agency/agencyList");
|
||||
export const xkListApi = async (params: any) => {
|
||||
return await get("/mobile/xk/list", params);
|
||||
};
|
||||
|
||||
export const serverCheckInRangeTimeApi = async () => {
|
||||
return await get("/api/server/checkInRangeTime");
|
||||
export const xkXkqdApi = async (params: any) => {
|
||||
return await get("/mobile/xk/xkqd", params);
|
||||
};
|
||||
export const kcjhFindKcjhByKcIdApi = async (params: any) => {
|
||||
return await get("/api/kcjh/findKcjhByKcId", params);
|
||||
};
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
import {get, post} from "@/utils/request";
|
||||
import { get, post } from "@/utils/request";
|
||||
|
||||
//字典接口
|
||||
export const dicApi = async (param: { pid: number }) => {
|
||||
return await get("/api/dic/findByPid", param);
|
||||
};
|
||||
//字典接口
|
||||
export const findDicTreeByPidApi = async (param: { pid: number }) => {
|
||||
return await get("/api/dic/findDicTreeByPid", param);
|
||||
};
|
||||
|
||||
//根据id查询部门
|
||||
export const deptFindAllDeptsByPidApi = async (param: { pid: number }) => {
|
||||
@ -12,11 +16,25 @@ export const deptFindAllDeptsByPidApi = async (param: { pid: number }) => {
|
||||
|
||||
//刷新token
|
||||
export const refreshTokenApi = async (param: { refresh_token: string }) => {
|
||||
return await post("/userlogin/refresh-token?refresh_token=" + param.refresh_token, param);
|
||||
return await post(
|
||||
"/userlogin/refresh-token?refresh_token=" + param.refresh_token,
|
||||
param
|
||||
);
|
||||
};
|
||||
|
||||
//修改用户部门
|
||||
export const userSaveApi = async (param: { id: string, deptId: string, deptName: string }) => {
|
||||
return await post("/api/user/save?deptId=" + param.deptId + '&deptName=' + param.deptName + '&id=' + param.id, param);
|
||||
export const userSaveApi = async (param: {
|
||||
id: string;
|
||||
deptId: string;
|
||||
deptName: string;
|
||||
}) => {
|
||||
return await post(
|
||||
"/api/user/save?deptId=" +
|
||||
param.deptId +
|
||||
"&deptName=" +
|
||||
param.deptName +
|
||||
"&id=" +
|
||||
param.id,
|
||||
param
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,14 +1,28 @@
|
||||
//登录接口
|
||||
import {get, post} from "@/utils/request";
|
||||
import { get, post } from "@/utils/request";
|
||||
|
||||
//密码登录接口
|
||||
export const loginPass = async (param: { username: string, password: string, openId: number | string }) => {
|
||||
return await post("/userlogin/check?username=" + param.username + '&password=' + param.password + '&openId=' + param.openId, param
|
||||
)
|
||||
;
|
||||
export const loginPass = async (param: {
|
||||
username: string;
|
||||
password: string;
|
||||
openId: number | string;
|
||||
}) => {
|
||||
return await post(
|
||||
"/userlogin/check?username=" +
|
||||
param.username +
|
||||
"&password=" +
|
||||
param.password +
|
||||
"&openId=" +
|
||||
param.openId,
|
||||
param
|
||||
);
|
||||
};
|
||||
//验证码登录接口
|
||||
export const loginCode = async (param: { phone: string | number, code: string | number, openId: number | string }) => {
|
||||
export const loginCode = async (param: {
|
||||
phone: string | number;
|
||||
code: string | number;
|
||||
openId: number | string;
|
||||
}) => {
|
||||
return await post("/open/sms/checkCode", param);
|
||||
};
|
||||
//验证码登录接口
|
||||
@ -16,7 +30,7 @@ export const loginCheckCode = async (param: any) => {
|
||||
return await post("/open/sms/checkCode", param);
|
||||
};
|
||||
//获取验证码接口
|
||||
export const sendCodeApi = async (param:any) => {
|
||||
export const sendCodeApi = async (param: any) => {
|
||||
return await get("/open/sms/sendCode", param);
|
||||
};
|
||||
|
||||
@ -35,15 +49,20 @@ export const authenticationApi = async (param: { userId: string }) => {
|
||||
return await get("/api/authentication/find-by-user", param);
|
||||
};
|
||||
|
||||
// 汇兴小程序登录
|
||||
export const huiXingLoginApi = async (param: { token: string }) => {
|
||||
return await post("/userlogin/appCheck?token=" + param.token, param);
|
||||
};
|
||||
|
||||
//获取公众号票据
|
||||
export const wxConfigApi = async (param: any) => {
|
||||
return await post("/userlogin/wxConfig", param);
|
||||
};
|
||||
export const checkOpenId = async (param: { openId: string | number, appCode: string }) => {
|
||||
return await post("/open/sms/checkOpenId", param);
|
||||
|
||||
export const checkOpenId = async (param: {
|
||||
openId: string | number;
|
||||
appCode: string;
|
||||
}) => {
|
||||
return await post("/open/login/jz/checkUser", param);
|
||||
};
|
||||
export const updateUserApi = async (param: any) => {
|
||||
return await post("/open/login/js/updateUser", param);
|
||||
};
|
||||
export const findJsByPhoneApi = async (param: any) => {
|
||||
return await get("/api/js/findJsByPhone", param);
|
||||
};
|
||||
|
||||
@ -1,69 +1,124 @@
|
||||
<template>
|
||||
<uni-data-picker :popup-title="'请选择'+attrs.label"
|
||||
<view>
|
||||
<u-loading-icon
|
||||
:show="loadingShow"
|
||||
style="justify-content: start"
|
||||
size="20"
|
||||
/>
|
||||
<uni-data-picker
|
||||
v-if="!loadingShow"
|
||||
:popup-title="'请选择' + attrs.label"
|
||||
:localdata="range"
|
||||
v-model="newValue"
|
||||
:map="{text:attrs.componentProps.rangeKey,value:attrs.componentProps.savaKey}"
|
||||
@change="onchange" @nodeclick="onnodeclick" @popupopened="onpopupopened"
|
||||
:map="{
|
||||
text: attrs.componentProps.rangeKey,
|
||||
value: attrs.componentProps.savaKey,
|
||||
}"
|
||||
@change="onchange"
|
||||
@nodeclick="onnodeclick"
|
||||
@popupopened="onpopupopened"
|
||||
@popupclosed="onpopupclosed"
|
||||
:readonly="!!attrs.componentProps.disabled"
|
||||
v-bind="attrs.componentProps"
|
||||
>
|
||||
<template #default="{data, error, options}">
|
||||
<template #default="{ data, error, options }">
|
||||
<view class="flex-row items-center justify-between py-7 font-13">
|
||||
<view v-if="error">
|
||||
<text style="color: red">{{ error }}</text>
|
||||
</view>
|
||||
<view v-else-if="data.length" class="flex-row">
|
||||
<view v-for="(item,index) in data" :key="index" class="selected-item">
|
||||
<view
|
||||
v-for="(item, index) in data"
|
||||
:key="index"
|
||||
class="selected-item"
|
||||
>
|
||||
<text>{{ item.text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="color-9" v-else-if="!attrs.componentProps.disabled">
|
||||
<text v-if="attrs.componentProps&&attrs.componentProps.placeholder">{{
|
||||
attrs.componentProps.placeholder
|
||||
}}
|
||||
<text
|
||||
v-if="attrs.componentProps && attrs.componentProps.placeholder"
|
||||
>{{ attrs.componentProps.placeholder }}
|
||||
</text>
|
||||
<text v-else>请选择{{ attrs.label }}</text>
|
||||
</view>
|
||||
<view v-else>无</view>
|
||||
<uni-icons type="right" size="18" color="#999999" v-if="!attrs.componentProps.disabled"/>
|
||||
<uni-icons
|
||||
type="right"
|
||||
size="18"
|
||||
color="#999999"
|
||||
v-if="!attrs.componentProps.disabled"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
</uni-data-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps(['modelValue'])
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
import { isFunction, map } from "lodash";
|
||||
const props = defineProps(["modelValue"]);
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
const newValue = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
return props.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
const attrs = useAttrs()
|
||||
emit("update:modelValue", value);
|
||||
},
|
||||
});
|
||||
const attrs = useAttrs();
|
||||
|
||||
if (!newValue.value) {
|
||||
newValue.value = '0'
|
||||
newValue.value = "0";
|
||||
}
|
||||
|
||||
const range = ref(attrs.componentProps && attrs.componentProps.range || [])
|
||||
const range = computed({
|
||||
get() {
|
||||
if (attrs.componentProps && attrs.componentProps.range) {
|
||||
return attrs.componentProps.range;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
set(value) {
|
||||
attrs.componentProps.range = value;
|
||||
},
|
||||
});
|
||||
const loadingShow = ref(false);
|
||||
function initapi() {
|
||||
if (attrs.componentProps.api && isFunction(attrs.componentProps.api)) {
|
||||
loadingShow.value = true;
|
||||
attrs.componentProps.api(attrs.componentProps.param || null).then((res) => {
|
||||
attrs.componentProps.range =
|
||||
res[attrs.componentProps.resultKey || "result"];
|
||||
if (
|
||||
attrs.componentProps.request &&
|
||||
isFunction(attrs.componentProps.request)
|
||||
) {
|
||||
attrs.componentProps.request(attrs.componentProps.range);
|
||||
}
|
||||
loadingShow.value = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initapi();
|
||||
|
||||
function onchange(e) {
|
||||
if (
|
||||
attrs.componentProps.onChange &&
|
||||
isFunction(attrs.componentProps.onChange)
|
||||
) {
|
||||
attrs.componentProps.onChange(e);
|
||||
}
|
||||
}
|
||||
|
||||
function onnodeclick() {
|
||||
function onnodeclick() {}
|
||||
|
||||
}
|
||||
function onpopupopened() {}
|
||||
|
||||
function onpopupopened() {
|
||||
|
||||
}
|
||||
|
||||
function onpopupclosed() {
|
||||
}
|
||||
function onpopupclosed() {}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -37,10 +37,10 @@ const newValue = computed({
|
||||
const attrs: any = useAttrs()
|
||||
|
||||
function change(e: string) {
|
||||
newValue.value = e
|
||||
if (attrs.componentProps.change && isFunction(attrs.componentProps.change)) {
|
||||
attrs.componentProps.change(e)
|
||||
}
|
||||
newValue.value = e
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
141
src/components/BasicForm/components/BasicTree.vue
Normal file
141
src/components/BasicForm/components/BasicTree.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<view class="py-7">
|
||||
<u-loading-icon :show="loadingShow" style="justify-content: start" size="20"/>
|
||||
<view @click="open" class="wh-full flex-row items-center justify-between" v-if="!loadingShow">
|
||||
<view class="font-13 text-ellipsis-1" v-if="pickerValue">{{ pickerValue.join(',') }}</view>
|
||||
<view class="font-13 color-9" v-else-if="!attrs.componentProps.disabled">
|
||||
<text v-if="attrs.componentProps&&attrs.componentProps.placeholder">{{
|
||||
attrs.componentProps.placeholder
|
||||
}}
|
||||
</text>
|
||||
<text v-else>请选择{{ attrs.label }}</text>
|
||||
</view>
|
||||
<view v-else>无</view>
|
||||
<uni-icons type="right" size="18" color="#999999" v-if="!attrs.componentProps.disabled"/>
|
||||
</view>
|
||||
<BasicTree ref="basicTreeRef"
|
||||
:range="range"
|
||||
:idKey="savaKey"
|
||||
:rangeKey="rangeKey"
|
||||
:title="'选择'+ attrs.label"
|
||||
@confirm="confirm"
|
||||
v-bind="attrs.componentProps"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BasicTree from '@/components/BasicTree/Tree.vue';
|
||||
/**
|
||||
* BasicPicker 选择器
|
||||
* @property title 顶部title
|
||||
* @property range 渲染数据列表
|
||||
* @property api 渲染数据接口
|
||||
* @property param 接口参数
|
||||
* @property resultKey 数据接口返回字段默认为result
|
||||
* @property rangeKey 显示值的key
|
||||
* @property savaKey 保存值的key
|
||||
*
|
||||
* @property @ok 点击确定事件
|
||||
* @property @change 选择器change事件
|
||||
*/
|
||||
import {isFunction, map} from "lodash";
|
||||
|
||||
const loadingShow = ref(false)
|
||||
const basicTreeRef = ref<any>(null)
|
||||
const props = defineProps(['modelValue'])
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const pickerValue = ref<any>([])
|
||||
|
||||
const newValue = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
const attrs: any = useAttrs()
|
||||
|
||||
const rangeKey = ref(attrs.componentProps && attrs.componentProps.rangeKey || '')
|
||||
const savaKey = ref(attrs.componentProps && attrs.componentProps.savaKey || '')
|
||||
|
||||
const range = computed({
|
||||
get() {
|
||||
if (attrs.componentProps && attrs.componentProps.range) {
|
||||
return attrs.componentProps.range
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
},
|
||||
set(value) {
|
||||
attrs.componentProps.range = value
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function initapi() {
|
||||
if (attrs.componentProps.api && isFunction(attrs.componentProps.api)) {
|
||||
loadingShow.value = true
|
||||
attrs.componentProps.api(attrs.componentProps.param || null).then((res: any) => {
|
||||
attrs.componentProps.range = res[attrs.componentProps.resultKey || 'result']
|
||||
if (attrs.componentProps.request && isFunction(attrs.componentProps.request)) {
|
||||
attrs.componentProps.request(attrs.componentProps.range)
|
||||
}
|
||||
loadingShow.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
initapi()
|
||||
|
||||
function open() {
|
||||
if (!attrs.componentProps.disabled) {
|
||||
basicTreeRef.value._show()
|
||||
}
|
||||
}
|
||||
|
||||
function confirm(value: any) {
|
||||
const valueDataID = map(value, (item) => {
|
||||
return item[attrs.componentProps.savaKey]
|
||||
})
|
||||
newValue.value = valueDataID.join(',')
|
||||
|
||||
if (attrs.componentProps.ok && typeof attrs.componentProps.ok === 'function') {
|
||||
attrs.componentProps.ok(value, attrs.componentProps.range)
|
||||
}
|
||||
}
|
||||
|
||||
function hx(rangeData: any, data: any) {
|
||||
let valueList = data.split(',')
|
||||
for (const key in rangeData) {
|
||||
for (const vkey in valueList) {
|
||||
if (rangeData[key][attrs.componentProps.savaKey] == valueList[vkey]) {
|
||||
rangeData[key].checked = true;
|
||||
if (!attrs.componentProps.multiple) {
|
||||
pickerValue.value = []
|
||||
}
|
||||
pickerValue.value.push(rangeData[key][attrs.componentProps.rangeKey])
|
||||
}
|
||||
}
|
||||
if (rangeData[key].children && rangeData[key].children.length > 0) {
|
||||
hx(rangeData[key].children, data)
|
||||
}
|
||||
}
|
||||
range.value = rangeData;
|
||||
}
|
||||
|
||||
|
||||
watchEffect(() => {
|
||||
if (newValue.value || newValue.value == 0) {
|
||||
if (attrs.componentProps.range && attrs.componentProps.range.length > 0) {
|
||||
hx(attrs.componentProps.range, newValue.value.toString())
|
||||
}
|
||||
} else {
|
||||
pickerValue.value = newValue.value
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
<FormBasicDataPicker v-bind="attrs" v-if="isShow('BasicDataPicker')" v-model="newValue"/>
|
||||
<FormBasicSearchList v-bind="attrs" v-if="isShow('BasicSearchList')" v-model="newValue"/>
|
||||
<FormBasicDateTimes v-bind="attrs" v-if="isShow('BasicDateTimes')" v-model="newValue"/>
|
||||
<FormBasicTree v-bind="attrs" v-if="isShow('BasicTree')" v-model="newValue"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
1
src/components/BasicForm/type/useForm.d.ts
vendored
1
src/components/BasicForm/type/useForm.d.ts
vendored
@ -26,6 +26,7 @@ type Component =
|
||||
| 'BasicDataPicker'
|
||||
| 'BasicSearchList'
|
||||
| 'BasicDateTimes'
|
||||
| 'BasicTree'
|
||||
|
||||
interface FormsSchema {
|
||||
field?: string,
|
||||
|
||||
@ -407,7 +407,7 @@ export default {
|
||||
background: #FFF;
|
||||
margin: 10px 0;
|
||||
width: 90vw;
|
||||
height: 90vh;
|
||||
height: 88vh;
|
||||
align-self: center;
|
||||
// pointer-events:none;
|
||||
}
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
const ip: string = "dj.zhongjingzh.com";
|
||||
const ip: string = "119.29.194.155:8893";
|
||||
const fwqip: string = "yufangzc.com";
|
||||
//打包服务器接口代理标识
|
||||
const SERVERAGENT: string = "/";
|
||||
const SERVERAGENT: string = "/jzd-api";
|
||||
//本地代理url地址,配置了就启动代理,没配置就不启动代理
|
||||
export const HOMEAGENT: string = "";
|
||||
// 接口地址
|
||||
export const BASE_URL: string =
|
||||
process.env.NODE_ENV == "development" ? `http://${ip}/yqdj` : SERVERAGENT;
|
||||
process.env.NODE_ENV == "development" ? `http://${ip}/zhxy` : SERVERAGENT;
|
||||
// WebSocket地址
|
||||
export const BASE_WS_URL: string = `wss://${ip}`;
|
||||
//图片地址
|
||||
export const BASE_IMAGE_URL: string = `http://${ip}`;
|
||||
export const BASE_IMAGE_URL: string = process.env.NODE_ENV == "development" ? `http://${ip}` : `https://${fwqip}`;
|
||||
//存token的key
|
||||
export const AUTH_KEY: string = "satoken";
|
||||
//token过期返回状态码
|
||||
@ -17,7 +18,7 @@ export const RESULT_CODE_NOT_LOGIN: number = 10;
|
||||
//是否打印接口日志
|
||||
export const ISREQUESTLOG: boolean = false;
|
||||
//是否打开登录页面拦截
|
||||
export const ISROUTERINTERCEPT: boolean = false;
|
||||
export const ISROUTERINTERCEPT: boolean = true;
|
||||
//配置路由白名单
|
||||
export const WHITELIST: WhiteList = [];
|
||||
//主题颜色
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "模版",
|
||||
"name": "智慧校园",
|
||||
"appid": "__UNI__27C6F45",
|
||||
"description": "",
|
||||
"versionName": "1.0.0",
|
||||
@ -207,9 +207,9 @@
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"publicPath": "/",
|
||||
"publicPath": "/zhxy-jzd",
|
||||
"router": {
|
||||
"base": "/",
|
||||
"base": "/zhxy-jzd/",
|
||||
"mode": "hash"
|
||||
},
|
||||
"sdkConfigs": {
|
||||
|
||||
@ -91,13 +91,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/parentRegister/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "家长注册",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/class-schedule/index",
|
||||
"style": {
|
||||
@ -195,6 +188,26 @@
|
||||
"navigationBarTitleText": "俱乐部选课",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/course-selection/notice",
|
||||
"style": {
|
||||
"navigationBarTitleText": "告知书",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/course-selection/enrolled",
|
||||
"style": {
|
||||
"navigationBarTitleText": "已报名",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
} , {
|
||||
"path": "pages/base/course-selection/notopen",
|
||||
"style": {
|
||||
"navigationBarTitleText": "未开放",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
<view class="course-info">
|
||||
<image
|
||||
class="course-image"
|
||||
:src="courseDetail.image || '/static/images/course-default.jpg'"
|
||||
:src="courseDetail.xkkcImg"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
|
||||
@ -21,11 +21,12 @@
|
||||
<view class="course-location"
|
||||
>上课地点:{{ courseDetail.location }}</view
|
||||
>
|
||||
<view class="course-price"
|
||||
>金额:<text class="price-value"
|
||||
>¥{{ courseDetail.price }}</text
|
||||
></view
|
||||
<view class="course-time"
|
||||
>上课时间:{{ courseDetail.studyTime }}</view
|
||||
>
|
||||
<view class="course-price">
|
||||
金额:<text class="price-value">¥{{ courseDetail.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -36,17 +37,28 @@
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="teacher-info">
|
||||
<!-- 教师头部信息区域 -->
|
||||
<view class="teacher-header">
|
||||
<image
|
||||
class="teacher-avatar"
|
||||
:src="teacherInfo.avatar || '/static/images/teacher-avatar.jpg'"
|
||||
:src="teacherInfo.avatar"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="teacher-basic-info">
|
||||
<view class="teacher-name">{{ teacherInfo.name }}</view>
|
||||
<view class="teacher-title">课程教师</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 教师简介区域 -->
|
||||
<view class="teacher-intro-section">
|
||||
<view class="intro-title">教师简介</view>
|
||||
<view class="teacher-intro">
|
||||
<text>{{ teacherInfo.introduction }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 教学理念 -->
|
||||
<view class="info-card">
|
||||
@ -64,6 +76,7 @@
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="content-section">
|
||||
<template v-if="teachingPlan && teachingPlan.length > 0">
|
||||
<view
|
||||
v-for="(phase, index) in teachingPlan"
|
||||
:key="index"
|
||||
@ -71,6 +84,13 @@
|
||||
>
|
||||
<text>{{ phase }}</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="empty-data">
|
||||
<u-icon name="info-circle" color="#C8C9CC" size="18"></u-icon>
|
||||
<text>暂无教学计划</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -90,57 +110,81 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import { navigateBack } from "@/utils/uniapp";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { imagUrl } from "@/utils";
|
||||
import { kcjhFindKcjhByKcIdApi } from "@/api/base/server";
|
||||
|
||||
// 定义课程数据类型
|
||||
interface CourseData {
|
||||
id?: string;
|
||||
kcmc?: string;
|
||||
jsName?: string;
|
||||
kcdd?: string;
|
||||
kcje?: number;
|
||||
studyTime?: string;
|
||||
kcjsms?: string;
|
||||
jxll?: string;
|
||||
remark?: string;
|
||||
xkkcImg?: string;
|
||||
[key: string]: any; // 允许其他字段
|
||||
}
|
||||
|
||||
const useData = useDataStore();
|
||||
const { kcData } = storeToRefs(useData);
|
||||
|
||||
// 教学计划 - 此处假设没有具体教学计划字段,将备注内容拆分为教学计划
|
||||
const teachingPlan = ref<string[]>([]);
|
||||
|
||||
const courseData = kcData.value as CourseData;
|
||||
if (courseData && courseData.id) {
|
||||
kcjhFindKcjhByKcIdApi({
|
||||
xkkcId: courseData.id,
|
||||
}).then((res) => {
|
||||
if (res.resultCode == 1) {
|
||||
teachingPlan.value = res.result.map(
|
||||
(item: any) => item.jhjd + ":" + item.jhms
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 课程详情数据
|
||||
const courseDetail = ref({
|
||||
id: 2,
|
||||
title: "机器人创客",
|
||||
teacher: "叶老师",
|
||||
location: "第一教学楼302",
|
||||
price: 142,
|
||||
image: "/static/images/robot-course.jpg",
|
||||
const courseDetail = computed(() => {
|
||||
const data = (kcData.value as CourseData) || {};
|
||||
return {
|
||||
id: data.id || "",
|
||||
title: data.kcmc || "暂无课程名称",
|
||||
teacher: data.jsName || "暂无教师信息",
|
||||
location: data.kcdd || "暂无地点信息",
|
||||
price: data.kcje || 0,
|
||||
studyTime: data.studyTime || "暂无上课时间",
|
||||
xkkcImg: data.xkkcImg || "/static/images/robot-course.jpg", // 默认图片
|
||||
};
|
||||
});
|
||||
|
||||
// 教师信息
|
||||
const teacherInfo = ref({
|
||||
name: "叶老师",
|
||||
avatar: "/static/images/teacher-avatar.jpg",
|
||||
introduction:
|
||||
"叶老师,男,出生于1997年7月10日,青少年机器人创客指导教师,指导祥富小学-晟航水木年华获得2022年青少年机器人竞赛小学组三等奖。",
|
||||
const teacherInfo = computed(() => {
|
||||
const data = (kcData.value as CourseData) || {};
|
||||
return {
|
||||
name: data.jsName || "暂无教师信息",
|
||||
avatar: imagUrl(data.jstx), // 默认头像
|
||||
introduction: data.kcjsms || "暂无教师介绍",
|
||||
};
|
||||
});
|
||||
|
||||
// 教学理念
|
||||
const teachingPhilosophy = ref(
|
||||
'"做中学、玩中学"的教育理念,机器人课程最大的优势就是能够让孩子在"玩"中去探索,去体验属于他们自己的世界,很多孩子刚开始接触的时候都是出于兴趣。培养孩子更进一步的能力,提高孩子的学习效果也的确需要从兴趣开始。但真正激发孩子能力,形成学习动力的是对目标的追求。我就通过机器人赛事帮助孩子把"兴趣"变成学习的目标,继而助力孩子未来成长的道路。'
|
||||
);
|
||||
|
||||
// 教学计划
|
||||
const teachingPlan = ref([
|
||||
"第一阶段:了解机器人的组成,知道每个零件的名称及用途,认识机器人的结构。",
|
||||
"第二阶段:在老师的引导下,分组搭建机器人,注意引导幼儿理解机器人的数据线连接和遥控器方向的关系。",
|
||||
"第三阶段:学会操控机器人的移动方向,并练习把魔方根据要求推到指定位置。",
|
||||
"第四阶段:组织幼儿参加创客机器人比赛。",
|
||||
]);
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
// 页面加载时获取课程详情
|
||||
onMounted(() => {
|
||||
// 实际应用中从URL参数获取课程ID,然后请求详情
|
||||
const courseId = uni.getStorageSync("currentCourseId") || 2;
|
||||
// fetchCourseDetail(courseId);
|
||||
const teachingPhilosophy = computed(() => {
|
||||
const data = (kcData.value as CourseData) || {};
|
||||
return data.jxll || "暂无教学理念信息";
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.course-detail {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f7fa;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.nav-bar {
|
||||
@ -195,7 +239,7 @@ onMounted(() => {
|
||||
|
||||
.course-image {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
height: 138px;
|
||||
border-radius: 8px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
@ -217,6 +261,12 @@ onMounted(() => {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.course-time {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.course-price {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
@ -231,19 +281,62 @@ onMounted(() => {
|
||||
|
||||
.teacher-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.teacher-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.teacher-avatar {
|
||||
width: 80px;
|
||||
height: 100px;
|
||||
border-radius: 4px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
|
||||
.teacher-basic-info {
|
||||
.teacher-name {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.teacher-title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
background-color: #f4f7fc;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.teacher-intro-section {
|
||||
width: 100%;
|
||||
|
||||
.intro-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #555;
|
||||
margin-bottom: 8px;
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #2879ff;
|
||||
}
|
||||
|
||||
.teacher-intro {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
background-color: #f8f9fc;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,6 +352,19 @@ onMounted(() => {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
|
||||
text {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-action {
|
||||
|
||||
428
src/pages/base/course-selection/enrolled.vue
Normal file
428
src/pages/base/course-selection/enrolled.vue
Normal file
@ -0,0 +1,428 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<view class="enrolled-page">
|
||||
<!-- 已报名状态提示 -->
|
||||
<view class="status-card">
|
||||
<view class="status-icon">
|
||||
<u-icon name="checkmark" size="32" color="#3FBF72"></u-icon>
|
||||
</view>
|
||||
<view class="status-text">已报名</view>
|
||||
<view class="status-desc">该学生已成功报名以下兴趣课程</view>
|
||||
</view>
|
||||
|
||||
<!-- 学生信息卡片 -->
|
||||
<view class="info-card student-card">
|
||||
<view class="card-title">学生信息</view>
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="student-info">
|
||||
<view class="student-avatar">
|
||||
<image
|
||||
:src="studentInfo.avatar || '/static/base/home/11222.png'"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
</view>
|
||||
<view class="student-details">
|
||||
<view class="student-name">{{ studentInfo.xm }}</view>
|
||||
<view class="student-class"
|
||||
>{{ studentInfo.njmc }} {{ studentInfo.bjmc }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 已报名课程信息 -->
|
||||
<view class="info-card">
|
||||
<view class="card-title">已报名课程</view>
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="course-info">
|
||||
<image
|
||||
class="course-image"
|
||||
:src="enrolledCourse.image || '/static/base/home/2211.png'"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="course-details">
|
||||
<view class="course-name">{{ enrolledCourse.title }}</view>
|
||||
<view class="course-teacher"
|
||||
>开课老师:{{ enrolledCourse.teacher }}</view
|
||||
>
|
||||
<view class="course-time">上课时间:{{ enrolledCourse.time }}</view>
|
||||
<view class="course-location"
|
||||
>上课地点:{{ enrolledCourse.location }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 报名信息 -->
|
||||
<view class="enrollment-info">
|
||||
<view class="info-item">
|
||||
<text class="info-label">报名时间:</text>
|
||||
<text class="info-value">{{ enrolledCourse.enrollDate }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">课程费用:</text>
|
||||
<text class="info-value highlight">¥{{ enrolledCourse.fee }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">支付状态:</text>
|
||||
<text
|
||||
class="info-value"
|
||||
:class="enrolledCourse.isPaid ? 'paid' : 'unpaid'"
|
||||
>
|
||||
{{ enrolledCourse.isPaid ? "已支付" : "未支付" }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 温馨提示 -->
|
||||
<!-- <view class="notice-card">
|
||||
<view class="notice-title">
|
||||
<u-icon name="info-circle" size="18" color="#2879FF"></u-icon>
|
||||
<text>温馨提示</text>
|
||||
</view>
|
||||
<view class="notice-content">
|
||||
<text>1. 课程一经报名成功,不可取消或更换;</text>
|
||||
<text>2. 如有特殊情况需要请假,请提前与老师联系;</text>
|
||||
<text>3. 请按时上课,迟到将影响学习效果。</text>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view class="bottom-actions" v-if="!enrolledCourse.isPaid">
|
||||
<u-button text="继续支付" type="primary" @click="goPay"></u-button>
|
||||
<!-- <u-button
|
||||
text="返回选课"
|
||||
:plain="true"
|
||||
@click="goBack"
|
||||
></u-button> -->
|
||||
</view>
|
||||
</template>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
|
||||
const { getUser } = useUserStore();
|
||||
|
||||
// 获取路由参数
|
||||
const studentId = ref("");
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
// @ts-ignore
|
||||
const options = currentPage.$page?.options;
|
||||
if (options && options.studentId) {
|
||||
studentId.value = options.studentId;
|
||||
}
|
||||
});
|
||||
|
||||
// 当前学生信息
|
||||
const studentInfo = ref({
|
||||
id: "",
|
||||
xm: "加载中...",
|
||||
njmc: "",
|
||||
bjmc: "",
|
||||
avatar: "",
|
||||
});
|
||||
|
||||
// 已报名课程信息
|
||||
const enrolledCourse = ref({
|
||||
id: "",
|
||||
title: "少儿声乐",
|
||||
image: "",
|
||||
teacher: "张老师",
|
||||
time: "每周一 16:00-17:30",
|
||||
location: "艺术楼 203教室",
|
||||
enrollDate: "2023-09-15 14:30:45",
|
||||
fee: 420,
|
||||
isPaid: false,
|
||||
});
|
||||
|
||||
// 获取学生信息
|
||||
const fetchStudentInfo = () => {
|
||||
// 在实际应用中,这里应该从学生列表中找到对应ID的学生
|
||||
// 或者调用接口获取详细信息
|
||||
const student = getUser.xsList.find((s: any) => s.id === studentId.value);
|
||||
if (student) {
|
||||
studentInfo.value = student;
|
||||
}
|
||||
|
||||
// TODO: 添加实际的接口调用
|
||||
// const url = '/api/student/detail';
|
||||
// const params = { studentId: studentId.value };
|
||||
// return new Promise((resolve) => {
|
||||
// // 模拟API调用
|
||||
// setTimeout(() => {
|
||||
// resolve();
|
||||
// }, 500);
|
||||
// });
|
||||
};
|
||||
|
||||
// 获取已报名课程信息
|
||||
const fetchEnrolledCourse = () => {
|
||||
// TODO: 添加实际的接口调用
|
||||
// const url = '/api/course/enrolled';
|
||||
// const params = { studentId: studentId.value };
|
||||
// return new Promise((resolve) => {
|
||||
// // 模拟API调用
|
||||
// setTimeout(() => {
|
||||
// resolve();
|
||||
// }, 500);
|
||||
// });
|
||||
|
||||
// 模拟数据
|
||||
setTimeout(() => {
|
||||
enrolledCourse.value = {
|
||||
id: "course123",
|
||||
title: "少儿声乐",
|
||||
image: "/static/base/home/2211.png",
|
||||
teacher: "张老师",
|
||||
time: "每周一 16:00-17:30",
|
||||
location: "艺术楼 203教室",
|
||||
enrollDate: "2023-09-15 14:30:45",
|
||||
fee: 420,
|
||||
isPaid: Math.random() > 0.5, // 随机生成支付状态
|
||||
};
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 去支付
|
||||
const goPay = () => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/base/course-selection/payment?courseId=${enrolledCourse.value.id}&studentId=${studentId.value}`,
|
||||
});
|
||||
};
|
||||
|
||||
// 返回选课页面
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
uni.showLoading({ title: "加载中..." });
|
||||
|
||||
// 获取学生信息和已报名课程信息
|
||||
Promise.all([fetchStudentInfo(), fetchEnrolledCourse()]).finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.enrolled-page {
|
||||
background-color: #f5f7fa;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.status-card {
|
||||
background: linear-gradient(135deg, #3fbf72, #2ab559);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 15px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
|
||||
.status-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.status-desc {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&.student-card {
|
||||
background-color: #eef4ff;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background-color: #eee;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.student-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.student-avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin-right: 15px;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.student-details {
|
||||
.student-name {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.student-class {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-info {
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.course-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
margin-right: 15px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.course-details {
|
||||
flex: 1;
|
||||
|
||||
.course-name {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.course-teacher,
|
||||
.course-time,
|
||||
.course-location {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.enrollment-info {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
|
||||
&.highlight {
|
||||
color: #ff6b01;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.paid {
|
||||
color: #3fbf72;
|
||||
}
|
||||
|
||||
&.unpaid {
|
||||
color: #ff5252;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notice-card {
|
||||
background-color: #fff9e6;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
|
||||
.notice-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
text {
|
||||
margin-left: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-content {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
|
||||
text {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
:deep(.u-button) {
|
||||
flex: 1;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
60
src/pages/base/course-selection/notice.vue
Normal file
60
src/pages/base/course-selection/notice.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<view class="p-15">
|
||||
<view class="white-bg-color p-15 r-md">
|
||||
<view> 各位家长:</view>
|
||||
<view class="notice-text">
|
||||
随着素质教育的不断深入,学生各项素质、能力的培养越来越受到学校、家庭的重视。我校根据教育局的有关精神,继续举办兴趣班。请各位家长根据实际情况,遵照"孩子自主,家长自愿"的原则,选择兴趣班,请点击下一步确认知晓告知内容。
|
||||
</view>
|
||||
</view>
|
||||
<BasicSign ref="signCompRef" title="签名"></BasicSign>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view class="white-bg-color py-5">
|
||||
<view class="flex-row items-center pb-10 pt-5">
|
||||
<u-button
|
||||
text="下一步"
|
||||
class="mx-15"
|
||||
type="primary"
|
||||
@click="submit"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { xkListApi } from "@/api/base/server";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
|
||||
const signCompRef = ref<any>(null);
|
||||
const sign_file = ref<any>(null);
|
||||
const { setData, getGlobal } = useDataStore();
|
||||
async function submit() {
|
||||
// 显示加载中
|
||||
const data = await signCompRef.value.getSyncSignature();
|
||||
sign_file.value = data.base64;
|
||||
setData({
|
||||
sign_file: sign_file.value,
|
||||
});
|
||||
if (getGlobal.type == 1) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/index",
|
||||
});
|
||||
}
|
||||
if (getGlobal.type == 2) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/club-selection",
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notice-text {
|
||||
margin-top: 10px;
|
||||
text-indent: 2em; /* 添加两个中文字符的缩进 */
|
||||
}
|
||||
</style>
|
||||
171
src/pages/base/course-selection/notopen.vue
Normal file
171
src/pages/base/course-selection/notopen.vue
Normal file
@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<view class="notopen-page">
|
||||
<!-- 未开放状态图标 -->
|
||||
<view class="status-icon">
|
||||
<u-icon name="clock" size="80" color="#A0CFFF"></u-icon>
|
||||
</view>
|
||||
|
||||
<!-- 状态说明 -->
|
||||
<view class="status-text">
|
||||
<view class="title">课程报名尚未开放</view>
|
||||
<view class="subtitle">请耐心等待学校通知</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<view class="info-card">
|
||||
<view class="info-title">
|
||||
<u-icon name="info-circle" size="18" color="#2879FF"></u-icon>
|
||||
<text>温馨提示</text>
|
||||
</view>
|
||||
<view class="info-content">
|
||||
<text>1. 学校将按计划开放兴趣课程报名,敬请关注学校通知;</text>
|
||||
<text>2. 为保证公平,课程报名将统一时间开放;</text>
|
||||
<text>3. 开放报名后,您可以为孩子选择合适的兴趣课程;</text>
|
||||
<text>4. 如有疑问,请联系班主任老师咨询详情。</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 时间提示 -->
|
||||
<!-- <view class="time-info">
|
||||
<view class="time-title">预计开放时间</view>
|
||||
<view class="time-value">9月15日 14:00</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 课程预览图 -->
|
||||
<!-- <view class="preview-container">
|
||||
<image
|
||||
src="/static/base/home/2211.png"
|
||||
mode="aspectFill"
|
||||
class="preview-image"
|
||||
></image>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
// 返回首页
|
||||
const goHome = () => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/home/index"
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 页面加载时可以执行一些操作,例如记录用户访问日志
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notopen-page {
|
||||
background-color: #f5f7fa;
|
||||
padding: 30px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
margin-top: 50px;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
background-color: rgba(160, 207, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.info-card {
|
||||
width: 100%;
|
||||
background-color: #eef4ff;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.info-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
|
||||
text {
|
||||
margin-left: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.info-content {
|
||||
text {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time-info {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.time-title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.time-value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
color: #2879FF;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
width: 100%;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-actions {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
@ -1,403 +0,0 @@
|
||||
<template>
|
||||
<BasicLayout>
|
||||
<view class="page-container">
|
||||
<view class="notice-box">
|
||||
<text class="notice-text"
|
||||
>特别提示:家中家庭成员可多人注册,可接收孩子在校情况、学业情况等。</text
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
v-for="(student, index) in students"
|
||||
:key="index"
|
||||
class="form-section mb-15"
|
||||
>
|
||||
<view v-if="index > 0" class="remove-btn" @click="removeStudent(index)">
|
||||
<u-icon name="minus-circle" color="#ff4d4f" size="18"></u-icon>
|
||||
</view>
|
||||
|
||||
<view class="avatar-section">
|
||||
<view class="avatar-uploader-container-rect">
|
||||
<CustomUpload
|
||||
@select="(event) => afterRead(event, index)"
|
||||
@close="handleAvatarClose(index)"
|
||||
:sourceType="['camera', 'album']"
|
||||
>
|
||||
<view class="avatar-placeholder">
|
||||
<view class="wh-full flex-col-center">
|
||||
<svg
|
||||
t="1729656215869"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="5302"
|
||||
width="32"
|
||||
height="32"
|
||||
>
|
||||
<path
|
||||
d="M851.552 890.88 172.448 890.88c-74.592 0-135.296-60.672-135.296-135.296L37.152 370.752c0-74.624 60.672-135.328 135.296-135.328l132.16 0L302.912 195.904c0-34.624 28.192-62.816 62.816-62.816l302.016 0c29.408 0 53.312 23.904 53.312 53.312l0 49.024 130.464 0c74.592 0 135.296 60.672 135.296 135.328l0 384.832C986.816 830.208 926.144 890.88 851.552 890.88zM172.448 283.456c-48.128 0-87.296 39.168-87.296 87.328l0 384.832c0 48.128 39.168 87.296 87.296 87.296l679.104 0c48.128 0 87.296-39.168 87.296-87.296L938.848 370.752c0-48.16-39.168-87.328-87.296-87.328L716.8 283.424c-24.096 0-43.712-19.616-43.712-43.712L673.088 186.4c0-2.944-2.368-5.312-5.312-5.312l-302.016 0c-8.16 0-14.816 6.656-14.816 14.816L350.944 237.12c0 25.536-20.768 46.304-46.304 46.304L172.448 283.424zM512 755.84c-107.04 0-194.08-87.072-194.08-194.08S404.992 367.68 512 367.68s194.08 87.072 194.08 194.08S619.04 755.84 512 755.84zM512 415.68c-80.576 0-146.08 65.536-146.08 146.08S431.456 707.84 512 707.84s146.08-65.536 146.08-146.08S592.576 415.68 512 415.68zM816.8 438.016c-25.568 0-46.336-20.768-46.336-46.336s20.768-46.336 46.336-46.336 46.336 20.768 46.336 46.336S842.368 438.016 816.8 438.016zM816.8 390.016l-1.664 1.664c0 0.896 0.736 1.664 1.664 1.664L816.8 390.016z"
|
||||
fill="#cdcdcd"
|
||||
p-id="5303"
|
||||
></path>
|
||||
</svg>
|
||||
</view>
|
||||
</view>
|
||||
</CustomUpload>
|
||||
</view>
|
||||
<text class="avatar-upload-note">上传学生人像用于校园进出</text>
|
||||
</view>
|
||||
|
||||
<view class="student-info-form">
|
||||
<u--form label-width="auto">
|
||||
<u-form-item
|
||||
label="姓名"
|
||||
:prop="`students[${index}].name`"
|
||||
required
|
||||
borderBottom
|
||||
>
|
||||
<u--input
|
||||
v-model="student.name"
|
||||
placeholder="请输入子女姓名"
|
||||
border="none"
|
||||
inputAlign="right"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="身份证号"
|
||||
:prop="`students[${index}].idCard`"
|
||||
required
|
||||
borderBottom
|
||||
>
|
||||
<u--input
|
||||
v-model="student.idCard"
|
||||
placeholder="请输入子女身份证号"
|
||||
border="none"
|
||||
inputAlign="right"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
<view class="add-child-btn mb-15" @click="addMoreChildren">
|
||||
<u-icon name="plus" color="#416AF2" size="20"></u-icon>
|
||||
<text class="add-child-btn-text">新增多孩</text>
|
||||
</view>
|
||||
|
||||
<BasicForm @register="register"></BasicForm>
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view class="white-bg-color py-5">
|
||||
<view class="flex-row items-center pb-10 pt-5">
|
||||
<u-button text="提交" class="mx-15" type="primary" @click="submit" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { hideLoading, showLoading, showToast } from "@/utils/uniapp";
|
||||
import { ref } from "vue";
|
||||
import { attachmentUpload } from "@/api/system/upload";
|
||||
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
||||
|
||||
import { useForm } from "@/components/BasicForm/hooks/useForm";
|
||||
|
||||
const [register, { getValue }] = useForm({
|
||||
formsProps: { labelWidth: 100 },
|
||||
schema: [
|
||||
{ title: "监督人信息" },
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "与学生关系",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "姓名",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "手机号",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "工作单位",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "职务",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gsmc",
|
||||
label: "家庭地址",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const students = ref([
|
||||
{
|
||||
name: "",
|
||||
idCard: "",
|
||||
avatar: "",
|
||||
avatarFile: null as UniNamespace.ChooseImageSuccessCallbackResult | null,
|
||||
avatarServerPath: "",
|
||||
},
|
||||
]);
|
||||
|
||||
async function afterRead(event: any, index: number) {
|
||||
if (!event.tempFilePaths || event.tempFilePaths.length === 0) {
|
||||
showToast({ title: "图片选择失败", icon: "none" });
|
||||
return;
|
||||
}
|
||||
const tempFilePath = event.tempFilePaths[0];
|
||||
students.value[index].avatar = tempFilePath;
|
||||
students.value[index].avatarFile = event;
|
||||
|
||||
showLoading({ title: "上传中" });
|
||||
try {
|
||||
const { result } = await attachmentUpload(tempFilePath);
|
||||
if (result && result.length > 0 && result[0].filePath) {
|
||||
students.value[index].avatarServerPath = result[0].filePath;
|
||||
console.log(`Student ${index} avatar uploaded:`, result[0].filePath);
|
||||
showToast({ title: "上传成功" });
|
||||
} else {
|
||||
showToast({ title: "上传失败,请重试", icon: "none" });
|
||||
console.error("Upload result format error:", result);
|
||||
}
|
||||
} catch (error) {
|
||||
showToast({ title: "上传出错", icon: "none" });
|
||||
console.error("Upload error:", error);
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
function handleAvatarClose(index: number) {
|
||||
students.value[index].avatar = "";
|
||||
students.value[index].avatarFile = null;
|
||||
students.value[index].avatarServerPath = "";
|
||||
console.log(`Student ${index} avatar removed`);
|
||||
}
|
||||
|
||||
function addMoreChildren() {
|
||||
students.value.push({
|
||||
name: "",
|
||||
idCard: "",
|
||||
avatar: "",
|
||||
avatarFile: null,
|
||||
avatarServerPath: "",
|
||||
});
|
||||
}
|
||||
|
||||
function removeStudent(index: number) {
|
||||
if (students.value.length > 1) {
|
||||
students.value.splice(index, 1);
|
||||
} else {
|
||||
showToast({ title: "至少需要一个学生信息", icon: "none" });
|
||||
}
|
||||
}
|
||||
|
||||
async function submit() {
|
||||
for (const student of students.value) {
|
||||
if (!student.name || !student.idCard) {
|
||||
showToast({ title: "请完整填写所有学生信息", icon: "none" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
const formData = await getValue();
|
||||
console.log(formData);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-container {
|
||||
padding: 15px; /* Consistent padding */
|
||||
}
|
||||
|
||||
.notice-box {
|
||||
background-color: #fff1f0; /* Slightly lighter red */
|
||||
padding: 12px 18px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.notice-text {
|
||||
color: #fa541c; /* Adjusted red color */
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 20px 20px 0 20px;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||||
/* Added margin-bottom directly here for spacing between sections */
|
||||
margin-bottom: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.avatar-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 25px; /* Increased margin */
|
||||
}
|
||||
|
||||
/* Keep avatar uploader styles relevant to CustomUpload */
|
||||
/* Replace with rectangular styles */
|
||||
.avatar-uploader-container-rect {
|
||||
/* Assuming uni.rpx units based on class names like wi-180, he-240 */
|
||||
width: 180rpx;
|
||||
height: 240rpx;
|
||||
margin: 0 auto 10px auto; /* mx-auto mb-10 */
|
||||
border-radius: 6px; /* r-md approximation */
|
||||
border: 1px solid #cccccc;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
/* Remove old circular styles */
|
||||
/* .avatar-uploader-container { ... } */
|
||||
|
||||
.avatar-placeholder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Keep inner placeholder for centering SVG */
|
||||
.avatar-placeholder-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* Remove old hint style */
|
||||
/* .avatar-upload-hint { ... } */
|
||||
|
||||
.avatar-upload-note {
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.student-info-form {
|
||||
margin-bottom: 20px; /* Restore original margin */
|
||||
}
|
||||
|
||||
.form-title {
|
||||
display: block;
|
||||
font-size: 16px; /* Slightly larger title */
|
||||
font-weight: 600; /* Bolder */
|
||||
margin-bottom: 15px; /* Space below title */
|
||||
}
|
||||
|
||||
/* Restore remove button style if needed, or adapt */
|
||||
/* Updated remove button style */
|
||||
.remove-btn {
|
||||
position: absolute;
|
||||
top: 10px; /* Closer to top edge */
|
||||
right: 10px; /* Closer to right edge */
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
/* Optional: add padding for easier clicking */
|
||||
// padding: 5px;
|
||||
}
|
||||
|
||||
.add-child-btn {
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 15px; /* Increased padding */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10px; /* Increased margin */
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-child-btn-text {
|
||||
color: #416af2;
|
||||
margin-left: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Adjust uview form item styles */
|
||||
::v-deep .u-form-item {
|
||||
margin-bottom: 0; /* Remove default margin if any */
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body {
|
||||
padding: 15px 0 !important; /* Adjusted padding */
|
||||
/* Align items vertically if label wraps */
|
||||
// align-items: flex-start;
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body__left {
|
||||
/* Allow label to take necessary width, adjust as needed */
|
||||
// flex: 0 0 80px;
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body__left__text {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
line-height: 1.5; /* Improve line spacing if label wraps */
|
||||
/* Ensure required asterisk is red and BEFORE the text */
|
||||
display: flex; /* Use flex to control order */
|
||||
align-items: center; /* Vertically center asterisk and text */
|
||||
|
||||
span {
|
||||
color: #f56c6c;
|
||||
/* Order asterisk first */
|
||||
order: -1;
|
||||
margin-right: 4px;
|
||||
/* Adjust vertical alignment if needed */
|
||||
// line-height: 1;
|
||||
// display: inline-block;
|
||||
// vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-input {
|
||||
text-align: right; /* Align input text to the right */
|
||||
}
|
||||
|
||||
::v-deep .u-border-bottom {
|
||||
/* Ensure border spans full width if needed, or adjust */
|
||||
// left: 0 !important;
|
||||
// right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,24 +1,62 @@
|
||||
<template>
|
||||
<view class="wh-full">
|
||||
<BasicLoading :isShow="isShow" bgColor="#fff" isShowTitle textColor="#000" title="启动中..." :type="1"/>
|
||||
<BasicLoading
|
||||
:isShow="isShow"
|
||||
bgColor="#fff"
|
||||
isShowTitle
|
||||
textColor="#000"
|
||||
title="启动中..."
|
||||
:type="1"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {onShow} from "@dcloudio/uni-app";
|
||||
import {isTabBar} from "@/utils/uniapp";
|
||||
import pages from '@/pages.json'
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import pages from "@/pages.json";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { checkOpenId } from "@/api/system/login";
|
||||
import { isTabBar } from "@/utils/uniapp";
|
||||
|
||||
const isShow = ref(true)
|
||||
onShow(async () => {
|
||||
if (isTabBar()) {
|
||||
uni.switchTab({
|
||||
url: '/' + (pages as any).tabBar.list[0].pagePath
|
||||
})
|
||||
const { setGlobal, getGlobal } = useDataStore();
|
||||
const { afterLoginAction, getToken } = useUserStore();
|
||||
const { setFile, getFile } = useDataStore();
|
||||
const isShow = ref(true);
|
||||
|
||||
function toHome(data: any) {
|
||||
if (data.type == 1 || data.type == 2) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/notice",
|
||||
});
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: '/' + pages.pages[1].path
|
||||
})
|
||||
url: "/pages/base/home/index",
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(async (data: any) => {
|
||||
setGlobal(data);
|
||||
if (!getToken) {
|
||||
if (data && data.openId) {
|
||||
checkOpenId({ openId: data.openId, appCode: "JZ" })
|
||||
.then(async (res) => {
|
||||
if (res.resultCode == 1) {
|
||||
if (res.result) {
|
||||
afterLoginAction(res.result);
|
||||
toHome(data);
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/parentRegister/index",
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {});
|
||||
}
|
||||
} else {
|
||||
toHome(data);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1,20 +1,29 @@
|
||||
<template>
|
||||
<view class="register-container p-30">
|
||||
<!-- 顶部 Logo -->
|
||||
<image
|
||||
class="logo"
|
||||
src="@/static/system/login/logo.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<view class="form-card">
|
||||
<!-- 头像和标题 -->
|
||||
<view
|
||||
class="wi-180 he-240 mx-auto r-md mb-20"
|
||||
style="border: 1px solid #cccccc"
|
||||
<BasicLayout>
|
||||
<view class="page-container">
|
||||
<view class="notice-box">
|
||||
<text class="notice-text"
|
||||
>特别提示:家中家庭成员可多人注册,可接收孩子在校情况、学业情况等。</text
|
||||
>
|
||||
<CustomUpload @select="afterRead" :sourceType="['camera']">
|
||||
</view>
|
||||
<view
|
||||
v-for="(student, index) in students"
|
||||
:key="index"
|
||||
class="form-section mb-15"
|
||||
>
|
||||
<view v-if="index > 0" class="remove-btn" @click="removeStudent(index)">
|
||||
<u-icon name="minus-circle" color="#ff4d4f" size="18"></u-icon>
|
||||
</view>
|
||||
|
||||
<view class="avatar-section">
|
||||
<view class="avatar-uploader-container-rect">
|
||||
<CustomUpload
|
||||
@select="(event:any) => afterRead(event, index)"
|
||||
@close="handleAvatarClose(index)"
|
||||
:sourceType="['camera', 'album']"
|
||||
:value="student.xstx"
|
||||
>
|
||||
<view class="avatar-placeholder">
|
||||
<view class="wh-full flex-col-center">
|
||||
<svg
|
||||
t="1729656215869"
|
||||
@ -33,274 +42,401 @@
|
||||
></path>
|
||||
</svg>
|
||||
</view>
|
||||
</view>
|
||||
</CustomUpload>
|
||||
<!-- <text class="verify-title">身份验证</text> -->
|
||||
</view>
|
||||
<text class="avatar-upload-note">上传学生人像用于校园进出</text>
|
||||
</view>
|
||||
|
||||
<!-- 输入框 -->
|
||||
<view class="input-group">
|
||||
<view class="input-item">
|
||||
<text class="label"><text class="required">*</text>姓名:</text>
|
||||
<input
|
||||
class="input-field"
|
||||
type="text"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<text class="label"><text class="required">*</text>手机号码:</text>
|
||||
<input
|
||||
class="input-field"
|
||||
type="number"
|
||||
v-model="formData.phone"
|
||||
placeholder="请输入手机号码"
|
||||
maxlength="11"
|
||||
/>
|
||||
</view>
|
||||
<view class="input-item verification-code-item">
|
||||
<text class="label"><text class="required">*</text>验证码:</text>
|
||||
<input
|
||||
class="input-field verification-code-input"
|
||||
type="number"
|
||||
v-model="formData.code"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
/>
|
||||
<button
|
||||
class="get-code-btn"
|
||||
:disabled="isCountingDown"
|
||||
@click="handleGetCode"
|
||||
<view class="student-info-form">
|
||||
<u--form label-width="auto">
|
||||
<u-form-item
|
||||
label="姓名"
|
||||
:prop="`students[${index}].xcxm`"
|
||||
required
|
||||
borderBottom
|
||||
>
|
||||
{{ countdownText }}
|
||||
</button>
|
||||
<u--input
|
||||
v-model="student.xcxm"
|
||||
placeholder="请输入子女姓名"
|
||||
border="none"
|
||||
inputAlign="right"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="身份证号"
|
||||
:prop="`students[${index}].xssfzh`"
|
||||
required
|
||||
borderBottom
|
||||
>
|
||||
<u--input
|
||||
v-model="student.xssfzh"
|
||||
placeholder="请输入子女身份证号"
|
||||
border="none"
|
||||
inputAlign="right"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
</view>
|
||||
</view>
|
||||
<view class="add-child-btn mb-15" @click="addMoreChildren">
|
||||
<u-icon name="plus" color="#416AF2" size="20"></u-icon>
|
||||
<text class="add-child-btn-text">新增多孩</text>
|
||||
</view>
|
||||
|
||||
<!-- 验证按钮 -->
|
||||
<button class="verify-btn" @click="handleVerify">验证</button>
|
||||
<BasicForm @register="register"></BasicForm>
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view class="white-bg-color py-5">
|
||||
<view class="flex-row items-center pb-10 pt-5">
|
||||
<u-button text="提交" class="mx-15" type="primary" @click="submit" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed } from "vue";
|
||||
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
||||
import { onUnmounted } from "vue";
|
||||
import { hideLoading, showLoading } from "@/utils/uniapp";
|
||||
import { hideLoading, showLoading, showToast } from "@/utils/uniapp";
|
||||
import { ref } from "vue";
|
||||
import { attachmentUpload } from "@/api/system/upload";
|
||||
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
||||
|
||||
const formData = reactive({
|
||||
name: "",
|
||||
phone: "",
|
||||
code: "",
|
||||
avatar_url: "",
|
||||
import { useForm } from "@/components/BasicForm/hooks/useForm";
|
||||
import { dicApi } from "@/api/system/dic";
|
||||
import { loginRegisterJzApi } from "@/api/base/server";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
|
||||
const [register, { getValue }] = useForm({
|
||||
formsProps: { labelWidth: 100 },
|
||||
schema: [
|
||||
{ title: "监督人信息" },
|
||||
{
|
||||
field: "jzxsgxId",
|
||||
label: "与学生关系",
|
||||
component: "BasicPicker",
|
||||
componentProps: {
|
||||
api: dicApi,
|
||||
param: { pid: 1622287061 },
|
||||
rangeKey: "dictionaryValue",
|
||||
savaKey: "dictionaryCode",
|
||||
},
|
||||
},
|
||||
{
|
||||
field: "jzxm",
|
||||
label: "家长姓名",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "jzsj",
|
||||
label: "家长手机号",
|
||||
component: "BasicInput",
|
||||
required: true,
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "gzdw",
|
||||
label: "家长工作单位",
|
||||
component: "BasicInput",
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "zw",
|
||||
label: "职务",
|
||||
component: "BasicInput",
|
||||
componentProps: {},
|
||||
},
|
||||
{
|
||||
field: "jtzz",
|
||||
label: "家庭地址",
|
||||
component: "BasicInput",
|
||||
componentProps: {},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const countdown = ref(60);
|
||||
const isCountingDown = ref(false);
|
||||
let timer: NodeJS.Timeout | null = null;
|
||||
const countdownText = computed(() => {
|
||||
return isCountingDown.value ? `${countdown.value}s后重试` : "获取验证码";
|
||||
});
|
||||
const students = ref([
|
||||
{
|
||||
xcxm: "",
|
||||
xssfzh: "",
|
||||
xstx: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const handleGetCode = () => {
|
||||
if (isCountingDown.value) {
|
||||
async function afterRead(event: any, index: number) {
|
||||
if (!event.tempFilePaths || event.tempFilePaths.length === 0) {
|
||||
showToast({ title: "图片选择失败", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!formData.phone) {
|
||||
uni.showToast({ title: "请输入手机号码", icon: "none" });
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("获取验证码,手机号:", formData.phone);
|
||||
|
||||
isCountingDown.value = true;
|
||||
countdown.value = 60; // 重置倒计时
|
||||
timer = setInterval(() => {
|
||||
if (countdown.value > 1) {
|
||||
countdown.value--;
|
||||
} else {
|
||||
if (timer) clearInterval(timer);
|
||||
timer = null;
|
||||
isCountingDown.value = false;
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const handleVerify = () => {
|
||||
if (
|
||||
!formData.name ||
|
||||
!formData.phone ||
|
||||
!formData.code ||
|
||||
!formData.avatar_url
|
||||
) {
|
||||
uni.showToast({ title: "请填写完整的验证信息", icon: "none" });
|
||||
return;
|
||||
}
|
||||
console.log("提交验证信息:", formData);
|
||||
uni.showToast({ title: "验证成功 (模拟)", icon: "success" });
|
||||
};
|
||||
|
||||
async function afterRead(event: any) {
|
||||
const tempFilePath = event.tempFilePaths[0];
|
||||
showLoading({ title: "上传中" });
|
||||
const { result } = await attachmentUpload(event.tempFilePaths[0]);
|
||||
try {
|
||||
const { result } = await attachmentUpload(tempFilePath);
|
||||
if (result && result.length > 0 && result[0].filePath) {
|
||||
students.value[index].xstx = result[0].filePath;
|
||||
console.log(`Student ${index} avatar uploaded:`, result[0].filePath);
|
||||
showToast({ title: "上传成功" });
|
||||
} else {
|
||||
showToast({ title: "上传失败,请重试", icon: "none" });
|
||||
console.error("Upload result format error:", result);
|
||||
}
|
||||
} catch (error) {
|
||||
showToast({ title: "上传出错", icon: "none" });
|
||||
console.error("Upload error:", error);
|
||||
} finally {
|
||||
hideLoading();
|
||||
formData.avatar_url = result[0].filePath;
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
function handleAvatarClose(index: number) {
|
||||
students.value[index].xstx = "";
|
||||
}
|
||||
|
||||
function addMoreChildren() {
|
||||
students.value.push({
|
||||
xcxm: "",
|
||||
xssfzh: "",
|
||||
xstx: "",
|
||||
});
|
||||
}
|
||||
|
||||
function removeStudent(index: number) {
|
||||
if (students.value.length > 1) {
|
||||
students.value.splice(index, 1);
|
||||
} else {
|
||||
showToast({ title: "至少需要一个子女信息", icon: "none" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toHome() {
|
||||
if (getGlobal.type == 1) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/notice",
|
||||
});
|
||||
} else if (getGlobal.type == 2) {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/club-selection",
|
||||
});
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/home/index",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const { getGlobal } = useDataStore();
|
||||
const { afterLoginAction } = useUserStore();
|
||||
async function submit() {
|
||||
for (const student of students.value) {
|
||||
if (!student.xstx) {
|
||||
showToast({ title: "请上传子女照片", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!student.xcxm) {
|
||||
showToast({ title: "请输入子女姓名", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!student.xssfzh) {
|
||||
showToast({ title: "请输入子女身份证号", icon: "none" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
const formData = await getValue();
|
||||
showLoading({ title: "提交中" });
|
||||
try {
|
||||
const res = await loginRegisterJzApi({
|
||||
xsList: students.value,
|
||||
...formData,
|
||||
openId: getGlobal.openId,
|
||||
appCode: "JZ",
|
||||
});
|
||||
hideLoading();
|
||||
if (res.resultCode == 1) {
|
||||
afterLoginAction(res.result);
|
||||
toHome();
|
||||
} else {
|
||||
showToast({ title: res.message || "提交失败", icon: "none" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.register-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
// height: 100vh; // 使用 min-height 避免内容过长时截断
|
||||
min-height: 100vh;
|
||||
background: url("@/static/base/bg.jpg") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
<style lang="scss" scoped>
|
||||
.page-container {
|
||||
padding: 15px; /* Consistent padding */
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 250px; // 根据实际 logo 尺寸调整
|
||||
height: 60px; // 根据实际 logo 尺寸调整
|
||||
margin-top: 40px; // 与顶部的距离
|
||||
margin-bottom: 30px;
|
||||
.notice-box {
|
||||
background-color: #fff1f0; /* Slightly lighter red */
|
||||
padding: 12px 18px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
.notice-text {
|
||||
color: #fa541c; /* Adjusted red color */
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
background-color: #ffffff;
|
||||
border-radius: 15px;
|
||||
padding: 30px 25px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: 400px; // 限制最大宽度
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
border-radius: 10px;
|
||||
padding: 20px 20px 0 20px;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||||
/* Added margin-bottom directly here for spacing between sections */
|
||||
margin-bottom: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.avatar-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 25px;
|
||||
margin-bottom: 25px; /* Increased margin */
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 10px;
|
||||
background-color: #f0f0f0; // 头像占位背景色
|
||||
/* Keep avatar uploader styles relevant to CustomUpload */
|
||||
/* Replace with rectangular styles */
|
||||
.avatar-uploader-container-rect {
|
||||
/* Assuming uni.rpx units based on class names like wi-180, he-240 */
|
||||
width: 180rpx;
|
||||
height: 240rpx;
|
||||
margin: 0 auto 10px auto; /* mx-auto mb-10 */
|
||||
border-radius: 6px; /* r-md approximation */
|
||||
border: 1px solid #cccccc;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.verify-title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Remove old circular styles */
|
||||
/* .avatar-uploader-container { ... } */
|
||||
|
||||
.input-group {
|
||||
.avatar-placeholder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.input-item {
|
||||
/* Keep inner placeholder for centering SVG */
|
||||
.avatar-placeholder-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee; // 输入框底部线条
|
||||
padding-bottom: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 80px; // 固定标签宽度
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
flex-shrink: 0; // 防止标签被压缩
|
||||
display: flex; // 使星号和文字对齐
|
||||
align-items: center;
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 4px;
|
||||
/* Remove old hint style */
|
||||
/* .avatar-upload-hint { ... } */
|
||||
|
||||
.avatar-upload-note {
|
||||
color: #999;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
flex-grow: 1;
|
||||
font-size: 14px;
|
||||
border: none; // 移除默认边框
|
||||
outline: none; // 移除选中时的轮廓
|
||||
padding: 5px 0; // 微调输入框内边距
|
||||
color: #333;
|
||||
.student-info-form {
|
||||
margin-bottom: 20px; /* Restore original margin */
|
||||
}
|
||||
|
||||
.verification-code-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between; // 让输入框和按钮分开
|
||||
.form-title {
|
||||
display: block;
|
||||
font-size: 16px; /* Slightly larger title */
|
||||
font-weight: 600; /* Bolder */
|
||||
margin-bottom: 15px; /* Space below title */
|
||||
}
|
||||
|
||||
.verification-code-input {
|
||||
flex-grow: 1; // 输入框占据剩余空间
|
||||
margin-right: 10px; // 与按钮的间距
|
||||
/* Restore remove button style if needed, or adapt */
|
||||
/* Updated remove button style */
|
||||
.remove-btn {
|
||||
position: absolute;
|
||||
top: 10px; /* Closer to top edge */
|
||||
right: 10px; /* Closer to right edge */
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
/* Optional: add padding for easier clicking */
|
||||
// padding: 5px;
|
||||
}
|
||||
|
||||
.get-code-btn {
|
||||
.add-child-btn {
|
||||
background-color: #ffffff;
|
||||
color: #007aff; // 按钮文字颜色
|
||||
border: 1px solid #007aff; // 按钮边框
|
||||
font-size: 12px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 20px;
|
||||
white-space: nowrap; // 防止文字换行
|
||||
line-height: 1; // 确保文字垂直居中
|
||||
height: auto; // 自适应高度
|
||||
margin: 0; // 移除默认外边距
|
||||
flex-shrink: 0; // 防止按钮被压缩
|
||||
border-radius: 10px;
|
||||
padding: 15px; /* Increased padding */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10px; /* Increased margin */
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.get-code-btn[disabled] {
|
||||
background-color: #f8f8f8;
|
||||
color: #cccccc;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
// 移除按钮默认的边框伪元素
|
||||
.get-code-btn::after {
|
||||
border: none;
|
||||
.add-child-btn-text {
|
||||
color: #416af2;
|
||||
margin-left: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.verify-btn {
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
background: linear-gradient(to right, #ff8c4a, #ff5e62); // 按钮渐变色
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
border-radius: 25px;
|
||||
margin-top: 10px;
|
||||
border: none; // 移除默认边框
|
||||
box-shadow: 0 2px 5px rgba(255, 100, 100, 0.3); // 添加阴影
|
||||
}
|
||||
// 移除按钮默认的边框伪元素
|
||||
.verify-btn::after {
|
||||
border: none;
|
||||
/* Adjust uview form item styles */
|
||||
::v-deep .u-form-item {
|
||||
margin-bottom: 0; /* Remove default margin if any */
|
||||
}
|
||||
|
||||
// 可以在这里添加 placeholder 的样式
|
||||
input::placeholder {
|
||||
color: #cccccc;
|
||||
font-size: 14px;
|
||||
::v-deep .u-form-item__body {
|
||||
padding: 15px 0 !important; /* Adjusted padding */
|
||||
/* Align items vertically if label wraps */
|
||||
// align-items: flex-start;
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body__left {
|
||||
/* Allow label to take necessary width, adjust as needed */
|
||||
// flex: 0 0 80px;
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body__left__text {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
line-height: 1.5; /* Improve line spacing if label wraps */
|
||||
/* Ensure required asterisk is red and BEFORE the text */
|
||||
display: flex; /* Use flex to control order */
|
||||
align-items: center; /* Vertically center asterisk and text */
|
||||
|
||||
span {
|
||||
color: #f56c6c;
|
||||
/* Order asterisk first */
|
||||
order: -1;
|
||||
margin-right: 4px;
|
||||
/* Adjust vertical alignment if needed */
|
||||
// line-height: 1;
|
||||
// display: inline-block;
|
||||
// vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-input {
|
||||
text-align: right; /* Align input text to the right */
|
||||
}
|
||||
|
||||
::v-deep .u-border-bottom {
|
||||
/* Ensure border spans full width if needed, or adjust */
|
||||
// left: 0 !important;
|
||||
// right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,23 +1,44 @@
|
||||
import {defineStore} from "pinia";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
export const useDataStore = defineStore({
|
||||
id: 'data',
|
||||
id: "data",
|
||||
state: () => ({
|
||||
data: {}
|
||||
data: {},
|
||||
kcData: {},
|
||||
global: {},
|
||||
file: {},
|
||||
}),
|
||||
getters: {
|
||||
getData(): any {
|
||||
return this.data
|
||||
}
|
||||
return this.data;
|
||||
},
|
||||
getGlobal(): any {
|
||||
return this.global;
|
||||
},
|
||||
getFile(): any {
|
||||
return this.file;
|
||||
},
|
||||
getKcData(): any {
|
||||
return this.kcData;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setData(data: any) {
|
||||
this.data = data
|
||||
}
|
||||
this.data = data;
|
||||
},
|
||||
setGlobal(data: any) {
|
||||
this.global = data;
|
||||
},
|
||||
setFile(data: any) {
|
||||
this.file = data;
|
||||
},
|
||||
setKcData(data: any) {
|
||||
this.kcData = data;
|
||||
},
|
||||
},
|
||||
persist: {
|
||||
enabled: true,
|
||||
detached: true,
|
||||
H5Storage: localStorage
|
||||
H5Storage: localStorage,
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
@ -80,7 +80,7 @@ export const useUserStore = defineStore({
|
||||
if (value[AUTH_KEY]) {
|
||||
this.setToken(value[AUTH_KEY])
|
||||
}
|
||||
authenticationApi({userId: value.userid}).then(({result}) => {
|
||||
authenticationApi({userId: value.userId}).then(({result}) => {
|
||||
if (result) {
|
||||
this.setAuth(result)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user