| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- <template>
- <view class="page-apply">
- <view class="header">
- <text class="header-title">申请人工方案</text>
- </view>
- <view class="form-container">
- <view class="form-group">
- <text class="form-label">需求类型</text>
- <radio-group class="radio-group" @change="onDemandTypeChange">
- <label class="radio-item" v-for="type in demandTypes" :key="type">
- <radio :value="type"></radio>
- <text>{{ type }}</text>
- </label>
- </radio-group>
- </view>
- <view class="form-group">
- <text class="form-label">具体需求描述</text>
- <textarea
- class="textarea"
- placeholder="请详细描述您的需求,我们将根据此信息匹配合适的能量师"
- maxlength="300"
- v-model="form.description"
- @input="onInput"
- ></textarea>
- <view class="counter">
- {{ form.description.length }}/300
- </view>
- </view>
- <view class="form-group">
- <text class="form-label">期望价格范围</text>
- <picker
- class="picker"
- mode="selector"
- :range="priceRanges"
- @change="onPriceChange"
- >
- <view class="picker-value">
- {{ priceRanges[form.priceIndex] }}
- </view>
- </picker>
- </view>
- </view>
- <button
- class="submit-btn"
- @click="onSubmit"
- :disabled="loading"
- >
- {{ loading ? '提交中...' : '提交申请' }}
- </button>
- </view>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { planApi } from '@/utils/api'
- import { useUserStore } from '@/stores/user'
- const form = ref({
- demandType: '',
- description: '',
- priceIndex: 0
- })
- const demandTypes = ['学业方向', '职业规划', '亲子关系', '其他']
- const priceRanges = ['¥50-99', '¥100-299', '¥300-499', '¥500-999', '面议']
- const loading = ref(false)
- const chartRecordId = ref('')
- // Get chartRecordId from query parameters on page load
- const onLoad = (query) => {
- if (query && query.chartRecordId) {
- chartRecordId.value = query.chartRecordId
- }
- }
- const onInput = (e) => {
- // Ensure we don't exceed 300 characters (though maxlength should handle it)
- if (form.value.description.length > 300) {
- form.value.description = form.value.description.slice(0, 300)
- }
- }
- const onDemandTypeChange = (e) => {
- form.value.demandType = e.detail.value
- }
- const onPriceChange = (e) => {
- form.value.priceIndex = parseInt(e.detail.value, 10)
- }
- const onSubmit = async () => {
- // Validate form
- if (!form.value.demandType) {
- uni.showToast({ title: '请选择需求类型', icon: 'none' })
- return
- }
- if (!form.value.description.trim()) {
- uni.showToast({ title: '请填写具体需求描述', icon: 'none' })
- return
- }
- loading.value = true
- try {
- const res = await planApi.apply({
- chartRecordId: chartRecordId.value,
- demandType: form.value.demandType,
- description: form.value.description.trim(),
- priceRange: priceRanges[form.value.priceIndex]
- })
- // Backend returns { planRequest, assigned, message }
- // If no practitioner assigned, show the guidance message
- if (res && !res.assigned) {
- uni.showModal({
- title: '提交成功',
- content: res.message || '暂未开放系统分配,请通过推荐链接找到专属能量师',
- showCancel: false,
- confirmText: '知道了'
- })
- } else {
- uni.showToast({ title: '提交成功', icon: 'success' })
- }
- // Navigate back after a short delay to let the toast/modal show
- setTimeout(() => {
- uni.navigateBack()
- }, res && !res.assigned ? 3000 : 1500)
- } catch (e) {
- // Error handling: show toast with error message from API
- uni.showToast({
- title: e.message || '提交失败,请重试',
- icon: 'none'
- })
- } finally {
- loading.value = false
- }
- }
- </script>
- <style scoped lang="scss">
- @import "@/styles/theme.scss";
- .page-apply {
- padding: 20px;
- min-height: 100vh;
- background: linear-gradient(180deg, #0c0a1a 0%, #1a1232 100%);
- }
- .header {
- text-align: center;
- margin-bottom: 24px;
- }
- .header-title {
- font-size: 22px;
- font-weight: 700;
- color: rgba(255,255,255,0.9);
- display: block;
- }
- .form-container {
- background: rgba(255,255,255,0.02);
- border-radius: 16px;
- padding: 24px;
- margin-bottom: 24px;
- }
- .form-group {
- margin-bottom: 20px;
- }
- .form-label {
- display: block;
- font-size: 14px;
- color: rgba(255,255,255,0.6);
- margin-bottom: 8px;
- font-weight: 500;
- }
- .radio-group {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
- }
- .radio-item {
- display: flex;
- align-items: center;
- cursor: pointer;
- font-size: 14px;
- color: rgba(255,255,255,0.8);
- }
- .radio-item text {
- margin-left: 6px;
- }
- .textarea {
- width: 100%;
- min-height: 80px;
- padding: 12px;
- border: 1px solid rgba(255,255,255,0.1);
- border-radius: 8px;
- background: rgba(255,255,255,0.03);
- color: #fff;
- font-size: 14px;
- resize: none;
- }
- .textarea:focus {
- outline: none;
- border-color: rgba(255,255,255,0.2);
- }
- .counter {
- margin-top: 8px;
- text-align: right;
- font-size: 12px;
- color: rgba(255,255,255,0.4);
- }
- .picker {
- width: 100%;
- padding: 12px;
- border: 1px solid rgba(255,255,255,0.1);
- border-radius: 8px;
- background: rgba(255,255,255,0.03);
- color: #fff;
- font-size: 14px;
- }
- .picker-value {
- display: block;
- text-align: center;
- }
- .submit-btn {
- width: 100%;
- padding: 16px;
- background: linear-gradient(135deg, #f59e0b, #d97706);
- color: #fff;
- border: none;
- border-radius: 14px;
- font-size: 17px;
- font-weight: 600;
- letter-spacing: 2px;
- }
- .submit-btn[disabled] {
- opacity: 0.4;
- }
- </style>
|