fillTask.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. <template>
  2. <view class="container">
  3. <Watermark />
  4. <Step :step="currentStep" :stepsData="currentText" />
  5. <scroll-view class="content" scroll-y>
  6. <!-- 驳回意见提示 -->
  7. <view class="rejection-banner" v-if="rejectionInfo">
  8. <view class="rejection-icon">✕</view>
  9. <view class="rejection-text">驳回意见: {{ rejectionInfo }}</view>
  10. </view>
  11. <!-- 基本信息 -->
  12. <view class="form-section">
  13. <view class="form-item">
  14. <view class="form-label">
  15. <text class="required">*</text>
  16. <text>任务归属</text>
  17. </view>
  18. <view class="form-input picker-input" :class="{ placeholder: !formData.deptId }"
  19. @click="showPicker('任务归属',companyData)">
  20. {{ institutionDisplayText || '请选择任务归属' }}
  21. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  22. </view>
  23. </view>
  24. <view class="form-item">
  25. <view class="form-label">
  26. <text class="required">*</text>
  27. <text>归属项目</text>
  28. </view>
  29. <view class="form-input picker-input" :class="{ placeholder: !formData.projectId }"
  30. @click="showPicker('归属项目',companyList)">
  31. {{ belongingProjectDisplayText || '请选择归属项目' }}
  32. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  33. </view>
  34. </view>
  35. <view class="form-item">
  36. <view class="form-label">
  37. <text class="required">*</text>
  38. <text>产品代码</text>
  39. </view>
  40. <view class="form-input picker-input" :class="{ placeholder: !formData.productId }"
  41. @click="showPicker('产品代码',productList)">
  42. {{ productNameDisplayText || '请选择产品代码' }}
  43. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  44. </view>
  45. </view>
  46. <view class="form-item">
  47. <view class="form-label">
  48. <text class="required">*</text>
  49. <text>费用分摊</text>
  50. </view>
  51. <view class="form-input picker-input" :class="{ placeholder: !formData.costShareId }"
  52. @click="showPicker('费用分摊',companyData)">
  53. {{ costAllocationDisplayText || '请选择费用分摊主体' }}
  54. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  55. </view>
  56. </view>
  57. <view class="form-item">
  58. <view class="form-label">
  59. <text>添加任务备注</text>
  60. </view>
  61. <EvanSwitch v-model="formData.addRemark"></EvanSwitch>
  62. </view>
  63. <view class="form-item" v-if="formData.addRemark">
  64. <textarea class="form-textarea" v-model="formData.remark" placeholder="请输入任务备注" rows="4"></textarea>
  65. </view>
  66. <view class="form-item">
  67. <view class="form-label">
  68. <text class="required">*</text>
  69. <text>归属类型</text>
  70. </view>
  71. <view class="form-input picker-input" :class="{ placeholder: !formData.belongType }"
  72. @click="showPicker('归属类型',dictTypeColumns)">
  73. {{ belongTypeDisplayText || '请选择归属类型' }}
  74. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  75. </view>
  76. </view>
  77. <view class="form-item">
  78. <view class="form-label">
  79. <text class="required">*</text>
  80. <text>任务类型</text>
  81. </view>
  82. <view class="form-input picker-input" :class="{ placeholder: !formData.taskType }"
  83. @click="showPicker('任务类型',taskTypeColumns)">
  84. {{ taskTypeDisplayText || '请选择任务类型' }}
  85. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  86. </view>
  87. </view>
  88. <view class="form-item">
  89. <view class="form-label">
  90. <text class="required">*</text>
  91. <text>计划开始时间</text>
  92. </view>
  93. <view class="form-input picker-input" :class="{ placeholder: !formData.planStartTime }"
  94. @click="showStartTimePicker = true">
  95. {{ formData.planStartTime || '请选择计划开始时间' }}
  96. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  97. </view>
  98. </view>
  99. <view class="form-item">
  100. <view class="form-label">
  101. <text class="required">*</text>
  102. <text>计划结束时间</text>
  103. </view>
  104. <view class="form-input picker-input" :class="{ placeholder: !formData.planEndTime }"
  105. @click="showEndTimePicker = true">
  106. {{ formData.planEndTime || '请选择计划结束时间' }}
  107. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_more.png"></image>
  108. </view>
  109. </view>
  110. <!-- 观看方式 -->
  111. <!-- <view class="form-item">
  112. <view class="form-label">
  113. <text class="required">*</text>
  114. <text>观看方式</text>
  115. </view>
  116. <view class="radio-group">
  117. <label class="radio-item" :class="{ active: formData.viewMode === '公开' }"
  118. @click="formData.viewMode = '公开'">
  119. <image class="radio-circle" v-if="formData.viewMode === '公开'"
  120. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle_sel.png"></image>
  121. <image class="radio-circle" v-else src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle.png"></image>
  122. <text>公开</text>
  123. </label>
  124. <label class="radio-item" :class="{ active: formData.viewMode === '加密' }"
  125. @click="formData.viewMode = '加密'">
  126. <image class="radio-circle" v-if="formData.viewMode === '加密'"
  127. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle_sel.png"></image>
  128. <image class="radio-circle" v-else src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle.png"></image>
  129. <text>加密</text>
  130. </label>
  131. </view>
  132. </view> -->
  133. <!-- 观看要求 -->
  134. <!-- <view class="form-item">
  135. <view class="form-label">
  136. <text class="required">*</text>
  137. <text>观看要求</text>
  138. </view>
  139. <view class="radio-group">
  140. <label class="radio-item" :class="{ active: formData.viewRequire === '登录账户' }"
  141. @click="formData.viewRequire = '登录账户'">
  142. <image class="radio-circle" v-if="formData.viewRequire === '登录账户'"
  143. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle_sel.png"></image>
  144. <image class="radio-circle" v-else src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle.png"></image>
  145. <text>登录账户</text>
  146. </label>
  147. <label class="radio-item" :class="{ active: formData.viewRequire === '认证客户' }"
  148. @click="formData.viewRequire = '认证客户'">
  149. <image class="radio-circle" v-if="formData.viewRequire === '认证客户'"
  150. src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle_sel.png"></image>
  151. <image class="radio-circle" v-else src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_circle.png"></image>
  152. <text>认证客户</text>
  153. </label>
  154. </view>
  155. </view> -->
  156. </view>
  157. <!-- <view class="form-section">
  158. <view class="form-item">
  159. <view class="form-label">
  160. <text class="required">*</text>
  161. <text>直播间标题</text>
  162. </view>
  163. <view class="form-input">
  164. <input v-model="formData.roomTitle" placeholder="请输入直播间标题" />
  165. </view>
  166. </view>
  167. <view class="form-item column baseline">
  168. <view class="form-label">
  169. <text class="required">*</text>
  170. <text>封面图</text>
  171. </view>
  172. <view class="upload-area" @click="chooseCoverImage">
  173. <image v-if="formData.coverImage" :src="formData.coverImage" class="cover-image" />
  174. <view v-else class="upload-placeholder">
  175. <text>点击上传封面图</text>
  176. </view>
  177. <image v-if="formData.coverImage" class="delete-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_cross.png"
  178. @click.stop="deleteCoverImage" />
  179. </view>
  180. </view>
  181. </view> -->
  182. <!-- 申请补充讲者任务 -->
  183. <!-- <view class="form-section">
  184. <view class="form-item">
  185. <view class="form-label">
  186. <text class="required">*</text>
  187. <text>申请补充讲者任务</text>
  188. </view>
  189. <EvanSwitch v-model="formData.applySpeaker"></EvanSwitch>
  190. </view>
  191. </view> -->
  192. </scroll-view>
  193. <view class="next-button" @click="toNext">下一步</view>
  194. <u-picker :title='pickerTitle' :show="showPickerVisible" confirmColor='#576B95' ref="uPicker"
  195. :columns="pickerData" @confirm="confirm" @cancel="cancel">
  196. </u-picker>
  197. <u-datetime-picker :show="showStartTimePicker" v-model="startTimeValue" mode="date"
  198. confirmColor='#576B95' @confirm="onStartTimeConfirm" @cancel="showStartTimePicker = false">
  199. </u-datetime-picker>
  200. <u-datetime-picker :show="showEndTimePicker" v-model="endTimeValue" mode="date"
  201. confirmColor='#576B95' @confirm="onEndTimeConfirm" @cancel="showEndTimePicker = false">
  202. </u-datetime-picker>
  203. <u-popup :show="showBelongingPopup" mode="bottom" round="20" @close="closePopup" closeable>
  204. <view class="popup-content p32">
  205. <view class="popup-header">
  206. <text class="title">归属项目</text>
  207. </view>
  208. <view class="search-box">
  209. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/search.png"></image>
  210. <u-input v-model="searchKeyword" placeholder="请输入归属项目" border="none" clearable />
  211. </view>
  212. <scroll-view scroll-y class="project-list">
  213. <view v-for="(project, index) in filteredProjects" :key="index" class="project-item"
  214. :class="{ active: selectedIndex === index }" @tap="selectProject(project, index)">
  215. <text class="project-name">{{ project.name }}</text>
  216. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_right.png"></image>
  217. </view>
  218. </scroll-view>
  219. </view>
  220. </u-popup>
  221. <u-popup :show="showTaskPopup" mode="bottom" round="16" @close="showTaskPopup = false" safeAreaInsetBottom>
  222. <view class="popup-content">
  223. <view class="popup-header">
  224. <text class="popup-title">任务归属</text>
  225. <image class="close-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_cross.png" @click="showTaskPopup=false"></image>
  226. </view>
  227. <view class="two-level-container">
  228. <scroll-view class="primary-list" scroll-y>
  229. <view v-for="(item, index) in primaryOptions" :key="index" class="primary-item"
  230. :class="{ 'primary-active': activePrimaryIndex === index }"
  231. @click="handlePrimarySelect(index)">
  232. <text class="primary-text">{{ item.name }}</text>
  233. </view>
  234. </scroll-view>
  235. <scroll-view class="secondary-list" scroll-y>
  236. <view v-for="(subItem, subIndex) in currentSecondaryOptions" :key="subIndex"
  237. class="secondary-item" :class="{ 'secondary-active': selectedSecondaryItem === subItem }"
  238. @click="handleSecondarySelect(subItem)">
  239. <text class="secondary-text">{{ subItem }}</text>
  240. <u-icon v-if="selectedSecondaryItem === subItem" name="checkbox-mark" color="#2979ff"
  241. size="20" />
  242. </view>
  243. </scroll-view>
  244. </view>
  245. <view class="popup-footer">
  246. <button class="confirm-btn" @click="handleConfirm">确定</button>
  247. </view>
  248. </view>
  249. </u-popup>
  250. <!-- 通用选择器 -->
  251. <u-picker :title='pickerTitle' :show="showPickerVisible" confirmColor='#576B95' ref="uPicker"
  252. :columns="pickerData" @confirm="confirm" @cancel="cancel">
  253. </u-picker>
  254. <!-- 归属项目弹窗 -->
  255. <u-popup :show="showBelongingPopup" mode="bottom" round="20" @close="closePopup" closeable>
  256. <view class="popup-content p32">
  257. <view class="popup-header">
  258. <text class="title">归属项目</text>
  259. </view>
  260. <view class="search-box">
  261. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/search.png"></image>
  262. <u-input v-model="searchKeyword" placeholder="请输入归属项目" border="none" clearable />
  263. </view>
  264. <scroll-view scroll-y class="project-list">
  265. <view v-for="(project, index) in filteredProjects" :key="index" class="project-item"
  266. :class="{ active: selectedIndex === index }" @tap="selectProject(project, index)">
  267. <text class="project-name">{{ project.name }}</text>
  268. <image class="icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_right.png"></image>
  269. </view>
  270. </scroll-view>
  271. </view>
  272. </u-popup>
  273. <!-- 任务归属弹窗 -->
  274. <u-popup :show="showTaskPopup" mode="bottom" round="16" @close="showTaskPopup = false" safeAreaInsetBottom>
  275. <view class="popup-content">
  276. <view class="popup-header">
  277. <text class="popup-title">任务归属</text>
  278. <image class="close-icon" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/image/icon_cross.png" @click="showTaskPopup=false"></image>
  279. </view>
  280. <view class="two-level-container">
  281. <scroll-view class="primary-list" scroll-y>
  282. <view v-for="(item, index) in primaryOptions" :key="index" class="primary-item"
  283. :class="{ 'primary-active': activePrimaryIndex === index }"
  284. @click="handlePrimarySelect(index)">
  285. <text class="primary-text">{{ item.name }}</text>
  286. </view>
  287. </scroll-view>
  288. <scroll-view class="secondary-list" scroll-y>
  289. <view v-for="(subItem, subIndex) in currentSecondaryOptions" :key="subIndex"
  290. class="secondary-item" :class="{ 'secondary-active': selectedSecondaryItem === subItem }"
  291. @click="handleSecondarySelect(subItem)">
  292. <text class="secondary-text">{{ subItem }}</text>
  293. <u-icon v-if="selectedSecondaryItem === subItem" name="checkbox-mark" color="#2979ff"
  294. size="20" />
  295. </view>
  296. </scroll-view>
  297. </view>
  298. <view class="popup-footer">
  299. <button class="confirm-btn" @click="handleConfirm">确定</button>
  300. </view>
  301. </view>
  302. </u-popup>
  303. </view>
  304. </template>
  305. <script>
  306. import { info, queryAllData, queryAllProduct, getAllData, company } from '@/api/task'
  307. import Step from '@/pages_task/components/step.vue'
  308. import EvanSwitch from '@/components/evan-switch.vue'
  309. import utils from '@/utils/common.js'
  310. export default {
  311. components: {
  312. Step,
  313. EvanSwitch
  314. },
  315. data() {
  316. return {
  317. showTaskPopup: false,
  318. primaryOptions: [],
  319. activePrimaryIndex: 0,
  320. currentSecondaryOptions: [],
  321. selectedSecondaryItem: '',
  322. selectedPrimaryItem: null,
  323. selectedIndex: -1,
  324. selectedProject: null,
  325. belongingprojects: [],
  326. searchKeyword: '',
  327. showBelongingPopup: false,
  328. showPickerVisible: false,
  329. currentStep: 1,
  330. currentText: [{
  331. id: 1,
  332. stepNumber: 1,
  333. title: '填写任务'
  334. },
  335. {
  336. id: 2,
  337. stepNumber: 2,
  338. title: '积分设置'
  339. }
  340. ],
  341. rejectionInfo: '',
  342. // 核心修复:所有表单字段统一放在formData里
  343. formData: {
  344. id:'',
  345. costShareId: '',
  346. planStartTime: '',
  347. planEndTime: '',
  348. deptId: '',
  349. projectId: '',
  350. productId: '',
  351. taskType: '',
  352. belongType: '',
  353. addRemark: false,
  354. remark: '',
  355. viewMode: '公开', // 观看方式默认值
  356. viewRequire: '登录账户', // 观看要求默认值
  357. roomTitle: '', // 直播间标题
  358. coverImage: '', // 封面图
  359. applySpeaker: true // 申请补充讲者任务
  360. },
  361. pickerTitle: '默认标题',
  362. pickerData: [],
  363. companyId:'',
  364. showStartTimePicker: false,
  365. showEndTimePicker: false,
  366. startTimeValue: new Date(),
  367. endTimeValue: new Date(),
  368. originalCompanyData: null,
  369. companyData: [],
  370. companyList: [],
  371. productList: [],
  372. taskTypeOriginalData: [],
  373. taskTypeDict: [],
  374. belongTypeList: [],
  375. projectData: [],
  376. userInfo: {},
  377. // 页面显示数据
  378. deptName: '',
  379. costShareName: '',
  380. productName: '',
  381. projectName: '',
  382. id:'',
  383. doctorId:''
  384. }
  385. },
  386. onLoad: async function(options) {
  387. console.log("编辑任务接受数据",options);
  388. try {
  389. this.taskTypeDict = await utils.getDicts("task_type");//任务类型
  390. this.belongTypeList = await utils.getDicts("task_belong_type");//任务类型
  391. } catch (e) {
  392. console.log('获取字典数据失败:', e)
  393. }
  394. if(options.id){
  395. console.log('有id',options.id);
  396. this.id=options.id
  397. this.formData.id=options.id
  398. }
  399. if(options.doctorId){
  400. this.doctorId=options.doctorId
  401. }
  402. this.userInfo=JSON.parse(uni.getStorageSync("userInfo"))||''
  403. if (options.rejectionInfo) {
  404. this.rejectionInfo = decodeURIComponent(options.rejectionInfo)
  405. }
  406. // 初始化二级选项
  407. this.currentSecondaryOptions = this.primaryOptions[0]?.children || []
  408. // 获取用户信息
  409. const userInfoStr = uni.getStorageSync('userInfo')
  410. this.userInfo = userInfoStr ? JSON.parse(userInfoStr) : {}
  411. console.log(this.userInfo);
  412. // 加载信息
  413. this.companyId = this.userInfo.companyId || 1
  414. // 设置默认日期为当天
  415. this.formData.planStartTime = this.formatDateTime(new Date());
  416. this.formData.planEndTime = this.formatDateTime(new Date());
  417. this.info();
  418. },
  419. computed: {
  420. filteredProjects() {
  421. if (!this.searchKeyword.trim()) {
  422. return this.belongingprojects;
  423. }
  424. return this.belongingprojects.filter(project =>
  425. project.name.includes(this.searchKeyword)
  426. );
  427. },
  428. taskTypeDisplayText() {
  429. console.log('计算taskTypeDisplayText, formData.taskType:', this.formData.taskType);
  430. console.log('计算taskTypeDisplayText, taskTypeOriginalData:', this.taskTypeOriginalData);
  431. if (!this.formData.taskType || !this.taskTypeOriginalData) {
  432. return '';
  433. }
  434. const selectedType = this.taskTypeOriginalData.find(item => item.dictValue === this.formData.taskType);
  435. console.log('找到的selectedType:', selectedType);
  436. return selectedType ? selectedType.dictLabel : '';
  437. },
  438. institutionDisplayText() {
  439. if (!this.formData.deptId || !this.companyData) {
  440. return '';
  441. }
  442. const selectedItem = this.companyData.find(item => item.deptId === this.formData.deptId);
  443. return selectedItem ? selectedItem.deptName : '';
  444. },
  445. costAllocationDisplayText() {
  446. if (!this.formData.costShareId || !this.companyData) {
  447. return '';
  448. }
  449. const selectedItem = this.companyData.find(item => item.deptId === this.formData.costShareId);
  450. return selectedItem ? selectedItem.deptName : '';
  451. },
  452. belongingProjectDisplayText() {
  453. console.log('计算belongingProjectDisplayText:', this.formData.projectId, this.projectData);
  454. if (!this.formData.projectId || !this.projectData) {
  455. console.log('formData.projectId或projectData为空');
  456. return '';
  457. }
  458. const selectedItem = this.projectData.find(item => item.id === this.formData.projectId);
  459. console.log('找到的项目:', selectedItem);
  460. return selectedItem ? selectedItem.projectName : '';
  461. },
  462. productNameDisplayText() {
  463. if (!this.formData.productId || !this.productList) {
  464. return '';
  465. }
  466. const selectedItem = this.productList.find(item => item.id === this.formData.productId);
  467. return selectedItem ? selectedItem.productName : '';
  468. },
  469. belongTypeDisplayText() {
  470. if (!this.formData.belongType || !this.belongTypeList) {
  471. return '';
  472. }
  473. const selectedItem = this.belongTypeList.find(item => item.dictValue === this.formData.belongType);
  474. return selectedItem ? selectedItem.dictLabel : '';
  475. }
  476. },
  477. methods: {
  478. // 任务详情查询
  479. info() {
  480. info(this.id).then(res => {
  481. if (res.code === 200) {
  482. const data = res.data;
  483. // 直接将接口返回的数据赋值给 formData
  484. this.formData = {
  485. // 基本信息
  486. id: this.id || '',
  487. deptId: data.deptId || '',
  488. deptName: data.deptName || '',
  489. projectId: data.projectId || '',
  490. productId: data.productId || '',
  491. costShareId: data.costShareId || '',
  492. belongType: data.belongType || '',
  493. taskType: data.taskType || '',
  494. addRemark: false,
  495. // 时间信息
  496. planStartTime: data.planStartTime || '',
  497. planEndTime: data.planEndTime || '',
  498. // 直播信息
  499. viewMode: '公开', // 观看方式默认值
  500. viewRequire: '登录账户', // 观看要求默认值
  501. roomTitle: '', // 直播间标题
  502. coverImage: '', // 封面图
  503. applySpeaker: true // 申请补充讲者任务
  504. };
  505. // 保存其他需要的数据
  506. this.deptName = data.deptName || '';
  507. this.costShareName = data.costShareName || '';
  508. this.productName = data.productName || '';
  509. this.projectName = data.projectName || '';
  510. } else {
  511. uni.showToast({
  512. title: '查询任务详情失败',
  513. icon: 'none'
  514. });
  515. }
  516. })
  517. },
  518. // 封面图上传
  519. chooseCoverImage() {
  520. uni.chooseImage({
  521. count: 1,
  522. sizeType: ['compressed'],
  523. sourceType: ['album', 'camera'],
  524. success: (res) => {
  525. this.formData.coverImage = res.tempFilePaths[0]
  526. }
  527. })
  528. },
  529. // 删除封面图
  530. deleteCoverImage() {
  531. this.formData.coverImage = ''
  532. },
  533. // 一级分类选择
  534. handlePrimarySelect(index) {
  535. this.activePrimaryIndex = index;
  536. this.currentSecondaryOptions = this.primaryOptions[index].children || [];
  537. this.selectedSecondaryItem = '';
  538. },
  539. // 二级分类选择
  540. handleSecondarySelect(item) {
  541. this.selectedSecondaryItem = item;
  542. this.selectedPrimaryItem = this.primaryOptions[this.activePrimaryIndex];
  543. },
  544. // 任务归属确认
  545. handleConfirm() {
  546. if (this.selectedSecondaryItem) {
  547. const displayText = `${this.selectedPrimaryItem.name} > ${this.selectedSecondaryItem}`;
  548. this.formData.institution = displayText;
  549. this.showTaskPopup = false;
  550. } else {
  551. uni.showToast({
  552. title: '请选择二级部门',
  553. icon: 'none'
  554. });
  555. }
  556. },
  557. // 关闭归属项目弹窗
  558. closePopup() {
  559. this.showBelongingPopup = false;
  560. this.searchKeyword = '';
  561. this.selectedIndex = -1;
  562. },
  563. // 选择归属项目
  564. selectProject(project, index) {
  565. this.selectedIndex = index;
  566. this.selectedProject = project;
  567. this.formData.belongingProject = project.name;
  568. setTimeout(() => {
  569. this.showBelongingPopup = false;
  570. this.searchKeyword = '';
  571. this.selectedIndex = -1;
  572. }, 300);
  573. },
  574. //任务类型
  575. queryAllData(){
  576. return new Promise((resolve, reject) => {
  577. if(!this.formData.productId){
  578. uni.showToast({
  579. title: '请先选择产品',
  580. icon: 'none'
  581. })
  582. resolve();
  583. return
  584. }
  585. let data={
  586. companyId:this.userInfo.companyId||'',
  587. deptId:this.formData.deptId||'',
  588. productId:this.formData.productId||'',
  589. }
  590. queryAllData(data).then(res => {
  591. if (res.code === 200) {
  592. // 处理任务类型
  593. this.taskType = res.data || []
  594. console.log('company接口返回数据:', res)
  595. // 处理taskTypeIds,获取对应的字典数据
  596. if (res.data && res.data.length > 0) {
  597. const firstData = res.data[0];
  598. if (firstData.taskTypeIds) {
  599. // 分割taskTypeIds为数组
  600. const taskTypeIdsArray = firstData.taskTypeIds.split(',');
  601. // 从字典表中筛选出对应的项
  602. const filteredTaskTypes = this.taskTypeDict.filter(item =>
  603. taskTypeIdsArray.includes(item.dictValue)
  604. );
  605. // 保存原始数据(包含dictLabel和dictValue)
  606. this.taskTypeOriginalData = filteredTaskTypes;
  607. // 提取dictLabel并放到taskTypeColumns中
  608. const taskTypeLabels = filteredTaskTypes.map(item => item.dictLabel);
  609. this.taskTypeColumns = [taskTypeLabels];
  610. console.log('处理后的taskTypeColumns:', this.taskTypeColumns);
  611. console.log('任务类型原始数据:', this.taskTypeOriginalData);
  612. }
  613. }
  614. }
  615. resolve(res);
  616. }).catch(err => {
  617. console.error('获取任务类型失败:', err);
  618. reject(err);
  619. });
  620. });
  621. },
  622. //获取公司所有产品
  623. async queryAllProduct(){
  624. return new Promise((resolve, reject) => {
  625. let data={
  626. companyId:this.userInfo.companyId||'',
  627. }
  628. queryAllProduct(data).then(res => {
  629. if (res.code === 200) {
  630. // 处理公司所有产品数据
  631. this.productList = res.data || []
  632. console.log('company接口返回数据:', res)
  633. }
  634. resolve(res);
  635. }).catch(err => {
  636. console.error('获取公司所有产品失败:', err);
  637. reject(err);
  638. });
  639. });
  640. },
  641. // 归属项目
  642. async getAllData(){
  643. return new Promise((resolve, reject) => {
  644. let data={
  645. companyId:this.userInfo.companyId||'',
  646. deptId:this.userInfo.deptId||'',
  647. productCode:this.userInfo.productCode||''
  648. }
  649. getAllData(data).then(res => {
  650. if (res.code === 200) {
  651. // 处理公司项目设置列表数据
  652. this.companyList = res.data || []
  653. // 保存项目数据用于显示
  654. this.projectData = res.data || []
  655. console.log('company接口返回数据:', res)
  656. console.log('companyList数据结构:', this.companyList)
  657. }
  658. resolve(res);
  659. }).catch(err => {
  660. console.error('获取公司项目设置失败:', err);
  661. reject(err);
  662. });
  663. });
  664. },
  665. async company() {
  666. return new Promise((resolve, reject) => {
  667. try {
  668. uni.showLoading({
  669. title: '加载中...'
  670. })
  671. // 调用company接口获取公司项目设置列表
  672. company(this.companyId).then(companyRes => {
  673. uni.hideLoading()
  674. if (companyRes.code === 200) {
  675. // 处理公司项目设置列表数据
  676. this.companyData = companyRes.data || []
  677. console.log('company接口返回数据:', companyRes)
  678. // 这里可以根据接口返回的数据进行页面初始化,比如填充项目列表
  679. }
  680. resolve(companyRes);
  681. }).catch(e => {
  682. uni.hideLoading()
  683. console.error('加载信息失败', e)
  684. uni.showToast({
  685. title: '网络错误',
  686. icon: 'none'
  687. })
  688. reject(e);
  689. });
  690. } catch (e) {
  691. uni.hideLoading()
  692. console.error('加载信息失败', e)
  693. uni.showToast({
  694. title: '网络错误',
  695. icon: 'none'
  696. })
  697. reject(e);
  698. }
  699. });
  700. },
  701. // 打开通用选择器
  702. async showPicker(title, data) {
  703. // 根据不同的title调用对应的请求方法
  704. if (title === '任务归属' || title === '费用分摊') {
  705. // 调用company()获取任务归属和费用分摊数据
  706. await this.company();
  707. data = this.companyData;
  708. } else if (title === '归属项目') {
  709. // 调用getAllData()获取归属项目数据
  710. await this.getAllData();
  711. data = this.companyList;
  712. console.log('归属项目数据:', data);
  713. } else if (title === '产品代码') {
  714. // 调用queryAllProduct()获取产品代码数据
  715. await this.queryAllProduct();
  716. data = this.productList;
  717. } else if (title === '任务类型') {
  718. // queryAllData()获取任务类型数据
  719. await this.queryAllData();
  720. // 使用处理后的taskTypeColumns作为数据
  721. data = this.taskTypeColumns;
  722. console.log('任务类型数据:', data);
  723. } else if (title === '归属类型') {
  724. // 归属类型数据已经在onLoad中获取
  725. data = this.belongTypeList;
  726. console.log('归属类型数据:', data);
  727. }
  728. // 处理任务归属和费用分摊数据,将deptName作为显示文本
  729. if ((title === '任务归属' || title === '费用分摊') && data && data.length > 0) {
  730. // 转换为picker需要的格式
  731. this.pickerData = [data.map(item => item.deptName)]
  732. // 保存原始数据,用于后续获取deptId
  733. this.originalCompanyData = data
  734. } else if (title === '归属项目' && data && data.length > 0) {
  735. // 处理归属项目数据,将projectName作为显示文本
  736. this.pickerData = [data.map(item => item.projectName)]
  737. // 保存原始数据,用于后续获取productId
  738. this.originalCompanyData = data
  739. } else if (title === '产品代码' && data && data.length > 0) {
  740. // 处理产品代码数据,将productName作为显示文本
  741. this.pickerData = [data.map(item => item.productName)]
  742. // 保存原始数据,用于后续获取productCode
  743. this.originalCompanyData = data
  744. } else if (title === '归属类型' && data && data.length > 0) {
  745. // 处理归属类型数据,将dictLabel作为显示文本
  746. this.pickerData = [data.map(item => item.dictLabel)]
  747. // 保存原始数据,用于后续获取dictType
  748. this.originalCompanyData = data
  749. } else {
  750. this.pickerData = data
  751. this.originalCompanyData = null
  752. }
  753. this.pickerTitle = title
  754. console.log('打开picker, pickerTitle:', this.pickerTitle);
  755. console.log('pickerData:', this.pickerData);
  756. this.showPickerVisible = true
  757. },
  758. // 通用选择器确认
  759. confirm(e) {
  760. console.log('confirm事件返回值:', e);
  761. console.log('pickerTitle:', this.pickerTitle);
  762. console.log('e.value:', e.value);
  763. if (e.value && e.value.length > 0) {
  764. if (this.pickerTitle === '费用分摊') {
  765. // e.value[0]是选中的文本值(deptName)
  766. const selectedDeptStr = e.value[0];
  767. console.log('选中的费用分摊文本:', selectedDeptStr);
  768. console.log('originalCompanyData:', this.originalCompanyData);
  769. // 从originalCompanyData中找到对应的项
  770. const selectedItem = this.originalCompanyData.find(item => item.deptName === selectedDeptStr);
  771. if (selectedItem) {
  772. // 保存deptId到表单(存储id值)
  773. this.formData.costShareId = selectedItem.deptId;
  774. console.log('设置formData.costShareId为:', selectedItem.deptId);
  775. } else {
  776. this.formData.costShareId = '';
  777. console.log('未找到对应的费用分摊');
  778. }
  779. } else if (this.pickerTitle === '任务类型') {
  780. // e.value[0]是选中的文本值(dictLabel)
  781. const selectedLabel = e.value[0];
  782. console.log('选中的任务类型文本:', selectedLabel);
  783. console.log('taskTypeOriginalData:', this.taskTypeOriginalData);
  784. // 从taskTypeOriginalData中找到对应的项
  785. const selectedType = this.taskTypeOriginalData.find(item => item.dictLabel === selectedLabel);
  786. if (selectedType) {
  787. this.formData.taskType = selectedType.dictValue;
  788. console.log('设置formData.taskType为:', selectedType.dictValue);
  789. } else {
  790. }
  791. } else if (this.pickerTitle === '任务归属' && this.originalCompanyData) {
  792. // e.value[0]是选中的文本值(deptName)
  793. const selectedDeptStr = e.value[0];
  794. console.log('选中的任务归属文本:', selectedDeptStr);
  795. console.log('originalCompanyData:', this.originalCompanyData);
  796. // 从originalCompanyData中找到对应的项
  797. const selectedItem = this.originalCompanyData.find(item => item.deptName === selectedDeptStr);
  798. if (selectedItem) {
  799. // 保存deptId到表单(存储id值)
  800. this.formData.deptId = selectedItem.deptId;
  801. console.log('设置formData.deptId为:', selectedItem.deptId);
  802. } else {
  803. }
  804. } else if (this.pickerTitle === '归属项目' && this.originalCompanyData) {
  805. // e.value[0]是选中的文本值(projectName)
  806. const selectedProjectName = e.value[0];
  807. console.log('选中的归属项目文本:', selectedProjectName);
  808. console.log('originalCompanyData:', this.originalCompanyData);
  809. // 从originalCompanyData中找到对应的项
  810. const selectedItem = this.originalCompanyData.find(item => item.projectName === selectedProjectName);
  811. if (selectedItem) {
  812. // 保存id到表单(存储id值)
  813. this.formData.projectId = selectedItem.id;
  814. // 保存productId到表单
  815. this.formData.productId = selectedItem.productId;
  816. console.log('设置formData.projectId为:', selectedItem.id);
  817. } else {
  818. }
  819. } else if (this.pickerTitle === '产品代码' && this.originalCompanyData) {
  820. // e.value[0]是选中的文本值(productName)
  821. const selectedProductName = e.value[0];
  822. console.log('选中的产品代码文本:', selectedProductName);
  823. console.log('originalCompanyData:', this.originalCompanyData);
  824. // 从originalCompanyData中找到对应的项
  825. const selectedItem = this.originalCompanyData.find(item => item.productName === selectedProductName);
  826. if (selectedItem) {
  827. // 保存id到表单
  828. this.formData.productId = selectedItem.id;
  829. // 保存id用于获取任务类型
  830. console.log('设置formData.productId为:', selectedItem.id);
  831. } else {
  832. }
  833. } else if (this.pickerTitle === '归属类型' && this.originalCompanyData) {
  834. // e.value[0]是选中的文本值(dictLabel)
  835. const selectedLabel = e.value[0];
  836. console.log('选中的归属类型文本:', selectedLabel);
  837. console.log('originalCompanyData:', this.originalCompanyData);
  838. // 从originalCompanyData中找到对应的项
  839. const selectedItem = this.originalCompanyData.find(item => item.dictLabel === selectedLabel);
  840. if (selectedItem) {
  841. // 保存dictValue到表单的belongType字段
  842. this.formData.belongType = selectedItem.dictValue;
  843. console.log('设置formData.belongType为:', selectedItem.dictValue);
  844. } else {
  845. console.log('未找到对应的归属类型');
  846. }
  847. }
  848. }
  849. this.showPickerVisible = false
  850. },
  851. // 通用选择器取消
  852. cancel() {
  853. this.showPickerVisible = false
  854. },
  855. // 下一步
  856. toNext() {
  857. // 表单验证
  858. if (!this.formData.deptId) {
  859. uni.showToast({
  860. title: '请选择任务归属',
  861. icon: 'none'
  862. })
  863. return
  864. }
  865. if (!this.formData.projectId) {
  866. uni.showToast({
  867. title: '请选择归属项目',
  868. icon: 'none'
  869. })
  870. return
  871. }
  872. if (!this.formData.productId) {
  873. uni.showToast({
  874. title: '请选择产品代码',
  875. icon: 'none'
  876. })
  877. return
  878. }
  879. if (!this.formData.costShareId) {
  880. uni.showToast({
  881. title: '请选择费用分摊',
  882. icon: 'none'
  883. })
  884. return
  885. }
  886. if (!this.formData.belongType) {
  887. uni.showToast({
  888. title: '请选择归属类型',
  889. icon: 'none'
  890. })
  891. return
  892. }
  893. if (!this.formData.taskType) {
  894. uni.showToast({
  895. title: '请选择任务类型',
  896. icon: 'none'
  897. })
  898. return
  899. }
  900. if (!this.formData.planStartTime) {
  901. uni.showToast({
  902. title: '请选择计划开始时间',
  903. icon: 'none'
  904. })
  905. return
  906. }
  907. if (!this.formData.planEndTime) {
  908. uni.showToast({
  909. title: '请选择计划结束时间',
  910. icon: 'none'
  911. })
  912. return
  913. }
  914. // 如果开启了任务备注,则备注为必填
  915. if (this.formData.addRemark && !this.formData.remark) {
  916. uni.showToast({
  917. title: '请输入任务备注',
  918. icon: 'none'
  919. })
  920. return
  921. }
  922. console.log('去编辑积分:', this.doctorId);
  923. console.log('去编辑积分formData:', this.formData);
  924. // 保存表单数据到本地存储,以便 editSelectCustomer.vue 页面使用
  925. uni.setStorageSync('fillTaskFormData', JSON.stringify(this.formData));
  926. uni.navigateTo({
  927. url: `/pages_task/editSelectCustomer?doctorId=${this.doctorId}`
  928. })
  929. },
  930. // 提交表单
  931. submit() {
  932. console.log('提交表单数据:', this.formData);
  933. // 这里可以添加表单验证逻辑
  934. // 然后调用接口提交数据
  935. uni.showToast({
  936. title: '提交成功',
  937. icon: 'success'
  938. });
  939. },
  940. // 开始时间选择确认
  941. onStartTimeConfirm(e) {
  942. this.formData.planStartTime = this.formatDateTime(e.value);
  943. this.showStartTimePicker = false;
  944. },
  945. // 结束时间选择确认
  946. onEndTimeConfirm(e) {
  947. this.formData.planEndTime = this.formatDateTime(e.value);
  948. this.showEndTimePicker = false;
  949. },
  950. // 格式化日期时间
  951. formatDateTime(timestamp) {
  952. const date = new Date(timestamp);
  953. const year = date.getFullYear();
  954. const month = String(date.getMonth() + 1).padStart(2, '0');
  955. const day = String(date.getDate()).padStart(2, '0');
  956. // const hours = String(date.getHours()).padStart(2, '0');
  957. // const minutes = String(date.getMinutes()).padStart(2, '0');
  958. // const seconds = String(date.getSeconds()).padStart(2, '0');
  959. // ${hours}:${minutes}:${seconds}
  960. return `${year}-${month}-${day}`;
  961. }
  962. }
  963. }
  964. </script>
  965. <style lang="scss" scoped>
  966. .column {
  967. flex-direction: column;
  968. }
  969. .baseline {
  970. align-items: baseline !important;
  971. }
  972. // 页面容器样式
  973. .container {
  974. min-height: 100vh;
  975. background: #F7F8FA;
  976. display: flex;
  977. flex-direction: column;
  978. position: relative;
  979. // 顶部渐变背景
  980. &::before {
  981. content: '';
  982. position: absolute;
  983. top: 0;
  984. left: 0;
  985. right: 0;
  986. width: 100%;
  987. height: 544rpx;
  988. background: linear-gradient(180deg, #E4EFFE 0%, rgba(228, 239, 254, 0) 100%);
  989. }
  990. // 滚动内容区
  991. .content {
  992. flex: 1;
  993. box-sizing: border-box;
  994. // 驳回提示
  995. .rejection-banner {
  996. display: flex;
  997. align-items: center;
  998. padding: 24rpx;
  999. background: #FF5030;
  1000. color: #fff;
  1001. margin: 24rpx;
  1002. border-radius: 8rpx;
  1003. .rejection-icon {
  1004. width: 40rpx;
  1005. height: 40rpx;
  1006. border-radius: 50%;
  1007. background: rgba(255, 255, 255, 0.3);
  1008. display: flex;
  1009. align-items: center;
  1010. justify-content: center;
  1011. font-size: 24rpx;
  1012. margin-right: 16rpx;
  1013. }
  1014. .rejection-text {
  1015. flex: 1;
  1016. font-size: 28rpx;
  1017. line-height: 1.5;
  1018. }
  1019. }
  1020. // 表单区域
  1021. .form-section {
  1022. background: #fff;
  1023. margin: 20rpx;
  1024. border-radius: 24rpx;
  1025. padding: 32rpx;
  1026. // 表单项
  1027. .form-item {
  1028. display: flex;
  1029. justify-content: space-between;
  1030. align-items: center;
  1031. border-bottom: 1px solid #EBEDF0;
  1032. padding: 30rpx 0;
  1033. &:last-child {
  1034. border-bottom: 0;
  1035. }
  1036. // 表单标签
  1037. .form-label {
  1038. display: flex;
  1039. align-items: center;
  1040. font-size: 28rpx;
  1041. color: #333;
  1042. margin-bottom: 16rpx;
  1043. .required {
  1044. color: #CF3546;
  1045. margin-right: 4rpx;
  1046. }
  1047. }
  1048. // 纯文本展示
  1049. .txt {
  1050. font-size: 28rpx;
  1051. color: #333333;
  1052. }
  1053. // 输入框容器
  1054. .form-input {
  1055. flex: 1;
  1056. font-size: 28rpx;
  1057. color: #C8C9CC;
  1058. text-align: end;
  1059. &.placeholder {
  1060. color: #C8C9CC;
  1061. }
  1062. &.picker-input {
  1063. display: flex;
  1064. align-items: center;
  1065. justify-content: flex-end;
  1066. }
  1067. .icon {
  1068. width: 36rpx;
  1069. height: 36rpx;
  1070. }
  1071. }
  1072. // 单选组样式(嵌套到form-item里)
  1073. .radio-group {
  1074. display: flex;
  1075. gap: 40rpx;
  1076. .radio-item {
  1077. display: flex;
  1078. align-items: center;
  1079. font-size: 28rpx;
  1080. .radio-circle {
  1081. width: 36rpx;
  1082. height: 36rpx;
  1083. border-radius: 50%;
  1084. margin-right: 16rpx;
  1085. }
  1086. }
  1087. }
  1088. // 上传区域样式(嵌套到form-item里)
  1089. .upload-area {
  1090. position: relative;
  1091. width: 200rpx;
  1092. height: 120rpx;
  1093. border: 1rpx dashed #C8C9CC;
  1094. border-radius: 8rpx;
  1095. display: flex;
  1096. align-items: center;
  1097. justify-content: center;
  1098. .cover-image {
  1099. width: 100%;
  1100. height: 100%;
  1101. border-radius: 8rpx;
  1102. }
  1103. .upload-placeholder {
  1104. color: #C8C9CC;
  1105. font-size: 24rpx;
  1106. }
  1107. .delete-icon {
  1108. position: absolute;
  1109. top: -12rpx;
  1110. right: -12rpx;
  1111. width: 32rpx;
  1112. height: 32rpx;
  1113. background: #fff;
  1114. border-radius: 50%;
  1115. }
  1116. }
  1117. }
  1118. }
  1119. }
  1120. // 下一步按钮
  1121. .next-button {
  1122. text-align: center;
  1123. font-size: 32rpx;
  1124. color: #FFFFFF;
  1125. height: 88rpx;
  1126. line-height: 88rpx;
  1127. background: #388BFF;
  1128. border-radius: 200rpx;
  1129. margin: 32rpx;
  1130. }
  1131. }
  1132. // 弹窗样式
  1133. ::v-deep .u-popup__content {
  1134. border-radius: 40rpx 40rpx 0 0 !important;
  1135. }
  1136. .popup-content {
  1137. border-radius: 40rpx 40rpx 0rpx 0rpx;
  1138. height: 70vh;
  1139. background-color: #fff;
  1140. .popup-header {
  1141. padding: 40rpx 30rpx 20rpx;
  1142. text-align: center;
  1143. .close-icon {
  1144. width: 44rpx;
  1145. height: 44rpx;
  1146. position: absolute;
  1147. right: 32rpx;
  1148. }
  1149. flex-shrink: 0;
  1150. .title,
  1151. .popup-title {
  1152. font-size: 32rpx;
  1153. font-weight: 600;
  1154. color: #333;
  1155. }
  1156. }
  1157. .search-box {
  1158. display: flex;
  1159. align-items: center;
  1160. background: #F7F8FA;
  1161. border-radius: 38rpx;
  1162. padding: 16rpx 28rpx;
  1163. margin-bottom: 24rpx;
  1164. .icon {
  1165. width: 26rpx;
  1166. height: 26rpx;
  1167. margin-right: 10rpx;
  1168. }
  1169. }
  1170. .project-list {
  1171. height: calc(100% - 200rpx);
  1172. .project-item {
  1173. display: flex;
  1174. justify-content: space-between;
  1175. align-items: center;
  1176. padding: 28rpx 0;
  1177. font-size: 28rpx;
  1178. border-bottom: 1rpx solid #eee;
  1179. &:active {
  1180. background-color: #f9f9f9;
  1181. }
  1182. &.active {
  1183. .project-name {
  1184. font-weight: 500;
  1185. color: #388BFF;
  1186. }
  1187. .icon {
  1188. opacity: 1;
  1189. }
  1190. }
  1191. .project-name {
  1192. color: #333;
  1193. transition: all 0.2s ease;
  1194. }
  1195. .icon {
  1196. width: 36rpx;
  1197. height: 36rpx;
  1198. opacity: 0;
  1199. transition: opacity 0.2s ease;
  1200. }
  1201. }
  1202. }
  1203. .two-level-container {
  1204. display: flex;
  1205. flex: 1;
  1206. border-top: 1rpx solid #f5f5f5;
  1207. .primary-list {
  1208. width: 40%;
  1209. background-color: #f8f9fa;
  1210. .primary-item {
  1211. padding: 28rpx 20rpx;
  1212. background: #F2F3F5;
  1213. &:active {
  1214. background: #FFFFFF;
  1215. }
  1216. &.primary-active {
  1217. position: relative;
  1218. background-color: #fff;
  1219. &::before {
  1220. content: '';
  1221. position: absolute;
  1222. top: 50%;
  1223. left: 0;
  1224. transform: translateY(-50%);
  1225. width: 8rpx;
  1226. height: 32rpx;
  1227. background: #388BFF;
  1228. }
  1229. .primary-text {
  1230. font-weight: 500;
  1231. }
  1232. }
  1233. .primary-text {
  1234. font-size: 28rpx;
  1235. color: #666;
  1236. }
  1237. }
  1238. }
  1239. .secondary-list {
  1240. width: 60%;
  1241. padding: 0 20rpx;
  1242. .secondary-item {
  1243. display: flex;
  1244. justify-content: space-between;
  1245. align-items: center;
  1246. padding: 28rpx 10rpx;
  1247. font-size: 28rpx;
  1248. color: #333;
  1249. &.secondary-active {
  1250. font-weight: 500;
  1251. color: #388BFF;
  1252. }
  1253. }
  1254. }
  1255. }
  1256. .popup-footer {
  1257. padding: 20rpx 30rpx 40rpx;
  1258. background-color: #fff;
  1259. border-top: 1rpx solid #f5f5f5;
  1260. flex-shrink: 0;
  1261. .confirm-btn {
  1262. width: 100%;
  1263. height: 88rpx;
  1264. line-height: 88rpx;
  1265. background-color: #2979ff;
  1266. color: #fff;
  1267. font-size: 32rpx;
  1268. border-radius: 200rpx;
  1269. &:active {
  1270. opacity: 0.8;
  1271. }
  1272. }
  1273. }
  1274. }
  1275. // 暗黑模式适配
  1276. @media (prefers-color-scheme: dark) {
  1277. .popup-content {
  1278. background-color: #1e1e1e;
  1279. .popup-header {
  1280. .title,
  1281. .popup-title {
  1282. color: #fff;
  1283. }
  1284. }
  1285. .two-level-container {
  1286. .primary-list {
  1287. background-color: #2d2d2d;
  1288. border-right-color: #3d3d3d;
  1289. .primary-item {
  1290. border-bottom-color: #3d3d3d;
  1291. &:active {
  1292. background-color: #3d3d3d;
  1293. }
  1294. &.primary-active {
  1295. background-color: #3d3d3d;
  1296. .primary-text {
  1297. color: #2979ff;
  1298. }
  1299. }
  1300. .primary-text {
  1301. color: #ccc;
  1302. }
  1303. }
  1304. }
  1305. .secondary-list {
  1306. .secondary-item {
  1307. border-bottom-color: #3d3d3d;
  1308. &:active {
  1309. background-color: #3d3d3d;
  1310. }
  1311. &.secondary-active {
  1312. background-color: #2d2d2d;
  1313. }
  1314. .secondary-text {
  1315. color: #fff;
  1316. }
  1317. }
  1318. }
  1319. }
  1320. .popup-footer {
  1321. background-color: #1e1e1e;
  1322. border-top-color: #3d3d3d;
  1323. }
  1324. }
  1325. }
  1326. </style>